创立我的项目
应用vue create xx
创立我的项目,依据本人的我的项目自行抉择即可;初始化我的项目结束后,可看到我的项目的目录构造中曾经存在vue.config.js
文件了。
publicPath
配置打包后的门路,须要留神的一点是当路由是history
模式时,门路须要设置为绝对路径,即/
而不是./
。同时 nginx 须要配置try_files $uri $uri/ /index.html;
module.exports = defineConfig({
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
})
outputDir
配置打包文件的寄存目录。
module.exports = defineConfig({
outputDir: 'dist',
})
productionSourceMap
是否在生产环境中应用 sourcemap,用于定位到谬误源码。(不倡议应用,会影响打包速度,且会让人看到本人的代码)
module.exports = defineConfig({
outputDir: 'dist',
})
devServer
配置 api 以及跨域端口等设置。
module.exports = defineConfig({
devServer: {
port: 8887,
hot: true,
compress: true, // 是否启动压缩 gzip
proxy: {
'/api': {
target: 'http://www.galaxychips.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
})
css 优化
创立我的项目时曾经抉择了 sass,打包时会主动转化为根底 css,且文件会独立分离出来。所以这里我只引入了一个全局变量文件。
module.exports = defineConfig({
css: {
loaderOptions: {
scss: {
additionalData: '@import "@/assets/scss/variables.scss";'
}
}
},
})
js 优化
生产环境下内置的插件曾经会解决压缩并用 babel 转化代码的操作。
cdn 减速
将专用库改为cdn
引入形式,放慢访问速度,注入html的插件无需装置,曾经内置。externals
和cdn
常量依据本人的我的项目而定。(文末会贴出代码)
module.exports = defineConfig({
chainWebpack: cOnfig=> {
if (process.env.NODE_ENV === 'production') {
config.externals(externals)
// 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
config.plugin('html')
.tap(args => {
args[0].cdn = cdn
return args
})
}
}
})
public/index.html 中须要写入注入代码。
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
">
<% } %>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<% } %>
留神:我应用的 ui 框架是vuetify
,应用 cdn 引入的话就不须要通过 import 引入款式,否则打包时会出错。
代码宰割
lru-cache
是我的项目中的额定插件,提取为一个独自的 chunk。
config
.optimization.splitChunks({
cacheGroups: {
styles: {
name: 'styles',
test: /\.(s?css|less|sass)$/,
chunks: 'all',
priority: 10
},
common: {
name: 'chunk-common',
chunks: 'all',
minChunks: 2, // 拆分前必须共享模块的最小 chunks 数。
maxInitialRequests: 5, // 打包后的入口文件加载时,还能同时加载js文件的数量(包含入口文件)
minSize: 0, // 生成 chunk 的最小体积(≈ 20kb)
priority: 1, // 优化将优先思考具备更高 priority(优先级)的缓存组
reuseExistingChunk: true // 如果以后 chunk 蕴含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
},
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: 2,
reuseExistingChunk: true
},
lrucache: {
name: 'chunk-lrucache',
test: /[\\/]node_modules[\\/]_?lru-cache(.*)/,
chunks: 'all',
priority: 3,
reuseExistingChunk: true
}
}
})
gzip压缩
运行npm install compression-webpack-plugin -D
装置压缩插件。
config.plugin('CompressionPlugin').use('compression-webpack-plugin', [{
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240, // 只解决比这个值大的资源。按字节计算
minRatio: 0.8 // 只有压缩率比这个值小的资源才会被解决
}])
整个配置详情如下
const { defineConfig } = require('@vue/cli-service')
const path = require('path')
// 门路解决办法
function resolve (dir) {
return path.join(__dirname, dir)
}
const externals = [
{
vue: 'Vue'
},
{
'vue-router': 'VueRouter'
},
{
axios: 'axios'
},
{
vuetify: 'Vuetify'
},
{
md5: 'MD5'
},
{
qs: 'Qs'
}
]
const cdn = {
css: [],
js: [
'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js',
'https://cdn.jsdelivr.net/npm/vuetify@2.6.0/dist/vuetify.min.js',
'https://cdn.jsdelivr.net/npm/md5@2.3.0/dist/md5.min.js',
'https://cdn.jsdelivr.net/npm/qs@6.11.0/dist/qs.min.js'
]
}
module.exports = defineConfig({
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
outputDir: 'dist',
productionSourceMap: false,
lintOnSave: process.env.NODE_ENV !== 'production',
devServer: {
port: 8887,
hot: true,
compress: true, // 是否启动压缩 gzip
proxy: {
'/api': {
target: 'http://www.xxxx.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
css: {
loaderOptions: {
scss: {
additionalData: '@import "@/assets/scss/variables.scss";'
}
}
},
configureWebpack: {
resolve: {
extensions: ['.vue', '.js', '.json', 'scss', 'css'],
alias: {
'@': resolve('src')
},
modules: [resolve('src'), 'node_modules']
},
module: {
},
plugins: [
]
},
chainWebpack: cOnfig=> {
if (process.env.NODE_ENV === 'production') {
config.externals(externals)
// 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
config.plugin('html')
.tap(args => {
args[0].cdn = cdn
return args
})
config.plugin('CompressionPlugin').use('compression-webpack-plugin', [{
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240, // 只解决比这个值大的资源。按字节计算
minRatio: 0.8 // 只有压缩率比这个值小的资源才会被解决
}])
config
.optimization.splitChunks({
cacheGroups: {
styles: {
name: 'styles',
test: /\.(s?css|less|sass)$/,
chunks: 'all',
priority: 10
},
common: {
name: 'chunk-common',
chunks: 'all',
minChunks: 2, // 拆分前必须共享模块的最小 chunks 数。
maxInitialRequests: 5, // 打包后的入口文件加载时,还能同时加载js文件的数量(包含入口文件)
minSize: 0, // 生成 chunk 的最小体积(≈ 20kb)
priority: 1, // 优化将优先思考具备更高 priority(优先级)的缓存组
reuseExistingChunk: true // 如果以后 chunk 蕴含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
},
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: 2,
reuseExistingChunk: true
},
lrucache: {
name: 'chunk-lrucache',
test: /[\\/]node_modules[\\/]_?lru-cache(.*)/,
chunks: 'all',
priority: 3,
reuseExistingChunk: true
}
}
})
}
}
})