const path = require('path')
const defaultSettings = require('./src/settings.js')
const CompressionPlugin = require('compression-webpack-plugin')
const { RetryChunkLoadPlugin } = require('webpack-retry-chunk-load-plugin')
const Timestamp = new Date().getTime()

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = defaultSettings.title || 'vue Element Admin' // page title

// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following method:
// port = 9527 npm run dev OR npm run dev --port = 9527
const port = process.env.port || process.env.npm_config_port || 9527 // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: process.env.VUE_APP_PACKAGE_PATH || '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.VUE_APP_MODE === 'development',
  productionSourceMap: false,
  devServer: {
    port: port,
    hot: true,
    open: false,
    proxy: {
      'api56/open': {
        target: 'http://gatewayservicev2.fujica.com.cn/open',
        changeOrigin: true,
        pathRewrite: {
          '^/api56/open': ''
        }
      },
      // change xxx-api/login => mock/login
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      'api56': {
        target: process.env.VUE_APP_BASE_API,
        changeOrigin: true,
        pathRewrite: {
          '^/api56': ''
        }
      },
      'api11': {
        target: process.env.VUE_APP_BASE_API,
        // target: 'http://119.23.214.109:32011',
        changeOrigin: true,
        pathRewrite: {
          '^/api11': ''
        }
      }
    },
    // history模式下的url会请求到服务器端，但是服务器端并没有这一个资源文件，就会返回404，所以需要配置这一项
    // historyApiFallback: {
    //   index: '/index.html' // 与output的publicPath
    // },
    disableHostCheck: true
    // after: require('./mock/mock-server.js')
  },
  configureWebpack: {
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    // 打包时忽略以下文件
    externals: {
      'vue': 'Vue',
      'element-ui': 'Element'
    },
    output: { // 输出重构  打包编译后的 文件名称  【模块名称.时间戳】
      'filename': `[name].${Timestamp}.js`,
      'chunkFilename': `[name].${Timestamp}.js`
    },
    performance: {
      hints: 'warning',
      // 入口起点的最大体积
      maxEntrypointSize: 50000000,
      // 生成文件的最大体积
      maxAssetSize: 50000000,
      // 只给出 js 文件的性能提示
      assetFilter: function(assetFilename) {
        return assetFilename.endsWith('.js')
      }
    },
    plugins: [
      new RetryChunkLoadPlugin({
        cacheBust: `function() {
          return Date.now();
        }`,
        retryDelay: 3000,
        maxRetries: 2,
        // chunks: ['chunks.**.**.js'],
        lastResortScript: 'window.location.reload(true);'
      })
    ]
  },
  chainWebpack(config) {
    // if (process.env.VUE_APP_MODE === 'production') {
    //   // 清除css，js版本号
    //   config.output.filename('static/js/[name].v1.11.js').end()
    //   config.output.chunkFilename('static/js/[name].v1.11.js').end()
    //   // 为生产环境修改配置...
    //   config.plugin('extract-css').tap(args => [{
    //     filename: `static/css/[name].v1.11.css`,
    //     chunkFilename: `static/css/[name].v1.11.css`
    //   }])
    // } else {
    //   config.output.filename(`static/js/[name].${Timestamp}.js`).end()
    //   config.output.chunkFilename(`static/js/[name].${Timestamp}.js`).end()
    // }
    config.plugins.delete('prefetch') // TODO: need test
    // 可视化显示包的大小
    // config
    //   .plugin('webpack-bundle-analyzer')
    //   .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    // 开启gzip压缩,加快访问速度

    // 开发环境下不使用压缩
    config
      .when(process.env.VUE_APP_MODE !== 'development', config => {
        config.plugin('compression')
          .use(CompressionPlugin, [{
            algorithm: 'gzip',
            test: /\.js$|\.html$|\.css/,
            threshold: 10240,
            deleteOriginalAssets: false
          }])
          .end()
      })

    // config.plugin('compression')
    //   .use(CompressionPlugin, [{
    //     algorithm: 'gzip',
    //     test: /\.js$|\.html$|\.css/,
    //     threshold: 10240,
    //     deleteOriginalAssets: false
    //   }])
    //   .end()
    // set svg-sprite-loader

    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    // set preserveWhitespace
    config.module
      .rule('vue')
      .exclude.add(resolve('src/views/V1'))
      .end()
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true
        return options
      })
      .end()

    // config
    //   // 开发环境下打包生产map文件，其他环境不生成
    //   .when(process.env.VUE_APP_MODE === 'development',
    //     config => config.devtool('cheap-source-map')
    //   )

    config
      .when(process.env.VUE_APP_MODE !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
              // inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          config.optimization.runtimeChunk('single')
        }
      )
  }
}
