"use strict";
const path = require("path");
const webpack = require("webpack");
function resolve(dir) {
  return path.join(__dirname, dir);
}

//读取npm指令 process.argv 获取⾃定义参数
let argvs = process.argv.filter((e) => e.includes("="));
for (const iterator of argvs) {
  let diyArg = iterator.split("=");
  process.env["VUE_APP_" + diyArg[0].slice(2)] = diyArg[1];
}
process.env.VUE_APP_ENV = process.env.VUE_APP_ENV || process.env.NODE_ENV;

const env = require("./env");

process.env.VUE_APP_TITLE = env.SYSTEM_NAME_ALL;
process.env.VUE_APP_PACKETTIME = new Date().toLocaleString();

// vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分，具体配置参考文档
module.exports = {
  // 部署生产环境和开发环境下的URL。
  // 默认情况下，Vue CLI 会假设你的应用是被部署在一个域名的根路径上
  // 例如 https://www.xx.cn/。如果应用被部署在一个子路径上，你就需要用这个选项指定这个子路径。例如，如果你的应用被部署在 https://www.xx.cn/admin/，则设置 baseUrl 为 /admin/。
  publicPath: env.BASE_URL || "/",
  // 在npm run build 或 yarn build 时 ，生成文件的目录名称（要和baseUrl的生产环境路径一致）（默认dist）
  outputDir: "dist/" + process.env.VUE_APP_ENV,
  // 用于放置生成的静态资源 (js、css、img、fonts) 的；（项目打包之后，静态资源会放在这个文件夹下）
  // assetsDir: 'static',
  // 是否开启eslint保存检测，有效值：ture | false | 'error'
  lintOnSave: process.env.NODE_ENV === "development",
  // 如果你不需要生产环境的 source map，可以将其设置为 false 以加速生产环境构建。
  productionSourceMap: false,
  // webpack-dev-server 相关配置
  devServer: {
    host: "0.0.0.0",
    port: "80",
    // 自动打开浏览器
    open: true,
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      ["/api"]: {
        target: env.DOMAIN,
        changeOrigin: true,
        pathRewrite: {
          ["^/api"]: "",
        },
      },
    },
    disableHostCheck: true,
    // https: true,
  },
  css: {
    loaderOptions: {
      sass: {
        //依次导入的公用的scss变量，公用的scss混入，共用的默认样式
        prependData: `@import "./src/styles/variables.scss";`,
        // 因为 sass-loader 会检查运行环境的模式，给 dart-sass 传入 { outputStyle: “compressed”
        // }。 dart-sass 在这时会使用 BOM 而不是输出 @charset。
        // 如果是通过 @vue/cli 搭建的环境，因为有 cssnano 处理压缩，所以可以给 vue.config.js 传入 sassOptions 避免 compressed。
        sassOptions: { outputStyle: "expanded" },
      },
    },
  },
  configureWebpack(config) {
    const sassLoader = require.resolve("sass-loader");
    config.module.rules
      .filter((rule) => {
        return rule.test.toString().indexOf("scss") !== -1;
      })
      .forEach((item) => {
        item.oneOf.forEach((oneOfRule) => {
          const sassLoaderIndex = oneOfRule.use.findIndex(
            (item) => item.loader === sassLoader
          );
          oneOfRule.use.splice(sassLoaderIndex, 0, {
            loader: require.resolve("./css-unicode-loader"),
          });
        });
      });

    config.resolve.alias = {
      "@": resolve("src"),
    };

    if(process.env.NODE_ENV === "development"){
      config.devtool = 'cheap-module-source-map'
    }

    if (process.env.NODE_ENV !== "development") {
      // cdn
      if (env._ISCDN) {
        config.externals = {
          vue: "Vue",
          "element-ui": "ELEMENT",
          "vue-router": "VueRouter",
          vuex: "Vuex",
          axios: "axios",
        };
      }
    }
  },
  chainWebpack(config) {
    // 修复HMR
    config.resolve.symlinks(true);
    // set svg-sprite-loader
    config.module.rule("svg").exclude.add(resolve("src/assets/icons")).end();
    config.module
      .rule("icons")
      .test(/\.svg$/)
      .include.add(resolve("src/assets/icons/svg"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        // icon symbolId, 文件目录结构  => 命名： svg本级下的svg直接使用文件名，eg： icon-文件名；svg子目录下的svg使用需要带上该子目录文件夹名 eg：icon-文件夹名-文件名
        // # src/icons/svg
        // - icon1.svg        => icon-icon1
        // - icon2.svg        => icon-icon2
        // - dir/icon1.svg    => icon-dir-icon1
        symbolId: (filePath) => {
          let split = filePath.includes("/") ? "/icons/svg" : "\\icons\\svg";
          let str = filePath.slice(
            filePath.lastIndexOf(split) + split.length,
            -4
          ); // eg: '/ase/as
          return "icon" + str.replace(/[\/\\]/g, "-"); // icon-aa-ss
        },
        // symbolId: 'icon-[name]',
      })
      .end();

    // 删除 moment 语言包
    config
      .plugin("ignore")
      .use(
        new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
      );

    config.when(process.env.NODE_ENV !== "development", (config) => {
      // cdn
      if (env._ISCDN) {
        const cdn = {
          // 访问https://unpkg.com/element-ui/lib/theme-chalk/index.css获取最新版本
          css: [
            "//cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/theme-chalk/index.min.css",
            // '//unpkg.com/element-ui@2.15.7/lib/theme-chalk/index.css'
          ],
          js: [
            "//cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.runtime.min.js",
            "//cdn.bootcdn.net/ajax/libs/vuex/3.1.0/vuex.min.js",
            "//cdn.bootcdn.net/ajax/libs/vue-router/3.5.3/vue-router.min.js",
            "//cdn.bootcdn.net/ajax/libs/axios/0.26.0/axios.min.js",
            "//cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/index.min.js",
            // '//unpkg.com/vue@2.6.10/dist/vue.runtime.min.js', // 访问https://unpkg.com/vue/dist/vue.min.js获取最新版本
            // '//unpkg.com/vue-router@3.5.3/dist/vue-router.min.js',
            // '//unpkg.com/vuex@3.1.0/dist/vuex.min.js',
            // '//unpkg.com/axios@0.26.0/dist/axios.min.js',
            // '//unpkg.com/element-ui@2.15.7/lib/index.js',
          ],
        };
        // 如果使用多页面打包，使用vue inspect --plugins查看html是否在结果数组中
        config.plugin("html").tap((args) => {
          // html中添加cdn
          args[0].cdn = cdn;
          return args;
        });
        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.minimizer("terser").tap((options) => {
        options[0].terserOptions.compress.drop_console = !env._ISLOG;
        options[0].terserOptions.compress.drop_debugger = false;
        return options;
      });

      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");

      config.plugin("preload").tap(() => [
        {
          rel: "preload",
          // to ignore runtime.js
          fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
          include: "initial",
        },
      ]);

      // when there are many pages, it will cause too many meaningless requests
      config.plugins.delete("prefetch");

      env._ISGZIP &&
        config.plugin("compression").use("compression-webpack-plugin", [
          {
            filename: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
            threshold: 10240,
            minRatio: 0.8,
          },
        ]);

      process.env.npm_config_report &&
        config
          .plugin("webpack-bundle-analyzer")
          .use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin, [
            {
              analyzerMode: "static",
            },
          ])
          .end();
    });
  },
};
