記一次vue-cli 3.0 build包太大導致首屏過長的解決方案


1、路由懶加載

在 Webpack  中,我們可以使用動態 import語法來定義代碼分塊點 (split point): import('./Foo.vue') // 返回 Promise 如果您使用的是 Babel,你將需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正確地解析語法。 結合這兩者,這就是如何定義一個能夠被 Webpack 自動代碼分割的異步組件。 const Foo = () => import('./Foo.vue') 在路由配置中什么都不需要改變,只需要像往常一樣使用 Foo: const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] }) 復制代碼

2、服務器和webpack打包同時配置Gzip

Gzip是GNU zip的縮寫,顧名思義是一種壓縮技術。它將瀏覽器請求的文件先在服務器端進行壓縮,然后傳遞給瀏覽器,瀏覽器解壓之后再進行頁面的解析工作。在服務端開啟Gzip支持后,我們前端需要提供資源壓縮包,通過Compression-Webpack-Plugin插件build提供壓縮  

// 安裝插件 cnpm i --save-dev compression-webpack-plugin // 在vue-config.js 中加入 const CompressionWebpackPlugin = require('compression-webpack-plugin'); const productionGzipExtensions = ['js', 'css']; const isProduction = process.env.NODE_ENV === 'production'; ..... module.exports = { .... // 配置webpack configureWebpack: config => { if (isProduction) { // 開啟gzip壓縮 config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.js$|\.html$|\.json$|\.css/, threshold: 10240, minRatio: 0.8 })) } } } 復制代碼

3、優化打包chunk-vendor.js文件體積過大

 當我們運行項目並且打包的時候,會發現chunk-vendors.js這個文件非常大,那是因為webpack將所有的依賴全都壓縮到了這個文件里面,這時我們可以將其拆分,將所有的依賴都打包成單獨的js。
// 在vue-config.js 中加入 ..... module.exports = { .... // 配置webpack configureWebpack: config => { if (isProduction) { // 開啟分離js config.optimization = { runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, minSize: 20000, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name (module) { // get the name. E.g. node_modules/packageName/not/this/part.js // or node_modules/packageName const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] // npm package names are URL-safe, but some servers don't like @ symbols return `npm.${packageName.replace('@', '')}` } } } } }; } } } // 至此,你會發現原先的vender文件沒有了,同時多了好幾個依賴的js文件 復制代碼

4、啟用CDN加速

用Gzip已把文件的大小減少了三分之二了,但這個還是得不到滿足。那我們就把那些不太可能改動的代碼或者庫分離出來,繼續減小單個chunk-vendors,然后通過CDN加載進行加速加載資源。
// 修改vue.config.js 分離不常用代碼庫 // 如果不配置webpack也可直接在index.html引入 module.exports = { configureWebpack: config => { if (isProduction) { config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'moment': 'moment' } } } } // 在public文件夾的index.html 加載 <!-- CND --> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.runtime.min.js"></script> <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script> 復制代碼

5、完整vue.config.js代碼

const path = require('path') // 在vue-config.js 中加入 // 開啟gzip壓縮 const CompressionWebpackPlugin = require('compression-webpack-plugin'); // 判斷開發環境 const isProduction = process.env.NODE_ENV === 'production'; const resolve = dir => { return path.join(__dirname, dir) } // 項目部署基礎 // 默認情況下,我們假設你的應用將被部署在域的根目錄下, // 例如:https://www.my-app.com/ // 默認:'/' // 如果您的應用程序部署在子路徑中,則需要在這指定子路徑 // 例如:https://www.foobar.com/my-app/ // 需要將它改為'/my-app/' // iview-admin線上演示打包路徑: https://file.iviewui.com/admin-dist/ const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/' module.exports = { //webpack配置 configureWebpack:config => { // 開啟gzip壓縮 if (isProduction) { config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.js$|\.html$|\.json$|\.css/, threshold: 10240, minRatio: 0.8 })); // 開啟分離js config.optimization = { runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, minSize: 20000, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name (module) { // get the name. E.g. node_modules/packageName/not/this/part.js // or node_modules/packageName const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] // npm package names are URL-safe, but some servers don't like @ symbols return `npm.${packageName.replace('@', '')}` } } } } }; // 取消webpack警告的性能提示 config.performance = { hints:'warning', //入口起點的最大體積 maxEntrypointSize: 50000000, //生成文件的最大體積 maxAssetSize: 30000000, //只給出 js 文件的性能提示 assetFilter: function(assetFilename) { return assetFilename.endsWith('.js'); } } } }, // Project deployment base // By default we assume your app will be deployed at the root of a domain, // e.g. https://www.my-app.com/ // If your app is deployed at a sub-path, you will need to specify that // sub-path here. For example, if your app is deployed at // https://www.foobar.com/my-app/ // then change this to '/my-app/' publicPath: BASE_URL, // tweak internal webpack configuration. // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md devServer: { host: 'localhost', port: 8080, // 端口號 hotOnly: false, https: false, // https:{type:Boolean} open: true, //配置自動啟動瀏覽器 proxy:null // 配置跨域處理,只有一個代理 }, // 如果你不需要使用eslint,把lintOnSave設為false即可 lintOnSave: true, css:{ loaderOptions:{ less:{ javascriptEnabled:true } }, extract: true,// 是否使用css分離插件 ExtractTextPlugin sourceMap: false,// 開啟 CSS source maps modules: false// 啟用 CSS modules for all css / pre-processor files. }, chainWebpack: config => { config.resolve.alias .set('@', resolve('src')) // key,value自行定義,比如.set('@@', resolve('src/components')) .set('@c', resolve('src/components')) }, // 打包時不生成.map文件 productionSourceMap: false // 這里寫你調用接口的基礎路徑,來解決跨域,如果設置了代理,那你本地開發環境的axios的baseUrl要寫為 '' ,即空字符串 // devServer: { // proxy: 'localhost:3000' // } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM