forked from Airubby/vue-cli3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvue.config.js
290 lines (287 loc) · 10.6 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
const path = require("path");
const chalk = require('chalk')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const isProduction = process.env.NODE_ENV === 'production';
const externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'element-ui': 'ELEMENT',
'swiper':'Swiper',
'echarts':'echarts'
}
// CDN外链,会插入到index.html中
const cdn = {
// 开发环境
dev: {
css: [
'./nodepackage/element-ui/lib/theme-chalk/index.css',
'./nodepackage/swiper/dist/css/swiper.min.css'
],
js: []
},
// 生产环境
build: {
css: [
'./nodepackage/element-ui/lib/theme-chalk/index.css',
'./nodepackage/swiper/dist/css/swiper.min.css'
],
js: [
'./nodepackage/vue/dist/vue.min.js',
'./nodepackage/vue-router/dist/vue-router.min.js',
'./nodepackage/vuex/dist/vuex.min.js',
'./nodepackage/axios/dist/axios.min.js',
'./nodepackage/element-ui/lib/index.js',
'./nodepackage/swiper/dist/js/swiper.min.js',
'./nodepackage/echarts/dist/echarts.min.js',
]
}
}
// 是否使用预渲染
const productionPrerender = true
// 需要预渲染的路由
const prerenderRoutes = ['/', '/login']
// 是否使用gzip
const productionGzip = true
// 需要gzip压缩的文件后缀
const productionGzipExtensions = ['js', 'css']
module.exports = {
// 基本路径
publicPath: './',
// 输出主文件名称
indexPath: './index.html',
//baseUrl: process.env.NODE_ENV === "production" ? "./" : "/"
// 输出文件目录
outputDir: 'dist',
// eslint-loader 是否在保存的时候检查
lintOnSave: false,
//放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
// assetsDir: 'static',
// use the full build with in-browser compiler?
// https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
// compiler: false,
// webpack配置
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
chainWebpack: config => {
// // 配置别名
// config.resolve.alias.set("@", path.join(__dirname, "src"))
/**
* 删除懒加载模块的prefetch,降低带宽压力
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch
* 而且预渲染时生成的prefetch标签是modern版本的,低版本浏览器是不需要的
*/
config.plugins.delete('prefetch')
config.plugins.delete('preload');
// 压缩代码
config.optimization.minimize(true);
// 分割代码
config.optimization.splitChunks({
chunks: 'all'
})
/**
* 添加CDN参数/将externals定义的不需要Webpack打包编译的到htmlWebpackPlugin配置中,
*/
config
.plugin('html')
.tap(args => {
if (isProduction) {
args[0].cdn = cdn.build
}
if (!isProduction) {
args[0].cdn = cdn.dev
}
return args
})
/**
* 无需使用@import在每个scss文件中引入变量或者mixin,也可以避免大量@import导致build变慢
* sass-resources-loader 文档链接:https://github.com/shakacode/sass-resources-loader
*/
const oneOfsMap = config.module.rule('scss').oneOfs.store
const sassResources = ['color.scss', 'mixin.scss', 'common.scss'] // scss资源文件,可以在里面定义变量,mixin,全局混入样式等
oneOfsMap.forEach(item => {
item
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: sassResources.map(file => path.resolve(__dirname, 'src/style/' + file))
})
.end()
})
},
//公共代码抽离
configureWebpack: config => {
const myConfig = {}
if (isProduction) {
// 1. 生产环境npm包转CDN,externals定义的部分不需要Webpack打包编译
myConfig.externals = externals
// 2. 使用预渲染,在仅加载html和css之后即可显示出基础的页面,提升用户体验,避免白屏
myConfig.plugins = []
productionPrerender && myConfig.plugins.push(
new PrerenderSPAPlugin({
staticDir: path.resolve(__dirname, './'), // 作为express.static()中间件的路径
outputDir: path.resolve(__dirname, './'),
indexPath: path.resolve(__dirname, 'index.html'),
routes: prerenderRoutes,
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
keepClosingSlash: true,
sortAttributes: true
},
postProcess (renderedRoute) {
/**
* 懒加载模块会自动注入,无需直接通过script标签引入
* 而且预渲染的html注入的是modern版本的懒加载模块
* 这会导致在低版本浏览器出现报错,需要剔除
* 这并不是一个非常严谨的正则,不适用于使用了 webpackChunkName: "group-foo" 注释的懒加载
*/
renderedRoute.html = renderedRoute.html.replace(
/<script[^<]*chunk-[a-z0-9]{8}\.[a-z0-9]{8}.js[^<]*><\/script>/g,
function (target) {
console.log(chalk.bgRed('\n\n剔除的懒加载标签:'), chalk.magenta(target))
return ''
}
)
return renderedRoute
}
})
)
//3.js代码整合
let optimization= {
splitChunks: {
cacheGroups: {
vendor:{
chunks:"all",
test: /node_modules/,
name:"vendor",
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority:100,
},
common: {
chunks:"all",
test:/[\\/]src[\\/]js[\\/]/,
name: "common",
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority:60
},
styles: {
name: 'styles',
test: /\.(le|sa|sc|c)ss$/,
chunks: 'all',
enforce: true,
},
runtimeChunk: {
name: 'manifest'
}
}
},
}
Object.assign(config, {
optimization
})
// 4. 构建时开启gzip,降低服务器压缩对CPU资源的占用,服务器也要相应开启gzip
productionGzip && myConfig.plugins.push(
new CompressionWebpackPlugin({
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 8192,
minRatio: 0.8
})
)
}
if (!isProduction) {
/**
* 关闭host check,方便使用ngrok之类的内网转发工具
*/
myConfig.devServer = {
disableHostCheck: true
}
let optimization={
minimizer:[
new TerserPlugin({
cache: true,
// 将多线程关闭 webpack会92%卡住的问题
parallel: false
})
]
}
Object.assign(config, {
optimization
})
}
return myConfig
// Object.assign(config, {
// // 开发生产共同配置
// resolve: {
// alias: {
// '@': path.resolve(__dirname, './src'),
// }
// }
// });
},
// vue-loader 配置项
// https://vue-loader.vuejs.org/en/options.html
// vueLoader: {},
// 生产环境是否生成 sourceMap 文件
productionSourceMap: false,
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {
//为每个css引入公共需要引入的样式
// less:{
// data:`@import "@/assets/public.less"`
// }
},
// 启用 CSS modules for all css / pre-processor files.
modules: false
},
// use thread-loader for babel & TS in production build
// enabled by default if the machine has more than 1 cores
parallel: require('os').cpus().length > 1,
// 是否启用dll
// See https://github.com/vuejs/vue-cli/blob/dev/docs/cli-service.md#dll-mode
// dll: false,
// PWA 插件相关配置
// see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
// pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: true,
compress: false, // 开启压缩
overlay: {
warnings: true,
errors: true
},
host: '0.0.0.0',
port: 8081,
https: false,
hotOnly: false,
// 设置代理
// proxy: {
// '/ISmac/ismacsite': {
// target: 'http://192.168.16.6:8090', // 你接口的域名
// secure: false, // 如果是https接口,需要配置这个参数
// changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
// pathRewrite:{
// '^/ISmac/ismacsite':'/ISmac/ismacsite'
// }
// }
// },
before: app => {
}
},
// 第三方插件配置
pluginOptions: {}
}