vue.config.js
9.08 KB
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
/* jshint esversion: 6 */
const path = require('path');
const webpack = require('webpack');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const assetsDir = 'static';
const resolve = dir => path.join(__dirname, dir);
// posix兼容方式处理路径
const posixJoin = _path => path.posix.join(assetsDir, _path);
const lastVersion = new Date().getTime();
const isProd = process.env.NODE_ENV === 'production';
// dns预加载,优化接口请求
const dnsPrefetch = [
'https://cdn.jsdelivr.net',
'https://cdn.bootcss.com'
];
// cdn预加载使用
const externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'vant': 'vant',
'$': 'jquery',
'jquery': 'Jquery',
'moment': 'moment',
'_': 'lodash',
'Fastclick': 'fastclick'
};
const cdn = {
// 开发环境
dev: {
css: [],
js: []
},
// 生产环境
build: {
css: [
// 'https://cdn.jsdelivr.net/npm/vant@1.5/lib/index.css'
'http://boh.onwall.cn/vant@1.5/lib/index.css'
],
js: [
'https://cdn.bootcss.com/vue/2.5.21/vue.min.js',
'https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js',
'https://cdn.bootcss.com/axios/0.18.0/axios.min.js',
// 'https://cdn.jsdelivr.net/npm/vant@1.5/lib/vant.min.js',
'http://boh.onwall.cn/vant@1.5/lib/vant.min.js',
'https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js',
'https://cdn.bootcss.com/moment.js/2.23.0/moment.min.js',
'https://cdn.bootcss.com/lodash.js/4.17.11/lodash.core.min.js',
// 'https://cdn.bootcss.com/lodash.js/4.17.11/lodash.min.js',
'https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js'
]
}
};
// 是否使用gzip
const productionGzip = true;
// 需要gzip压缩的文件后缀
const productionGzipExtensions = ['js', 'css'];
// 多页模板页
var pages = {
// 默认页
index: {
entry: 'src/index.js',
template: 'public/index.html',
filename: 'index.html',
title: 'Index Page',
chunks: ['chunk-vendors', 'chunk-common', 'index']
}
};
var prod_custom = require('./config/prod-custom');
var dev_custom = require('./config/dev-custom');
function getEntryPages (array) {
for (let i = 0; i < array.length; i++) {
pages[array[i].page] = {
// page 的入口
entry: `src/multiPages/${array[i].page}/${array[i].page}.js`,
// 模板来源
template: `public/${array[i].page}.html`,
// 在 dist/index.html 的输出
filename: `${array[i].page}.html`,
// 当使用 title 选项时,
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: `${array[i].title}`,
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', array[i].page]
};
}
return pages;
}
if (process.env.NODE_ENV === 'production') {
pages = getEntryPages(prod_custom);
}
if (process.env.NODE_ENV === 'development') {
pages = getEntryPages(dev_custom);
}
module.exports = {
// 基本路径
publicPath: process.env.NODE_ENV === 'production' ? '/boh/' : '/',
// 输出文件目录
outputDir: 'dist',
// 放置生成的静态资源的目录
assetsDir,
// 指定生成的 index.html 的输出路径 (相对于 outputDir)。也可以是一个绝对路径。
// indexPath: 'index.html',
filenameHashing: true,
pages,
// eslint-loader 是否在保存的时候检查
lintOnSave: 'error',
// 是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了。
runtimeCompiler: true,
// 生产环境是否生成 sourceMap 文件
productionSourceMap: false,
// 如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中。
// 如果这个值是一个函数,则会接收被解析的配置作为参数。该函数及可以修改配置并不返回任何东西,也可以返回一个被克隆或合并过的配置版本。
configureWebpack: config => {
config.plugins.push(
new webpack.ProvidePlugin({
'vue': 'Vue',
'$': 'jquery',
'jQuery': 'jquery',
'_': 'lodash',
'axios': 'axios',
'moment': 'moment'
})
);
//
config.resolve.extensions = ['.js', '.vue', '.json', '.less', '.css'];
//
// config.resolve.alias.assets = path.resolve(__dirname, './src/assets');
// config.resolve.alias.components = path.resolve(__dirname, './src/components');
// 修改webpack config, 使其不打包externals下的资源
if (process.env.NODE_ENV === 'production') {
// 生成环境执行task任务,写入版本号
// const task = require('./task');
// task.run(lastVersion);
// 1. 生产环境npm包转CDN
config.externals = externals;
// 2. 构建时开启gzip,降低服务器压缩对CPU资源的占用,服务器也要相应开启gzip
if (productionGzip) {
config.plugins.push(
new CompressionWebpackPlugin({
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
})
);
}
}
if (process.env.NODE_ENV === 'development') {
// 1. 生产环境npm包转CDN
config.externals = externals;
}
},
// 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。
chainWebpack: (config) => {
/**
* 删除懒加载模块的 prefetch preload,降低带宽压力
*/
// config.plugins
// .delete('prefetch')
// .delete('preload');
config.resolve.alias
.set('vue$', 'vue/dist/vue.esm.js')
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'));
// 清除警告
config.performance
.set('hints', false);
// 将版本号写入环境变量
config
.plugin('define')
.tap(args => {
args[0].app_build_version = lastVersion;
return args;
});
config
.when(isProd, config =>
// 生产环境js增加版本号
config.output
.set('filename', posixJoin(`js/${lastVersion}-[name].[chunkhash].js`))
.set('chunkFilename', posixJoin(`js/${lastVersion}-[id].[chunkhash].js`))
);
/**
* 添加CDN参数到htmlWebpackPlugin配置中, 详见public/index.html 修改
* vue inspect --plugins 查询插件 使用pages会有多个html实例
*/
config
.plugin('html-index')
.tap(args => {
if (process.env.NODE_ENV === 'production') {
}
args[0].cdn = cdn.build;
args[0].dnsPrefetch = dnsPrefetch;
return args;
})
.end()
.plugin('html-login')
.tap(args => {
if (process.env.NODE_ENV === 'production') {
}
args[0].cdn = cdn.build;
args[0].dnsPrefetch = dnsPrefetch;
return args;
})
.end();
},
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
// 增加版本号
extract: !isProd ? false : {
filename: posixJoin(`css/${lastVersion}-[name].[contenthash:8].css`),
chunkFilename: posixJoin(`css/${lastVersion}-[name].[contenthash:8].css`)
},
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {
css: {
// 这里的选项会传递给 css-loader
},
postcss: {
// 这里的选项会传递给 postcss-loader
}
},
// 默认情况下,只有 *.module.[ext] 结尾的文件才会被视作 CSS Modules 模块。设置为 true 后你就可以去掉文件名中的 .module 并将所有的 *.(css|scss|sass|less|styl(us)?) 文件视为 CSS Modules 模块。
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,
// PWA 插件相关配置
// see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: false,
// open: process.platform === 'darwin',
host: '0.0.0.0',
port: 8180,
https: false,
hotOnly: false,
// 设置代理
proxy: {
'api': {
filter: ['/op/', '/fi/', '/de/', '/st/', '/fr/', '/pr/', '/pu/', '/dl/', '/b/', '/t/', '/rpt/'],
target: 'http://dev.kmlab.com/boh',
// target: 'http://itomix-dev.kmlab.com/boh'
changeOrigin: true,
pathRewrite: {
'^/(.*)': '/$1'
},
onProxyReq: function (proxyReq, req, res, options) {
proxyReq.setHeader('X-Proxy-Host', req.header('host'));
proxyReq.setHeader('X-Proxy-Request-URI', req.url);
}
}
},
before: app => {},
overlay: {
warnings: false,
errors: true
}
},
// 第三方插件配置
pluginOptions: {
// dll: {
// entry: ['vue', 'vue-route', 'vuex', 'axios', 'vant', 'moment', 'lodash', 'jquery']
// }
}
};