-
Notifications
You must be signed in to change notification settings - Fork 0
/
vue.config.js
304 lines (298 loc) · 11.2 KB
/
vue.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
const path = require('path');
const join = path.join;
const fs = require('fs');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const Config = require('./build/config');
const devServer = require('./build/dev-server');
console.log('config');
// TODO: delete
// 设置使用mock数据
process.env.VUE_APP_IS_MOCK = true;
// const PrerenderSPAPlugin = require('prerender-spa-plugin');
// const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
// const isProduction = process.env.NODE_ENV === 'production';
// development 开发环境
// production 生产环境
// test 测试环境
const isCompression = process.env.VITE_APP_BASE_ENV === 'production'; // 只有在生产环境才需要各种压缩功能
// vue inspect > config.js 生成配置到config.js 查看配置
// 通过递归获取文件夹内所有文件路径
function findSync(startPath) {
let result = [];
function finder(path) {
let files = fs.readdirSync(path);
files.forEach((val) => {
let fPath = join(path, val);
let stats = fs.statSync(fPath);
if (stats.isDirectory()) finder(fPath);
if (stats.isFile()) {
if (fPath.indexOf('.md') === -1) {
result.push(fPath);
}
}
});
}
finder(startPath);
return result;
}
const fileNames = findSync('./src/assets/global'); // 拿到global里面的所有文件路径
const cssGlobal = fileNames.map((filename) => `@import "${filename}";`.replace(/\\/g, '/')).join('');
// cdn预加载使用
const externals = {
// vue: 'Vue',
// 'vue-router': 'VueRouter',
// vuex: 'Vuex',
// axios: 'axios',
// Vconsole: 'vconsole',
};
const cdn = {
// 生产环境
build: {
css: [],
js: [
// 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
// 'https://cdn.bootcss.com/vue-router/3.0.3/vue-router.min.js',
// 'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
// 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js',
],
},
};
const prodConfigureWebpack = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
priority: 2,
reuseExistingChunk: true,
enforce: true,
},
elementUI: {
name: 'chunk-elementUI',
priority: 20,
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
},
commons: {
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
reuseExistingChunk: true,
enforce: true,
},
},
},
// 用户缓存,不会每次都修改打包的文件
runtimeChunk: {
name: (entrypoint) => `runtimechunk-${entrypoint.name}`,
},
},
};
module.exports = {
outputDir: process.env.VUE_APP_outputDir || 'dist/pms-other',
lintOnSave: true, // true开启 false关闭eslint
productionSourceMap: true, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: isCompression,
// dev环境下开启sourceMap方便查找元素对应文件
sourceMap: !isCompression,
loaderOptions: {
// 这里的选项会传递给对应-loader
sass: {
// 你可以在这里引入全局scss, 这样就不用每个页面都引入
prependData: cssGlobal,
},
},
},
// 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
transpileDependencies: ['swiper', 'dom7'],
// 离线缓存 pwa应用
// https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
pwa: {
// api https://developers.google.cn/web/tools/workbox/
workboxOptions: {
importWorkboxFrom: 'local', // 本地server worker
skipWaiting: true, // 跳过等待
clientsClaim: true, // 立刻获取页面控制权
exclude: [/\.map$/, /asset-manifest\.json$/],
runtimeCaching: [].concat(Config.webpack.pwa.runtimeCaching),
},
},
// parallel: os.cpus().length > 1, // 构建时开启多进程处理babel编译 已经默认开启
configureWebpack: (config) => {
// config.entry = './src/main.js'; // 默认是main.ts
config.mode = process.env.NODE_ENV; //指定webpack的编译环境
// cheap-module-source-map 无法捕获错误位置,强压缩代码 prod
// cheap-module-eval-source-map (默认)加快编译速度
// config.devtool = isCompression ? 'cheap-module-source-map' : 'cheap-module-eval-source-map';
config.devtool = process.env.VUE_APP_BASE_ENV !== 'development' ? 'cheap-module-source-map' : 'cheap-module-eval-source-map';
// 修改js压缩配置
config.optimization.splitChunks = prodConfigureWebpack.optimization.splitChunks;
config.optimization.runtimeChunk = prodConfigureWebpack.optimization.runtimeChunk;
// externals里的模块不打包
Object.assign(config, { externals: externals });
if (isCompression) {
// 移除console
Object.assign(config.optimization.minimizer[0].options.terserOptions.compress, {
warnings: false,
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log'],
});
// gzip压缩
config.plugins.push(
// 还可以开启比 gzip 体验更好的 Zopfli 压缩详见https://webpack.js.org/plugins/compression-webpack-plugin
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(js|css|svg|woff|ttf|json|html|txt|ico)(\?.*)?$/i,
threshold: 10240, // 大于10kb的会压缩
deleteOriginalAssets: false, //压缩后删除原文件
minRatio: 0.8,
})
);
}
},
chainWebpack(config) {
const webpackConfig = Config.webpack;
// css有关的loader不建议在这里修改,在loaderOptions中修改即可
if (webpackConfig.noPreload) {
// 移除 prefetch 插件
// 当页面过多时去除,防止页面出现过多的请求
config.plugins.delete('prefetch');
// 移除 preload 插件
// config.plugins.delete('preload');
}
// 加快首屏加载速度
config.plugin('preload').tap(() => [
{
rel: 'preload',
// to ignore runtime.js
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
include: 'initial',
},
]);
if (webpackConfig.pwa.off) {
// 移除 pwa
config.plugins.delete('pwa');
config.plugins.delete('workbox');
}
// alias配置,
// 可以通过.get(key)获取、.set(key, value)设置、.delete(key)
// config.resolve.alias.get('@')
// config.resolve.extensions.push('.tsxxx');
if (webpackConfig.alias) {
Object.keys(webpackConfig.alias).forEach((key) => {
let value = webpackConfig.alias[key];
value = path.resolve(__dirname, value.replace(/..\//, './src/'));
config.resolve.alias.set(key, value);
});
}
// 图片压缩(仅 production环境)
// if (isProduction && webpackConfig.imgCompress) {
// config.module
// .rule('images')
// .use('image-webpack-loader')
// .loader('image-webpack-loader')
// .tap((options) => {
// options = options || {};
// options['mozjpeg'] = { progressive: true, quality: 75 };
// // optipng.enabled: false will disable optipng
// options['optipng'] = { enabled: false };
// options['gifsicle'] = { interlaced: true };
// options['pngquant'] = { quality: '75-90', speed: 4 };
// // win7貌似用不了下面的
// // the webp option will enable WEBP
// // options['webp'] = {
// // quality: 75,
// // };
// return options;
// });
// }
// 修改全局配置
if (webpackConfig.globalParams) {
config.plugin('define').tap((args) => {
Object.keys(webpackConfig.globalParams).forEach((key) => {
let value = webpackConfig.globalParams[key];
if (value) args[0]['process.env'][`${key}`] = JSON.stringify(value);
});
return args;
});
}
// 非history模式下这个预渲染功能无效
// if (isProduction && webpackConfig.globalParams.ROUTER_MODE === 'history' && webpackConfig.spaPrerender.open) {
// config.plugin('prerender').use(PrerenderSPAPlugin, [
// {
// // 生成文件的路径,也可以与webpakc打包的一致。
// // 下面这句话非常重要!!!
// // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
// staticDir: path.join(__dirname, 'dist'),
// // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
// routes: webpackConfig.spaPrerender.routes,
// // 这个很重要,如果没有配置这段,也不会进行预编译
// renderer: new Renderer({
// inject: {
// foo: 'bar',
// },
// //其他操纵up选项。
// //(请参阅此处:https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions)
// headless: false, //渲染时显示浏览器窗口。对于调试很有用。
// // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
// renderAfterDocumentEvent: 'render-event',
// }),
// },
// ]);
// }
config.plugin('html').tap((args) => {
// 注 pubilc中的index.html页面中需要做对应参数的填充
// if (isProduction)
args[0].cdn = cdn.build;
args[0].inject = true;
return args;
});
},
devServer: {
// host: '0.0.0.0',
port: 8080, // 端口号
open: false, //配置自动启动浏览器
// public: '100.119.193.240:8080', // 解决 Network: unavailable
overlay: {
// 输出到屏幕上,错误
warnings: true,
errors: true,
},
// 配置启动mock数据
...(process.env.VUE_APP_IS_MOCK !== 'false' ? { setup: (app) => devServer.install(app) } : {}),
// headers: {
// 'Access-Control-Allow-Origin': '*',
// },
hotOnly: false,
disableHostCheck: true,
// proxy: {
// '/pms-server': {
// // target: 'https://gw-test-fl.sfflive.com', // 服务器
// target: 'https://gw.sfflive.com', // 服务器
// changeOrigin: true,
// },
// '/pms-report-api': {
// // target: 'https://gw-test-fl.sfflive.com', // 服务器
// target: 'https://gw.sfflive.com', // 服务器
// changeOrigin: true,
// },
// '/fl-apartment': {
// // target: 'https://gw-test-fl.sfflive.com', // 服务器
// target: 'https://gw.sfflive.com', // 服务器
// changeOrigin: true,
// },
// '/pms-pay-service': {
// target: 'https://gw-test-fl.sfflive.com', // 服务器
// changeOrigin: true,
// },
// },
},
};