vue.config.js 6.53 KB
const path = require("path")
const {
  publicPath,
  assetsDir,
  outputDir,
  lintOnSave,
  transpileDependencies,
  title,
  abbreviation,
  devPort,
  providePlugin,
  build7z,
} = require("./src/config/settings")
const { version, author } = require("./package.json")
const Webpack = require("webpack")
const WebpackBar = require("webpackbar")
const FileManagerPlugin = require("filemanager-webpack-plugin")
const date = require("dayjs")().format("YYYY_M_D")
const time = require("dayjs")().format("YYYY-M-D HH:mm:ss")
const CompressionWebpackPlugin = require("compression-webpack-plugin")
const productionGzipExtensions = ["html", "js", "css", "svg"]
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV)
process.env.VUE_APP_TITLE = title || "vue-admin-beautiful"
process.env.VUE_APP_AUTHOR = author || "chuzhixin"
process.env.VUE_APP_UPDATE_TIME = time
process.env.VUE_APP_VERSION = version

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

function mockServer() {
  if (process.env.NODE_ENV === "development") {
    const mockServer = require("./mock/mockServer.js")
    return mockServer
  } else {
    return ""
  }
}

const externals = {
  // vue: "Vue",
  // "vue-router": "VueRouter",
  // vuex: "Vuex",
  // axios: "axios",
  // echarts: "echarts",
  // lodash: "_",
  // "element-ui": "ELEMENT",
}

// CDN外链,会插入到index.html中
const cdn = {
  // 开发环境
  dev: {
    css: [],
    js: [],
  },
  // 生产环境
  build: {
    css: [],
    js: [
      // "https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js",
      // "https://cdn.jsdelivr.net/npm/vue-router@3.3.4/dist/vue-router.min.js",
      // "https://cdn.jsdelivr.net/npm/axios@0.19.2/dist/axios.min.js",
      // "https://cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js",
      // "https://cdn.jsdelivr.net/npm/echarts@5.1.2/dist/echarts.min.js",
      // "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js",
      // "https://cdn.jsdelivr.net/npm/element-ui@2.15.3/lib/index.min.js",
    ],
  },
}

module.exports = {
  publicPath,
  assetsDir,
  outputDir,
  lintOnSave,
  transpileDependencies,
  devServer: {
    disableHostCheck: true,
    hot: true,
    port: devPort,
    open: true,
    noInfo: false,
    overlay: {
      warnings: false,
      errors: true,
    },
    proxy: {
      "/api": {
        target: "http://192.168.31.140:11021/",
        // target: "https://ds.cixincloud.com/geca-api/",
        changeOrigin: true,
        pathRewrite: {
          "^/api": "",
        },
      },
    },
    // after: mockServer(),
  },
  configureWebpack(config) {
    if (IS_PROD) {
      config.externals = externals
    }
    return {
      resolve: {
        alias: {
          "@": resolve("src"),
          "^": resolve("src/components"),
          packages: resolve("packages"),
        },
      },
      plugins: [
        new Webpack.ProvidePlugin(providePlugin),
        new WebpackBar({
          name: abbreviation,
        }),
      ],
    }
  },
  chainWebpack(config) {
    config.plugins.delete("preload")
    config.plugins.delete("prefetch")
    config.resolve.symlinks(true)
    config.plugin("html").tap((args) => {
      if (IS_PROD) {
        args[0].cdn = cdn.build
      } else {
        args[0].cdn = cdn.dev
      }
      return args
    })

    config.module
      .rule("svg")
      .exclude.add(resolve("src/remixIcon"))
      .add(resolve("src/colorfulIcon"))
      .end()
    config.module
      .rule("remixIcon")
      .test(/\.svg$/)
      .include.add(resolve("src/remixIcon"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "remix-icon-[name]",
      })
      .end()
    config.module
      .rule("colorfulIcon")
      .test(/\.svg$/)
      .include.add(resolve("src/colorfulIcon"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "colorful-icon-[name]",
      })
      .end()
    config.module
      .rule("vue")
      .use("vue-loader")
      .loader("vue-loader")
      .tap((options) => {
        options.compilerOptions.preserveWhitespace = true
        return options
      })
      .end()
    config.when(process.env.NODE_ENV === "development", (config) => {
      config.devtool("cheap-module-eval-source-map")
    })
    config.when(process.env.NODE_ENV !== "development", (config) => {
      config.performance.set("hints", false)
      config.devtool("none")
      config
        .plugin("ScriptExtHtmlWebpackPlugin")
        .after("html")
        .use("script-ext-html-webpack-plugin", [
          {
            inline: /runtime\..*\.js$/,
          },
        ])
        .end()
      config.optimization.splitChunks({
        chunks: "all",
        cacheGroups: {
          libs: {
            name: "chunk-libs",
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: "initial",
          },
          elementUI: {
            name: "chunk-elementUI",
            priority: 20,
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
          },
          fortawesome: {
            name: "chunk-fortawesome",
            priority: 20,
            test: /[\\/]node_modules[\\/]_?@fortawesome(.*)/,
          },
          commons: {
            name: "chunk-commons",
            test: resolve("src/components"),
            minChunks: 3,
            priority: 5,
            reuseExistingChunk: true,
          },
        },
      })
      config.optimization.runtimeChunk("single")
    })
    config
      .plugin("compression")
      .use(CompressionWebpackPlugin, [
        {
          filename: "[path].gz[query]",
          algorithm: "gzip",
          test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
          threshold: 8192,
          minRatio: 0.8,
        },
      ])
      .end()
    if (build7z) {
      config.when(process.env.NODE_ENV === "production", (config) => {
        config
          .plugin("fileManager")
          .use(FileManagerPlugin, [
            {
              onEnd: {
                delete: [`./${outputDir}/video`, `./${outputDir}/data`],
                archive: [
                  {
                    source: `./${outputDir}`,
                    destination: `./${outputDir}/${abbreviation}.zip`,
                  },
                ],
              },
            },
          ])
          .end()
      })
    }
  },
  runtimeCompiler: true,
  productionSourceMap: false,
  css: {
    requireModuleExtension: true,
    sourceMap: true,
    loaderOptions: {
      scss: {
        prependData: '@import "~@/styles/variables.scss";',
      },
    },
  },
}