const path = require('path');

const { SPARK_CONFIG_DIR_KEY, SPARK_CONFIG } = require('./scripts/constant');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");


module.exports = function (isProd) {
  const appPath = process.cwd();
  const sparkConfig = require(path.join(appPath, SPARK_CONFIG));
  const cssReg = /\.(css|less)$/;
  // 处理相对路径
  SPARK_CONFIG_DIR_KEY.map((key) => {
    sparkConfig[key] = path.resolve(appPath, sparkConfig[key]);
  });

  const stylePlugins = [
    require("autoprefixer")({
      overrideBrowserslist: ["> 1%", "last 2 versions", "not ie <= 8"],
    })
  ];
  if (sparkConfig.PX2REM) {
    stylePlugins.push(
      require("postcss-px2rem-exclude")({
        remUnit: 100, // 注意算法，这是750设计稿，html的font-size按照750比例
        exclude: /node_modules/i,
      })
    );
  }
  const styleLoader = (cssOptions = {}) => {
    return [
      {
        loader: "style-loader",
      },
      isProd && {
        loader: MiniCssExtractPlugin.loader,
        options: {
          esModule: false,
        },
      },
      {
        loader: "css-loader",
        options: {
          ...cssOptions,
          importLoaders: 2, // 如果遇到css里面的 @import 执行后面两个loader。 不然如果import了less，css-loader是解析不了
        },

      },
      {
        loader: "postcss-loader",
        options: {
          sourceMap: isProd,
          plugins: stylePlugins,
        },
      },
      {
        loader: require.resolve("less-loader"),
        options: {
          sourceMap: isProd,
          lessOptions: {
            modifyVars: {
              "@RES_PATH": `"${isProd ? sparkConfig.RES_PATH_PROD + '/' : sparkConfig.RES_PATH}"`,
            },
          }
        },
      },
    ].filter(Boolean);
  };
  return {
    entry: sparkConfig.ENTRY,
    mode: isProd ? 'production' : 'development',
    devtool: isProd ? "source-map" : "cheap-module-source-map",
    output: {
      path: path.resolve(__dirname, sparkConfig.OUTPUT_DIR),
      filename: "js/[name].js",
    },
    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      alias: {
        "@src": path.resolve(__dirname, sparkConfig.SOURCE_DIR),
      },
    },
    module: {
      strictExportPresence: true,
      rules: [
        {
          test: cssReg,
          use: styleLoader(),
          include: sparkConfig.SOURCE_DIR,
        },
        {
          test: /\.(js|jsx)$/,
          loader: require.resolve("babel-loader"),
          // exclude: [path.resolve("node_modules")],
          options: {
            presets: [
              require("@babel/preset-env").default,
              require("@babel/preset-react").default
            ],
            plugins: [
              ["@babel/plugin-proposal-decorators", { "legacy": true }],
              ["@babel/plugin-proposal-class-properties", { "loose": false }],
              require("@babel/plugin-transform-runtime").default,
            ],
            sourceType: 'unambiguous'
          },
        },
        {
          test: [/\.(jpg|jpeg|png|svg|bmp)$/, /\.(eot|woff2?|ttf|svg)$/],
          loader: require.resolve("url-loader"),
          options: {
            name: "[path][name].[ext]", // name默认是加上hash值。这里做了更改，不让加
            outputPath: "images",
            limit: 10240, // url-loader处理图片默认是转成base64, 这里配置如果小于10kb转base64,否则使用file-loader打包到images文件夹下
          },
        },
      ].filter(Boolean),
    },
    plugins: [
      isProd &&
      new MiniCssExtractPlugin({
        filename: "styles/[name].[hash].css",
      }),
      new HtmlWebpackPlugin({
        template: sparkConfig.TEMPLATE,
        minify: !sparkConfig.UNMINIFY_INDEX && isProd,
      }),
      new CleanWebpackPlugin({
        // cleanOnceBeforeBuildPatterns:['**/*', 'dist'] // 这里不用写 是默认的。 路径会根据output 输出的路径去清除
      }),
      new ProgressBarPlugin(),
    ].filter(Boolean),
    optimization: {
      minimize: isProd,
      minimizer: [
        // 替换的js压缩 因为uglifyjs不支持es6语法，
        new TerserPlugin({
          cache: true,
          sourceMap: isProd,
          extractComments: false, // 提取注释
          parallel: true, // 多线程
          terserOptions: {
            compress: {
              pure_funcs: ["console.log"],
            },
          },
        }),
        // 压缩css
        new OptimizeCSSAssetsPlugin({
          assetNameRegExp: /\.css$/g,
          cssProcessor: require("cssnano"),
          cssProcessorPluginOptions: {
            preset: ["default", { discardComments: { removeAll: true } }],
          },
          canPrint: true,
        }),
      ],
      // 修改文件的ids的形成方式，避免单文件修改，会导致其他文件的hash值变化，影响缓存
      moduleIds: "hashed",
      splitChunks: {
        chunks: "all",
        minSize: 30000, // 小于这个限制的会打包进Main.js
        cacheGroups: {
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10, // 优先级权重，层级 相当于z-index。 谁值越大权会按照谁的规则打包
            name: "vendors",
          },
        },
      },
      // chunks 映射关系的 list单独从 app.js里提取出来
      runtimeChunk: {
        name: (entrypoint) => `runtime-${entrypoint.name}`,
      },
    },
  };



}
