vue-cli3优化配置
本文转载自:张雪冬前端工程师学习园地-vue-cli3优化配置
1.使用cdn引入不改变的第三方库
const cdn = {
// 忽略打包的第三方库
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios'
},
// 通过cdn方式使用
js: [
'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js'
],
css: []
}
module.exports = {
chainWebpack: config => {
// 配置cdn引入
config.plugin('html').tap(args => {
args[0].cdn = cdn
return args
})
}
configureWebpack: config => {
// 忽略打包配置
config.externals = cdn.externals
}
}
- 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
1.1.public下的html页面引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!--循环引入-->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" crossorigin="anonymous"></script>
<% } %>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2.移除prefetch插件,避免加载多余的资源
module.exports = {
chainWebpack: config => {
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3.定义目录的简写路径
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
chainWebpack: config => {
// 定义文件夹的路径
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('router', resolve('src/router'))
.set('store', resolve('src/store'))
.set('views', resolve('src/views'))
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4.压缩图片
module.exports = {
chainWebpack: config => {
// 压缩图片
const imagesRule = config.module.rule('images')
imagesRule.uses.clear()
imagesRule.use('file-loader')
.loader('url-loader')
.options({
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
outputPath: 'static/images'
}
}
})
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
5.使用gzip压缩
需要安装插件
npm i compression-webpack-plugin -D
// 引入gzip压缩插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: config => {
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
}
},
// 需要gzip压缩的文件
devServer: {
host: 'localhost',
port: 8080, // 端口号
open: false, // 配置自动启动浏览器
before (app, server) {
app.get(/.*.(js)$/, (req, res, next) => {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
next()
})
}
}
}
- 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
6.配置全局sass无需再组件中引入即可使用
module.exports = {
css: {
extract: true,
sourceMap: false,
loaderOptions: {
// 定义全局scss无需引入即可使用
sass: {
prependData: `
@import "@/assets/css/variable.scss";
@import "@/assets/css/common.scss";
@import "@/assets/css/mixin.scss";
`
}
}
},
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
7.公共代码抽离
module.exports = {
configureWebpack: config => {
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
}
}
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
8.代码压缩去除console.log
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 移除console
}
}
})
)
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
完整的配置代码
// vue.config.js配置
const path = require('path')
// gzip压缩插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 代码打包之后取出console.log压缩代码
const TerserPlugin = require('terser-webpack-plugin')
// 图形化打包详情
const BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const cdn = {
// 忽略打包的第三方库
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios'
},
// 通过cdn方式使用
js: [
'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js'
],
css: []
}
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
// 是否触发eslint检查
lintOnSave: false,
publicPath: '/',
// 打包文件的出口
outputDir: 'dist',
// 放置生成的css和js和img和fonts的目录
assetsDir: 'static',
// 存放index.html模板的路径
indexPath: 'static/index.html',
productionSourceMap: false,
chainWebpack: config => {
// 配置cdn引入
config.plugin('html').tap(args => {
args[0].cdn = cdn
return args
})
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
// 定义文件夹的路径
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('router', resolve('src/router'))
.set('store', resolve('src/store'))
.set('views', resolve('src/views'))
// 压缩图片
const imagesRule = config.module.rule('images')
imagesRule.uses.clear()
imagesRule.use('file-loader')
.loader('url-loader')
.options({
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
outputPath: 'static/images'
}
}
})
// 压缩响应的app.json返回的代码压缩
config.optimization.minimize(true)
},
// webpack的配置
configureWebpack: config => {
// 忽略打包配置
config.externals = cdn.externals
// 生产环境配置
if (process.env.NODE_ENV === 'production') {
// 代码压缩去除console.log
config.plugins.push(
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 移除console
}
}
})
)
}
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
)
// 展示打包图形化信息
config.plugins.push(
new BundleAnalyzer()
)
// 公共代码抽离
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
}
}
}
}
},
css: {
extract: true,
sourceMap: false,
loaderOptions: {
// 定义全局scss无需引入即可使用
sass: {
prependData: `
@import "@/assets/css/variable.scss";
@import "@/assets/css/common.scss";
@import "@/assets/css/mixin.scss";
`
}
}
},
// 需要gzip压缩的文件
devServer: {
host: 'localhost',
port: 8080, // 端口号
open: false, // 配置自动启动浏览器
before (app, server) {
app.get(/.*.(js)$/, (req, res, next) => {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
next()
})
}
}
}
本文转载自:张雪冬前端工程师学习园地-vue-cli3优化配置
1.使用cdn引入不改变的第三方库
const cdn = {
// 忽略打包的第三方库
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios'
},
// 通过cdn方式使用
js: [
'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js'
],
css: []
}
module.exports = {
chainWebpack: config => {
// 配置cdn引入
config.plugin('html').tap(args => {
args[0].cdn = cdn
return args
})
}
configureWebpack: config => {
// 忽略打包配置
config.externals = cdn.externals
}
}
- 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
1.1.public下的html页面引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!--循环引入-->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" crossorigin="anonymous"></script>
<% } %>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2.移除prefetch插件,避免加载多余的资源
module.exports = {
chainWebpack: config => {
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3.定义目录的简写路径
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
chainWebpack: config => {
// 定义文件夹的路径
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('router', resolve('src/router'))
.set('store', resolve('src/store'))
.set('views', resolve('src/views'))
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4.压缩图片
module.exports = {
chainWebpack: config => {
// 压缩图片
const imagesRule = config.module.rule('images')
imagesRule.uses.clear()
imagesRule.use('file-loader')
.loader('url-loader')
.options({
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
outputPath: 'static/images'
}
}
})
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
5.使用gzip压缩
需要安装插件
npm i compression-webpack-plugin -D
// 引入gzip压缩插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: config => {
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
}
},
// 需要gzip压缩的文件
devServer: {
host: 'localhost',
port: 8080, // 端口号
open: false, // 配置自动启动浏览器
before (app, server) {
app.get(/.*.(js)$/, (req, res, next) => {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
next()
})
}
}
}
- 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
6.配置全局sass无需再组件中引入即可使用
module.exports = {
css: {
extract: true,
sourceMap: false,
loaderOptions: {
// 定义全局scss无需引入即可使用
sass: {
prependData: `
@import "@/assets/css/variable.scss";
@import "@/assets/css/common.scss";
@import "@/assets/css/mixin.scss";
`
}
}
},
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
7.公共代码抽离
module.exports = {
configureWebpack: config => {
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
}
}
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
8.代码压缩去除console.log
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 移除console
}
}
})
)
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
完整的配置代码
// vue.config.js配置
const path = require('path')
// gzip压缩插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 代码打包之后取出console.log压缩代码
const TerserPlugin = require('terser-webpack-plugin')
// 图形化打包详情
const BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const cdn = {
// 忽略打包的第三方库
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios'
},
// 通过cdn方式使用
js: [
'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js'
],
css: []
}
function resolve (dir) {
return path.join(__dirname, dir)
}
module.exports = {
// 是否触发eslint检查
lintOnSave: false,
publicPath: '/',
// 打包文件的出口
outputDir: 'dist',
// 放置生成的css和js和img和fonts的目录
assetsDir: 'static',
// 存放index.html模板的路径
indexPath: 'static/index.html',
productionSourceMap: false,
chainWebpack: config => {
// 配置cdn引入
config.plugin('html').tap(args => {
args[0].cdn = cdn
return args
})
// 移除prefetch插件,避免加载多余的资源
config.plugins.delete('prefetch')
// 定义文件夹的路径
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('router', resolve('src/router'))
.set('store', resolve('src/store'))
.set('views', resolve('src/views'))
// 压缩图片
const imagesRule = config.module.rule('images')
imagesRule.uses.clear()
imagesRule.use('file-loader')
.loader('url-loader')
.options({
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
outputPath: 'static/images'
}
}
})
// 压缩响应的app.json返回的代码压缩
config.optimization.minimize(true)
},
// webpack的配置
configureWebpack: config => {
// 忽略打包配置
config.externals = cdn.externals
// 生产环境配置
if (process.env.NODE_ENV === 'production') {
// 代码压缩去除console.log
config.plugins.push(
new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log'] // 移除console
}
}
})
)
}
// 开启gzip压缩
config.plugins.push(
new CompressionWebpackPlugin(
{
filename: info => {
return `${info.path}.gz${info.query}`
},
algorithm: 'gzip',
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
test: new RegExp('\\.(' + ['js'].join('|') + ')$'
),
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
}
)
)
// 展示打包图形化信息
config.plugins.push(
new BundleAnalyzer()
)
// 公共代码抽离
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
}
}
}
}
},
css: {
extract: true,
sourceMap: false,
loaderOptions: {
// 定义全局scss无需引入即可使用
sass: {
prependData: `
@import "@/assets/css/variable.scss";
@import "@/assets/css/common.scss";
@import "@/assets/css/mixin.scss";
`
}
}
},
// 需要gzip压缩的文件
devServer: {
host: 'localhost',
port: 8080, // 端口号
open: false, // 配置自动启动浏览器
before (app, server) {
app.get(/.*.(js)$/, (req, res, next) => {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
next()
})
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南