const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { merge } = require('webpack-merge');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const antdTheme = require('./antd-theme');
const path = require('path');
const common = require('./webpack.common');
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const config = merge(common, {
  mode: 'production',
  devtool: false,
  entry: {
    app: ['./src/scripts/utils/drop-console.ts', './src/scripts/index.tsx'],
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              sourceMap: false,
              modules: {
                localIdentName: '[name]__[local]--[hash:base64:5]',
              },
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [require('postcss-preset-env')()],
              },
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
      {
        test: /\.less$/,
        include: /node_modules/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true,
                modifyVars: antdTheme,
              },
            },
          },
        ],
      },
      {
        test: /\.less$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              sourceMap: false,
              modules: {
                localIdentName: '[name]__[local]--[hash:base64:5]',
              },
            },
          },
          {
            loader: 'less-loader',
          },
        ],
      },
    ],
  },
  optimization: {
    minimize: true, // 压缩后删除不被使用的代码
    usedExports: true, // 只导出被使用的成员
    minimizer: [
      new CssMinimizerPlugin(),
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          compress: {
            drop_debugger:true, // 删除debug
          },
        },
      }),
    ],
    runtimeChunk: true, // 选项将 runtime 代码拆分为一个单独的 chunk
    splitChunks: {
      chunks: 'all', // 这表明将选择哪些 chunk 进行优化。当提供一个字符串，有效值为 all，async 和 initial
      minSize: 20000, // 生成 chunk 的最小体积
      maxAsyncRequests: 6, // 按需加载时的最大并行请求数
      maxInitialRequests: 6, // 入口点的最大并行请求数
      cacheGroups: {
        vendor: {
          name: 'chunk-vendors',
          minChunks: 2, // 拆分前必须共享模块的最小 chunks 数
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          reuseExistingChunk: true,
        },
        fantUI: {
          name: 'chunk-fantUI',
          test: /[\\/]node_modules[\\/]_?fant-ui(.*)/,
          priority: 15,
          reuseExistingChunk: true,
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    },
  },
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000,
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../src/favicon.ico'),
          to: path.resolve(__dirname, '../dist'),
        },
        {
          from: path.resolve(__dirname, '../pwa/'),
          to: path.resolve(__dirname, '../dist'),
        },
        {
          from: path.resolve(__dirname, '../public/'),
          to: path.resolve(__dirname, '../dist'),
        },
      ],
    }),
  ],
});

// 注意一定要在HtmlWebpackPlugin之后引用
// inline 的name 和你 runtimeChunk 的 name保持一致
config.plugins.push(
  new ScriptExtHtmlWebpackPlugin({
    inline: /runtime~main\..*\.js$/,
  }),
);


// 按环境变量IS_GZIP来决定是否启用Gzip
if (process.env.IS_GZIP === 'TRUE') {
  config.plugins.push(new CompressionWebpackPlugin({
    filename: '[path][base].gz', // 输出目标文件名
    algorithm: 'gzip', // 压缩格式
    test: new RegExp('\\.(js|css)$'), // 要处理的文件正则
    threshold: 0, // 仅处理大于此大小的文件（以字节为单位）
    minRatio: 0.8, // 仅处理压缩比此比率更好的文件（minRatio = 压缩大小/原始大小）
    deleteOriginalAssets: false // 是否删除原有文件
  }))
}

const configWithTimeMeasures = process.env.IS_SPEED === 'TRUE' ? new SpeedMeasurePlugin().wrap(config) :config;
 // TODO 配置方式原因，swap 和 MiniCssExtractPlugin 存在不兼容情况 https://github.com/stephencookdev/speed-measure-webpack-plugin/issues/167
 configWithTimeMeasures.plugins.push(
  new MiniCssExtractPlugin({
    filename: 'style/[name].[chunkhash:5].css',
    ignoreOrder: true,
  }),
);

module.exports = configWithTimeMeasures;