const path = require('path');
const { defineConfig } = require('@vue/cli-service');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const PreloadPlugin = require('@vue/preload-webpack-plugin');

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

const NODE_ENV = process.env.NODE_ENV;
const port = process.env.port || 6589;

module.exports = defineConfig({
  publicPath: NODE_ENV === 'development' ? '/' : './',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: NODE_ENV === 'development',
  runtimeCompiler: true,
  productionSourceMap: false,
  devServer: {
    port,
    open: {
      target: [`http://localhost:${port}`],
    },
    client: {
      overlay: {
        warnings: false,
        errors: true,
      },
    },
    proxy: {
      [process.env.VUE_APP_BASE_API]: {
        // target: 'https://gcls.utschool.cn/',
        target: 'https://gcls.helxsoft.cn/',
        // target: 'https://youthchinesedu.blcup.com/',
        changeOrigin: true,
        pathRewrite: {
          [`^${process.env.VUE_APP_BASE_API}`]: '',
        },
      },
      [process.env.VUE_APP_FILE]: {
        // target: 'https://file-cs.helxsoft.cn',
        target: 'https://file-kf.helxsoft.cn/',
        changeOrigin: true,
        pathRewrite: {
          [`^${process.env.VUE_APP_FILE}`]: '',
        },
      },
    },
  },
  css: {
    loaderOptions: {
      sass: {
        additionalData: '@use "@/styles/variables.scss" as *;',
      },
    },
  },
  configureWebpack: {
    name: '首页',
    // 配置路径别名
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    devtool: NODE_ENV === 'development' ? 'source-map' : false,
    plugins: [
      // stylelint 配置
      new StyleLintPlugin({
        files: ['src/**/*.{vue,html,css,scss}'],
        fix: true, // 是否自动修复
        failOnError: false,
      }),
      new CompressionPlugin({
        algorithm: 'gzip', // 使用gzip压缩
        test: /\.js$|\.html$|\.css$/, // 匹配文件名
        minRatio: 0.8, // 压缩率小于0.8才会压缩
        threshold: 10240, // 对超过10k的数据压缩
        deleteOriginalAssets: false, // 是否删除未压缩的源文件，谨慎设置，如果希望提供非gzip的资源，可不设置或者设置为false（比如删除打包后的gz后还可以加载到原始资源文件）
      }),
    ],
  },
  chainWebpack(config) {
    // 启用预加载，提高首屏加载速度
    config
      .plugin('preload')
      .use(PreloadPlugin, [
        {
          rel: 'preload',
          include: 'initial',
          fileBlacklist: [/\.map$/, /hot-update\.js$/],
          as(entry) {
            if (/\.css$/.test(entry)) return 'style';

            return 'script';
          },
        },
      ])
      .after('html');

    // 当页面很多时，prefetch 将导致太多无意义的请求，开启这个
    config
      .plugin('prefetch')
      .use(PreloadPlugin, [
        {
          rel: 'prefetch',
          include: 'asyncChunks',
        },
      ])
      .after('html');

    // 设置 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();

    config.when(NODE_ENV !== 'development', () => {
      config.optimization.splitChunks({
        chunks: 'all',
        cacheGroups: {
          libs: {
            name: 'chunk-libs',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: 'initial', // 仅打包最初依赖的第三方
          },
          elementUI: {
            name: 'chunk-elementUI', // 将elementUI拆分为一个包
            priority: 20, // 权重必须大于libs和app，否则将被打包到libs或app中
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
          },
          commons: {
            name: 'chunk-commons',
            test: resolve('src/components'), // 可以自定义规则
            minChunks: 3, // 最小公用数
            priority: 5,
            reuseExistingChunk: true,
          },
        },
      });

      // https://webpack.js.org/configuration/optimization/#optimizationruntimechunk
      config.optimization.runtimeChunk('single');
    });
  },
});
