1.关闭productionSourceMap
最新件脚手架不自带配置文件
先在根目录新建vue.config.js文件,在vue.config.js中写入如下内容:
module.exports = {
productionSourceMap: false
}
2.开启Gzip压缩
安装插件compression-webpack-plugin。这个插件必须配合后台,服务器上nginx也必须开启gzip才能生效
npm install --save-dev compression-webpack-plugin
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development';
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
productionSourceMap: false,
configureWebpack: config => {
// 生产环境相关配置
if (isProduction) {
//gzip压缩
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.html$|.\css/,
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
})
)
}
},
}
3.开启CDN加速(有可能cdn会挂掉,也可以不配置这选项)
// 本地环境是否需要使用cdn
const devNeedCdn = false
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development';
// cdn链接
const cdn = {
// cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
externals: {
vue: "Vue",
vuex: "Vuex",
"vue-router": "VueRouter",
axios: "axios",
vant: "vant",
},
//
// cdn的css链接
css: ["https://cdn.jsdelivr.net/npm/vant@2.10/lib/index.css"],
// cdn的js链接
js: [
"https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js",
"https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js",
"https://cdn.jsdelivr.net/npm/vue-router@3.4.9/dist/vue-router.min.js",
"https://cdn.jsdelivr.net/npm/vant@2.10/lib/vant.min.js",
"https://cdn.jsdelivr.net/npm/axios@0.21.0/dist/axios.min.js",
],
};
module.exports = {
chainWebpack: config => {
config.plugin('html').tap(args => {
// 生产环境或本地需要cdn时,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
},
configureWebpack: config => {
// 用cdn方式引入,则构建时要忽略相关资源
if (isProduction || devNeedCdn) config.externals = cdn.externals
}
}
然后在index.html中引入使用了CDN的链接(使用了loading动画,刷新时不会出现空白加载)
<html lang="en" style="width: 100%;height: 100%;">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<style>
#vue-loading{
background-color: #fff;
height: 100%;
width: 100%;
position: fixed;
z-index: 99999;
margin-top: 0px;
top: 0px;
}
#loading-center{
width: 100%;
height: 100%;
position: relative;
}
#loading-center-absolute {
position: absolute;
left: 50%;
top: 50%;
height: 150px;
width: 150px;
margin-top: -75px;
margin-left: -75px;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.object{
width: 20px;
height: 20px;
background-color:#eb8819;
position: absolute;
left: 65px;
top: 65px;
}
.object:nth-child(2n+0) {
margin-right: 0px;
}
#object_one {
-webkit-animation: object_one 2s infinite;
animation: object_one 2s infinite;
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s;
}
#object_two {
-webkit-animation: object_two 2s infinite;
animation: object_two 2s infinite;
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
#object_three {
-webkit-animation: object_three 2s infinite;
animation: object_three 2s infinite;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
#object_four {
-webkit-animation: object_four 2s infinite;
animation: object_four 2s infinite;
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}
#object_five {
-webkit-animation: object_five 2s infinite;
animation: object_five 2s infinite;
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
}
#object_six {
-webkit-animation: object_six 2s infinite;
animation: object_six 2s infinite;
-webkit-animation-delay: 0.7s;
animation-delay: 0.7s;
}
#object_seven {
-webkit-animation: object_seven 2s infinite;
animation: object_seven 2s infinite;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
#object_eight {
-webkit-animation: object_eight 2s infinite;
animation: object_eight 2s infinite;
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
#object_big{
position: absolute;
width: 50px;
height: 50px;
left: 50px;
top: 50px;
-webkit-animation: object_big 2s infinite;
animation: object_big 2s infinite;
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}
@-webkit-keyframes object_big {
50% { -webkit-transform: scale(0.5); }
}
@keyframes object_big {
50% {
transform: scale(0.5);
-webkit-transform: scale(0.5);
}
}
@-webkit-keyframes object_one {
50% { -webkit-transform: translate(-65px,-65px) ; }
}
@keyframes object_one {
50% {
transform: translate(-65px,-65px) ;
-webkit-transform: translate(-65px,-65px) ;
}
}
@-webkit-keyframes object_two {
50% { -webkit-transform: translate(0,-65px) ; }
}
@keyframes object_two {
50% {
transform: translate(0,-65px) ;
-webkit-transform: translate(0,-65px) ;
}
}
@-webkit-keyframes object_three {
50% { -webkit-transform: translate(65px,-65px) ; }
}
@keyframes object_three {
50% {
transform: translate(65px,-65px) ;
-webkit-transform: translate(65px,-65px) ;
}
}
@-webkit-keyframes object_four {
50% { -webkit-transform: translate(65px,0) ; }
}
@keyframes object_four {
50% {
transform: translate(65px,0) ;
-webkit-transform: translate(65px,0) ;
}
}
@-webkit-keyframes object_five {
50% { -webkit-transform: translate(65px,65px) ; }
}
@keyframes object_five {
50% {
transform: translate(65px,65px) ;
-webkit-transform: translate(65px,65px) ;
}
}
@-webkit-keyframes object_six {
50% { -webkit-transform: translate(0,65px) ; }
}
@keyframes object_six {
50% {
transform: translate(0,65px) ;
-webkit-transform: translate(0,65px) ;
}
}
@-webkit-keyframes object_seven {
50% { -webkit-transform: translate(-65px,65px) ; }
}
@keyframes object_seven {
50% {
transform: translate(-65px,65px) ;
-webkit-transform: translate(-65px,65px) ;
}
}
@-webkit-keyframes object_eight {
50% { -webkit-transform: translate(-65px,0)} ;
}
@keyframes object_eight {
50% {
transform: translate(-65px,0) ;
-webkit-transform: translate(-65px,0) ;
}
}
</style>
<!-- 使用CDN的CSS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.css) { %>
<link
href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
rel="stylesheet"
/>
<% } %>
<!-- 使用CDN的CSS文件 -->
<title>人人家智慧社区</title>
</head>
<body style="width: 100%;height: 100%;">
<noscript>
<strong>We're sorry but blog doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="vue-loading">
<div id="loading-center">
<div id="loading-center-absolute">
<div class="object" id="object_one"></div>
<div class="object" id="object_two"></div>
<div class="object" id="object_three"></div>
<div class="object" id="object_four"></div>
<div class="object" id="object_five"></div>
<div class="object" id="object_six"></div>
<div class="object" id="object_seven"></div>
<div class="object" id="object_eight"></div>
<div class="object" id="object_big"></div>
</div>
</div>
</div>
<div id="app"></div>
<!-- built files will be auto injected -->
<!-- 使用CDN的JS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- 使用CDN的JS文件 -->
<script>
window.onload=function(){
if(document.querySelector("#vue-loading") !==undefined){
document.querySelector("#vue-loading").remove()
}
}
</script>
</body>
</html>
4.代码压缩
安装
npm i -D uglifyjs-webpack-plugin
// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
//生产环境自动删除console
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: false,
parallel: true
})
)
5.公共代码抽离,写在configureWebpack模块中
// 公共代码抽离
configureWebpack: config => {
// 生产环境相关配置
if (isProduction) {
config.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: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
}
},
6.图片压缩()
安装
npm i image-webpack-loader --save-dev
在chainWebpack中新增以下代码
configureWebpack: config => {
// 生产环境相关配置
if (isProduction) {
config.module.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
.end()
}
},
6.最终代码
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development';
// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin')
//path引入
const path = require('path')
// 本地环境是否需要使用cdn
const devNeedCdn = false
// cdn链接
const cdn = {
// cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
externals: {
vue: "Vue",
vuex: "Vuex",
"vue-router": "VueRouter",
axios: "axios",
vant: "vant",
},
//
// cdn的css链接
css: ["https://cdn.jsdelivr.net/npm/vant@2.10/lib/index.css"],
// cdn的js链接
js: [
"https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js",
"https://cdn.jsdelivr.net/npm/vuex@3.5.1/dist/vuex.min.js",
"https://cdn.jsdelivr.net/npm/vue-router@3.4.9/dist/vue-router.min.js",
"https://cdn.jsdelivr.net/npm/vant@2.10/lib/vant.min.js",
"https://cdn.jsdelivr.net/npm/axios@0.21.0/dist/axios.min.js",
],
};
module.exports = {
productionSourceMap: false,
chainWebpack: config => {
// ============注入cdn start============
config.plugin('html').tap(args => {
// 生产环境或本地需要cdn时,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============注入cdn start============
// ============压缩图片 start============
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
.end()
// ============压缩图片 end============
},
configureWebpack: config => {
// 用cdn方式引入,则构建时要忽略相关资源
if (isProduction || devNeedCdn) config.externals = cdn.externals
// 生产环境相关配置
if (isProduction) {
//gzip压缩
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test:/\.js$|\.html$|.\css/,
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件
})
)
// 代码压缩
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
//生产环境自动删除console
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: false,
parallel: true
})
)
}
// 公共代码抽离
config.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: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
}
}