vue.config.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. const path = require("path");
  2. const resolve = dir => path.join(__dirname, dir);
  3. const BundleAnalyzerPlugin = require("webpack-bundle-analyzer");
  4. const TerserPlugin = require("terser-webpack-plugin");
  5. const CompressionWebpackPlugin = require("compression-webpack-plugin");
  6. const productionGzipExtensions = ["js", "css"];
  7. const px2rem = require("postcss-px2rem");
  8. const SkeletonWebpackPlugin = require("vue-skeleton-webpack-plugin");
  9. const _env = process.env; // 不支持解构
  10. // == ant-design 主题覆盖 less (条件编译) == //
  11. let antDesignVariables = {};
  12. /* IFTRUE_ANT_DESIGN */
  13. antDesignVariables = {
  14. modifyVars: {
  15. hack: `true; @import "~@/styles/loader/ant-design.variables";`
  16. },
  17. javascriptEnabled: true
  18. };
  19. /* FITRUE_ANT_DESIGN */
  20. // es5语法, 导出一份拷贝: 修改需要重新运行
  21. module.exports = {
  22. // 基础配置
  23. publicPath: "./",
  24. outputDir: _env.DIR_OUT_PUT || "dist",
  25. assetsDir: "",
  26. lintOnSave: _env.NODE_ENV === "development",
  27. runtimeCompiler: true,
  28. productionSourceMap: false,
  29. // 本地代理
  30. devServer: {
  31. port: _env.VUE_APP_DEV_PORT,
  32. proxy: {
  33. [_env.VUE_APP_DEV_PROXY]: {
  34. // target字段为空编译报错
  35. target: _env.VUE_APP_BASE_API,
  36. changeOrigin: true,
  37. pathRewrite: {
  38. ["^" + _env.VUE_APP_DEV_PROXY]: ""
  39. }
  40. }
  41. },
  42. disableHostCheck: true
  43. },
  44. // css配置: 自动加载 loaderOptions 对 stylus 和 less 都无效
  45. css: {
  46. extract: true,
  47. sourceMap: false,
  48. loaderOptions: {
  49. // 自动加载仅导入主题: less sass stylus 方式不相同 - 细节详见 README.md
  50. stylus: {
  51. import: "~@/styles/loader/variables"
  52. },
  53. postcss: {
  54. plugins: [
  55. //基准大小 baseSize,需要和flexRem.js中相同
  56. px2rem({
  57. remUnit: _env.VUE_APP_REM_UNIT
  58. })
  59. ]
  60. },
  61. less: antDesignVariables
  62. }
  63. },
  64. chainWebpack: config => {
  65. // 运行 Webpack Bundle Analyzer插件:npm run analyze
  66. if (_env.IS_ANALYZE) {
  67. config
  68. .plugin("webpack-report")
  69. .use(BundleAnalyzerPlugin.BundleAnalyzerPlugin, [
  70. {
  71. analyzerMode: "static"
  72. }
  73. ]);
  74. }
  75. // 添加别名
  76. config.resolve.alias
  77. .set("@", resolve("src"))
  78. .set("storage", resolve("src/utils/storage"))
  79. .set("extend", resolve("src/styles/extend"))
  80. .set("mixin", resolve("src/styles/mixin"))
  81. .set("dinkle", resolve("src/modules/dinkle")) // 町洋阿拉丁
  82. .set("opay", resolve("src/modules/opay")); // 欧非项目
  83. // 模块配置使用链式语法
  84. config.module
  85. // 配置pug/jade
  86. .rule("pug")
  87. .test(/\.pug$/)
  88. .use("pug-plain-loader")
  89. .loader("pug-plain-loader")
  90. .end();
  91. },
  92. configureWebpack: config => {
  93. // 自动识别文件后缀
  94. config.resolve.extensions = [
  95. ".js",
  96. ".vue",
  97. ".json",
  98. ".css",
  99. ".styl",
  100. ".sass",
  101. ".scss",
  102. ".less"
  103. ];
  104. // vue骨架屏插件配置
  105. if (_env.VUE_APP_SKELETON) {
  106. config.plugins.push(
  107. new SkeletonWebpackPlugin({
  108. webpackConfig: {
  109. entry: {
  110. app: resolve("src/config/skeleton/conf")
  111. }
  112. },
  113. minimize: true,
  114. quiet: true
  115. })
  116. );
  117. }
  118. // 配置条件编译: js-conditional-compile-loader 下 npm 和 cnpm 不能混用
  119. config.module.rules.push({
  120. test: /\.js$/,
  121. include: [resolve("src"), resolve("test")],
  122. use: [
  123. {
  124. loader: "js-conditional-compile-loader",
  125. options: {
  126. isDebug: _env.NODE_ENV == "development", // optional, this is default
  127. // 自定义 flag (.env 是 string 化的值, 非合法 json: string 可使用 includes 函数, 单独效验使用正则)
  128. ANT_DESIGN: _env.VUE_APP_PLATFORM.includes(
  129. _env.VUE_APP_UI_ANT_DESIGN
  130. ),
  131. QUASAR: _env.VUE_APP_PLATFORM.includes(_env.VUE_APP_UI_QUASAR),
  132. ELEMENT: _env.VUE_APP_PLATFORM.includes(_env.VUE_APP_UI_ELEMENT)
  133. }
  134. }
  135. ]
  136. });
  137. // 开发环境独立配置 devtool
  138. if (_env.NODE_ENV === "development") {
  139. config.devtool = "source-map";
  140. }
  141. // 生产环境立配置
  142. if (_env.NODE_ENV === "production") {
  143. // 开启gzip压缩
  144. if (_env.IS_GZIP) {
  145. config.plugins.push(
  146. new CompressionWebpackPlugin({
  147. filename: "[path].gz[query]",
  148. algorithm: "gzip",
  149. test: new RegExp(
  150. "\\.(" + productionGzipExtensions.join("|") + ")$"
  151. ),
  152. threshold: 10240,
  153. minRatio: 0.8
  154. })
  155. );
  156. }
  157. // webpack4语法返回一个将会被合并的对象
  158. return {
  159. output: {
  160. // 输出重构: 打包编译后的文件名称【模块名称.chunkhash.版本号】- 添加文件夹(./js/)
  161. filename: `./js/[name].[chunkhash].${_env.VUE_APP_VERSION}.js`,
  162. chunkFilename: `./js/[name].[chunkhash].${_env.VUE_APP_VERSION}.js`
  163. },
  164. // 到打包chunk警告配置
  165. performance: {
  166. hints: "warning",
  167. // 入口起点的最大体积 整数类型(以字节为单位)
  168. maxEntrypointSize: 50000000,
  169. // 生成文件的最大体积 整数类型(以字节为单位 300k)
  170. maxAssetSize: 30000000,
  171. // 只给出 js 文件的性能提示
  172. assetFilter: function (assetFilename) {
  173. return assetFilename.endsWith(".js");
  174. }
  175. },
  176. // 拆包: 大文件拆分提升加载速度和懒加载
  177. optimization: {
  178. runtimeChunk: "single",
  179. splitChunks: {
  180. chunks: "all",
  181. maxInitialRequests: Infinity,
  182. minSize: 20000, // 依赖包超过20000bit将被单独打包
  183. cacheGroups: {
  184. vendor: {
  185. test: /[\\/]node_modules[\\/]/,
  186. name (module) {
  187. const packageName = module.context.match(
  188. /[\\/]node_modules[\\/](.*?)([\\/]|$)/
  189. )[1];
  190. return `npm.${packageName.replace("@", "")}`;
  191. }
  192. }
  193. }
  194. },
  195. // 代码压缩去除打印: npm i uglifyjs-webpack-plugin@1 需要使用低版本, 新版本不识别 const 关键字 - 报 npm audit fix
  196. minimizer: [
  197. new TerserPlugin({
  198. cache: false,
  199. sourceMap: false,
  200. parallel: true, // 使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
  201. terserOptions: {
  202. compress: {
  203. drop_debugger: true, // 去除 debugger
  204. drop_console: true, // 生产环境自动删除 console
  205. dead_code: true // 去除不可达代码: 如 if (false) { ... }
  206. },
  207. warnings: false
  208. }
  209. })
  210. ]
  211. }
  212. };
  213. }
  214. },
  215. // quasar: vue add quasar 自动添加
  216. pluginOptions: {
  217. quasar: {
  218. importStrategy: "manual",
  219. rtlSupport: false
  220. }
  221. },
  222. transpileDependencies: ["quasar"]
  223. };