const fs = require('fs')
const { merge } = require('webpack-merge')
const path = require('path')
const moment = require('moment')
const { defineConfig } = require('@vue/cli-service')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const CompressionPlugin = require('compression-webpack-plugin')
const tsImportPluginFactory = require('ts-import-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

const convertPath = (dir) => path.resolve(__dirname, dir)
const outputDir = convertPath('app/dist') // 打包输出目录

module.exports = defineConfig({
  transpileDependencies: true,
  productionSourceMap: false, // 打包取消.map
  publicPath: './',
  outputDir,
  pages: {
    indexPath: {
      entry: process.env.VUE_APP_ROOT + 'main.ts',
      template: process.env.VUE_APP_ROOT + 'index.html',
      filename: 'index.html',
      title: process.env.VUE_APP_TITLE,
      meta: {
        revised: moment(new Date()).format('YYYYMMDDHHmmss')  // 打包生成版本号
      }
    }
  },
  devServer: {
    client: {
      overlay: false
    }
  },
  css: {
    extract: true, // 是否使用css分离插件 ExtractTextPlugin
    sourceMap: false,
    loaderOptions: {
      postcss: {
        postcssOptions: {
          config: process.env.VUE_APP_ROOT, // 自定义 postcss.config.js 文件路径，https://webpack.docschina.org/loaders/postcss-loader/#postcss-options
        }
      }
    }
  },
  chainWebpack: (config) => {
    config.resolve.alias
      .set('@public', convertPath('public/'))
      .set('@pc', convertPath('src/packages/pc/'))
      .set('@mobile', convertPath('src/packages/mobile/'))

    config.module
      .rule('ts')
      .use('ts-loader')
      .tap((options) => {
        options = merge(options, {
          transpileOnly: true,
          getCustomTransformers: () => ({
            before: [
              // vant 按需引入
              tsImportPluginFactory({
                libraryName: 'vant',
                libraryDirectory: 'es',
                style: true
              })
            ],
            compilerOptions: {
              module: 'es2015'
            }
          })
        })
        return options;
      })

    config.plugin('compressionPlugin')
      .use(new CompressionPlugin({
        test: /\.js$|\.html$|\.css/, // 匹配文件名
        threshold: 10240, // 对超过10k的数据压缩
      }))

    config.plugin('fork-ts-checker')
      .use(new ForkTsCheckerWebpackPlugin({
        typescript: {
          memoryLimit: 4096,
        },
      }))
  },
  configureWebpack: (config) => {
    const oem = process.env.VUE_APP_OEM

    config.devtool = 'source-map'

    // const manifestPath = oem ? convertPath(oem + 'manifest.json') : convertPath('public/manifest.json')
    // const manifestContents = fs.readFileSync(manifestPath, 'utf-8')
    // const manifest = JSON.parse(manifestContents)
    // console.log(manifest)

    if (process.env.NODE_ENV === 'production' && !process.argv.includes('test')) {
      const configPath = oem ? convertPath(oem + 'config/appconfig.json') : convertPath('public/config/appconfig.json')
      const cfgContents = fs.readFileSync(configPath, 'utf-8')
      const cfg = JSON.parse(cfgContents)

      // 自动修改版本号
      if (process.argv.includes('ver')) {
        const arr = cfg.version.split('.').map(Number)
        arr[arr.length - 1] += 1 // 版本号自动+1

        // 版本号100进1
        for (let i = arr.length - 1; i >= 0; i--) {
          if (i > 0 && arr[i] > 99) {
            arr[i] = 0
            if (arr[i - 1] > -1) {
              arr[i - 1] += 1
            }
          }
        }

        cfg.version = arr.join('.')
        cfg.versionCode = (Number(cfg.versionCode) + 1).toString()
      }

      cfg.appName = process.env.VUE_APP_NAME
      cfg.tradeChannel = process.env.VUE_APP_TRADE_CHANNEL

      fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2))
      console.log(cfg)
    }

    if (oem) {
      // 打包时复制指定目录文件到目标目录
      config.plugins.push(new CopyWebpackPlugin({
        patterns: [
          {
            from: convertPath(oem), // 指定目录
            to: outputDir, // 目标目录
            force: true, // 强制覆盖文件
          }
        ]
      }))
    }
  }
})
