vue.config.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. "use strict";
  2. const path = require("path");
  3. const webpack = require("webpack");
  4. function resolve(dir) {
  5. return path.join(__dirname, dir);
  6. }
  7. //读取npm指令 process.argv 获取⾃定义参数
  8. let argvs = process.argv.filter((e) => e.includes("="));
  9. for (const iterator of argvs) {
  10. let diyArg = iterator.split("=");
  11. process.env["VUE_APP_" + diyArg[0].slice(2)] = diyArg[1];
  12. }
  13. process.env.VUE_APP_ENV = process.env.VUE_APP_ENV || process.env.NODE_ENV;
  14. const env = require("./env");
  15. process.env.VUE_APP_TITLE = env.SYSTEM_NAME_ALL;
  16. process.env.VUE_APP_PACKETTIME = new Date().toLocaleString();
  17. // vue.config.js 配置说明
  18. //官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
  19. // 这里只列一部分,具体配置参考文档
  20. module.exports = {
  21. // 部署生产环境和开发环境下的URL。
  22. // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
  23. // 例如 https://www.xx.cn/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.xx.cn/admin/,则设置 baseUrl 为 /admin/。
  24. publicPath: env.BASE_URL || "/",
  25. // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
  26. outputDir: "dist/" + process.env.VUE_APP_ENV,
  27. // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
  28. // assetsDir: 'static',
  29. // 是否开启eslint保存检测,有效值:ture | false | 'error'
  30. lintOnSave: process.env.NODE_ENV === "development",
  31. // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
  32. productionSourceMap: false,
  33. // webpack-dev-server 相关配置
  34. devServer: {
  35. host: "0.0.0.0",
  36. port: "80",
  37. // 自动打开浏览器
  38. open: true,
  39. proxy: {
  40. // detail: https://cli.vuejs.org/config/#devserver-proxy
  41. ["/api"]: {
  42. target: env.DOMAIN,
  43. changeOrigin: true,
  44. pathRewrite: {
  45. ["^/api"]: "",
  46. },
  47. },
  48. },
  49. disableHostCheck: true,
  50. // https: true,
  51. },
  52. css: {
  53. loaderOptions: {
  54. sass: {
  55. //依次导入的公用的scss变量,公用的scss混入,共用的默认样式
  56. prependData: `@import "./src/styles/variables.scss";`,
  57. // 因为 sass-loader 会检查运行环境的模式,给 dart-sass 传入 { outputStyle: “compressed”
  58. // }。 dart-sass 在这时会使用 BOM 而不是输出 @charset。
  59. // 如果是通过 @vue/cli 搭建的环境,因为有 cssnano 处理压缩,所以可以给 vue.config.js 传入 sassOptions 避免 compressed。
  60. sassOptions: { outputStyle: "expanded" },
  61. },
  62. },
  63. },
  64. configureWebpack(config) {
  65. const sassLoader = require.resolve("sass-loader");
  66. config.module.rules
  67. .filter((rule) => {
  68. return rule.test.toString().indexOf("scss") !== -1;
  69. })
  70. .forEach((item) => {
  71. item.oneOf.forEach((oneOfRule) => {
  72. const sassLoaderIndex = oneOfRule.use.findIndex(
  73. (item) => item.loader === sassLoader
  74. );
  75. oneOfRule.use.splice(sassLoaderIndex, 0, {
  76. loader: require.resolve("./css-unicode-loader"),
  77. });
  78. });
  79. });
  80. config.resolve.alias = {
  81. "@": resolve("src"),
  82. };
  83. if(process.env.NODE_ENV === "development"){
  84. config.devtool = 'cheap-module-source-map'
  85. }
  86. if (process.env.NODE_ENV !== "development") {
  87. // cdn
  88. if (env._ISCDN) {
  89. config.externals = {
  90. vue: "Vue",
  91. "element-ui": "ELEMENT",
  92. "vue-router": "VueRouter",
  93. vuex: "Vuex",
  94. axios: "axios",
  95. };
  96. }
  97. }
  98. },
  99. chainWebpack(config) {
  100. // 修复HMR
  101. config.resolve.symlinks(true);
  102. // set svg-sprite-loader
  103. config.module.rule("svg").exclude.add(resolve("src/assets/icons")).end();
  104. config.module
  105. .rule("icons")
  106. .test(/\.svg$/)
  107. .include.add(resolve("src/assets/icons/svg"))
  108. .end()
  109. .use("svg-sprite-loader")
  110. .loader("svg-sprite-loader")
  111. .options({
  112. // icon symbolId, 文件目录结构 => 命名: svg本级下的svg直接使用文件名,eg: icon-文件名;svg子目录下的svg使用需要带上该子目录文件夹名 eg:icon-文件夹名-文件名
  113. // # src/icons/svg
  114. // - icon1.svg => icon-icon1
  115. // - icon2.svg => icon-icon2
  116. // - dir/icon1.svg => icon-dir-icon1
  117. symbolId: (filePath) => {
  118. let split = filePath.includes("/") ? "/icons/svg" : "\\icons\\svg";
  119. let str = filePath.slice(
  120. filePath.lastIndexOf(split) + split.length,
  121. -4
  122. ); // eg: '/ase/as
  123. return "icon" + str.replace(/[\/\\]/g, "-"); // icon-aa-ss
  124. },
  125. // symbolId: 'icon-[name]',
  126. })
  127. .end();
  128. // 删除 moment 语言包
  129. config
  130. .plugin("ignore")
  131. .use(
  132. new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
  133. );
  134. config.when(process.env.NODE_ENV !== "development", (config) => {
  135. // cdn
  136. if (env._ISCDN) {
  137. const cdn = {
  138. // 访问https://unpkg.com/element-ui/lib/theme-chalk/index.css获取最新版本
  139. css: [
  140. "//cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/theme-chalk/index.min.css",
  141. // '//unpkg.com/element-ui@2.15.7/lib/theme-chalk/index.css'
  142. ],
  143. js: [
  144. "//cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.runtime.min.js",
  145. "//cdn.bootcdn.net/ajax/libs/vuex/3.1.0/vuex.min.js",
  146. "//cdn.bootcdn.net/ajax/libs/vue-router/3.5.3/vue-router.min.js",
  147. "//cdn.bootcdn.net/ajax/libs/axios/0.26.0/axios.min.js",
  148. "//cdn.bootcdn.net/ajax/libs/element-ui/2.15.7/index.min.js",
  149. // '//unpkg.com/vue@2.6.10/dist/vue.runtime.min.js', // 访问https://unpkg.com/vue/dist/vue.min.js获取最新版本
  150. // '//unpkg.com/vue-router@3.5.3/dist/vue-router.min.js',
  151. // '//unpkg.com/vuex@3.1.0/dist/vuex.min.js',
  152. // '//unpkg.com/axios@0.26.0/dist/axios.min.js',
  153. // '//unpkg.com/element-ui@2.15.7/lib/index.js',
  154. ],
  155. };
  156. // 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中
  157. config.plugin("html").tap((args) => {
  158. // html中添加cdn
  159. args[0].cdn = cdn;
  160. return args;
  161. });
  162. config
  163. .plugin("ScriptExtHtmlWebpackPlugin")
  164. .after("html")
  165. .use("script-ext-html-webpack-plugin", [
  166. {
  167. // `runtime` must same as runtimeChunk name. default is `runtime`
  168. inline: /runtime\..*\.js$/,
  169. },
  170. ])
  171. .end();
  172. }
  173. config.optimization.minimizer("terser").tap((options) => {
  174. options[0].terserOptions.compress.drop_console = !env._ISLOG;
  175. options[0].terserOptions.compress.drop_debugger = false;
  176. return options;
  177. });
  178. config.optimization.splitChunks({
  179. chunks: "all",
  180. cacheGroups: {
  181. libs: {
  182. name: "chunk-libs",
  183. test: /[\\/]node_modules[\\/]/,
  184. priority: 10,
  185. chunks: "initial", // only package third parties that are initially dependent
  186. },
  187. // elementUI: {
  188. // name: 'chunk-elementUI', // split elementUI into a single package
  189. // priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
  190. // test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
  191. // },
  192. commons: {
  193. name: "chunk-commons",
  194. test: resolve("src/components"), // can customize your rules
  195. minChunks: 3, // minimum common number
  196. priority: 5,
  197. reuseExistingChunk: true,
  198. },
  199. },
  200. });
  201. config.optimization.runtimeChunk("single");
  202. config.plugin("preload").tap(() => [
  203. {
  204. rel: "preload",
  205. // to ignore runtime.js
  206. fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
  207. include: "initial",
  208. },
  209. ]);
  210. // when there are many pages, it will cause too many meaningless requests
  211. config.plugins.delete("prefetch");
  212. env._ISGZIP &&
  213. config.plugin("compression").use("compression-webpack-plugin", [
  214. {
  215. filename: "[path].gz[query]",
  216. algorithm: "gzip",
  217. test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
  218. threshold: 10240,
  219. minRatio: 0.8,
  220. },
  221. ]);
  222. process.env.npm_config_report &&
  223. config
  224. .plugin("webpack-bundle-analyzer")
  225. .use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin, [
  226. {
  227. analyzerMode: "static",
  228. },
  229. ])
  230. .end();
  231. });
  232. },
  233. };