我的项目的版本是基于
@vue/cli 5.0.4
和webpack@5.73.0
vue-cli
5 版本曾经内置了 webpack5
,且很多配置都内置化了,换言之,根底打包无需在vue.config.js
中配置了,大大简化了配置过程。因为次要是针对我的项目的优化,所以创立的过程会简略,上面是优化的具体详情。
我的项目初始化
-
装置 vue-cli
npm install -g @vue/cli
-
创立我的项目
应用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 中须要写入注入代码。
<head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@2.6.0/dist/vuetify.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"> <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css"> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"> <% } %> </head> <body> <!-- built files will be auto injected --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body>
留神:我应用的 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 } } }) } } })