hello,咱又見了~~嘻嘻。本次主要來講說這個打包優化的問題。一個vue項目從開發到上線必須得經歷打包過程,一個項目的打包優化與否都決定了你這個項目的運行速度以及用戶體驗。本次主要是針對vue.config,js
的配置進行優化。項目地址javascript
開發環境與生產環境的配置也是開發中的必不可少的一環。本項目是由vue-cli3
開發,vue-cli3
深度集成了webpack
,若是不熟悉vue-cli3
能夠先去官網看看相關配置。css
在項目根目錄下新建.env.development
文件代表是開發環境。html
VUE_APP_CURRENTMODE ="development" //當前的環境 VUE_APP_LOGOUT_URL="http://localhost:3000/" //開發環境的地址
在項目根目錄下新建.env.production
文件代表是生產環境。vue
VUE_APP_CURRENTMODE ="development" //當前的環境 VUE_APP_LOGOUT_URL="xxx" //生產環境的地址
固然你也能夠本身建立一個測試環境.env.test
,一樣能夠像上邊同樣配置。java
那麼接下來咱們怎麼用它呢?這裏不得不說一下的是package.json
裏面的兩個命令serve
,build
,其實對應的是全命令是vue-cli-service serve --mode development
,vue-cli-service build --mode production
,若是你想要在構建命令中使用開發環境變量,那麼能夠加入node
"dev-build": "vue-cli-service build --mode development"
接下來在vue.config.js
運用它。webpack
config.plugin('define').tap(args => { args[0]['process.env'].VUE_APP_LOGOUT_URL = JSON.stringify(process.env.VUE_APP_LOGOUT_URL) console.log(args[0]) return args; });
這裏有必要說下,這段代碼是寫在chainWebpack
配置項下面。這段代碼其實運用了兩個webpack
插件webpack-chain
容許配置鏈式操做,以及webpack.DefinePlugin
。ios
process.env.VUE_APP_LOGOUT_URL
常量,在src
文件夾下面均可以使用。瞭解更多 首先思考,咱們引入的第三方包與咱們的業務代碼一塊兒打包會產生什麼問題?
顧名思義,咱們的業務代碼變更比較頻繁,而咱們引入的第三方包基本上不會變更。瀏覽器會有緩存,沒有變更的文件會直接從緩存中讀取,這也間接的優化了網站的訪問速速。
接下來配置vue.config.js
,git
//代碼分割 config.optimization.minimize(true); config.optimization.splitChunks({ chunks: 'all', cacheGroup:{ //vue2-editor單獨打一個包 vueEdior: { name: 'vueEdior', test: /[\\/]node_modules[\\/]vue2-editor[\\/]/, priority: 10 // 優先級要大於 vendors 否則會被打包進 vendors }, //其他的第三方包打進vendor vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 } } })
組件是vue項目的重要組成部分。至關一部分組件均可以公用,在不一樣的文件中引入,所以咱們能夠將這部分公用的組件直接分割出來。github
config.optimization.minimize(true); config.optimization.splitChunks({ chunks: 'all', cacheGroup:{ vueEdior: { name: 'vueEdior', test: /[\\/]node_modules[\\/]vue2-editor[\\/]/, priority: 10 // 優先級要大於 vendors 否則會被打包進 vendors }, public: { name: 'public', test: resolve('src/components'), minSize: 0, //表示在壓縮前的最小模塊大小,默認值是 30kb minChunks: 2, // 最小公用次數 priority: 5, // 優先級 reuseExistingChunk: true // 公共模塊必開啓 }, //其他的第三方包打進vendor vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 } } })
打包完後會發現dist/static/js
,多了一個vueEditor
和public
文件,這就代表分割完成。
咱們能夠進一步優化,打包默認生成map文件,從而致使包的體積過大,這時咱們須要設定一個屬性來關閉它。
productionSourceMap: false
alias
運用的好處在於不用一級級的去找,而是直接鎖定位置,從而減小文件搜索時間。
//設置別名 config.resolve.alias .set('@', resolve('src')) .set('@api', resolve('src/api/api'))//接口地址 .set('@assets', resolve('src/assets'))
若是上面的方式都編寫了,文件依舊過大,這個時候不得不考慮代碼壓縮和去掉console插件了,能夠說爲了優化項目,「無所不用其極」。
首先安裝開始安裝
cnpm install compression-webpack-plugin --save-dev
而後在configureWebpack
裏面配置它
const CompressionWebpackPlugin = require('compression-webpack-plugin') new CompressionWebpackPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + ['js', 'css'].join('|') + ')$', ), threshold: 10240, minRatio: 0.8, }),
值得注意的是gzip
壓縮文件須要後端來配合支持,若是後端沒有支持那麼項目加載的依舊是沒有壓縮的文件。
首先安裝
cnpm install uglifyjs-webpack-plugin --save-dev
而後在configureWebpack
裏面配置它
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_debugger: true, drop_console: true, }, }, sourceMap: false, parallel: true, }),
有的同窗說後端沒有支持gzip
壓縮加載,那怎麼辦?那只有涼拌咯~~~。
這裏給你們介紹一個cdn引入的方式,有的第三方插件太大,致使單獨分包後仍是挺大的,這個時候能夠考慮用cdn的方式引入文件。
首先咱們不讓webpack打包用cdn引入的文件
//對一些不常常改動的庫,能夠經過cdn引入,webpack不對他們打包 let externals = { 'vue': 'Vue', 'axios': 'axios', 'element-ui': 'ELEMENT', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'echarts': 'echarts', 'vue2-editor': 'VueEditor' }
而後配置cdn
const cdn = { css: [ //element-ui css 'https://unpkg.com/element-ui/lib/theme-chalk/index.css' ], js: [ //vue 'https://unpkg.com/vue@2.6.10/dist/vue.min.js', //axios 'http://cdn.staticfile.org/axios/0.19.0-beta.1/axios.min.js', //vuex 'https://unpkg.com/vuex@3.1.0/dist/vuex.min.js', //vue-router 'https://unpkg.com/vue-router@3.0.6/dist/vue-router.min.js', //element 'https://unpkg.com/element-ui@2.7.2/lib/index.js', //echarts 'https://cdn.jsdelivr.net/npm/echarts@4.2.1/dist/echarts.min.js', //vue2-editor "https://unpkg.com/vue2-editor@2.6.6/dist/vue2-editor.js" ] }
接下來在chainWebpack
配置
process.env.VUE_APP_CURRENTMODE === 'production') { config.externals(externals)//忽略打包 config.plugin('html') .tap(args => { args[0].cdn = cdn; return args }) }
這裏須要解釋的是config.plugin('html')
實際上是運用了 html-webpack-plugin
插件在其實例化的options
掛載cdn
對象,而後經過ejs
模板語法,讀取相關cdn。
緊接着咱們須要在public/index.html
中讀取相關cdn
<% if (process.env.VUE_APP_CURRENTMODE === 'production') { %> <% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%=css%>" as="style"> <% } %> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <script src="<%=js%>"></script> <% } %> <% } %>
至此cdn引入完成
因爲手動引入cdn太過麻煩,並且擔憂版本變化,每次都須要手動去更改,因此爲了更好的開發體驗,引入了自動匹配cdn插件,webpack-cdn-plugin
。接下來開始安裝
cnpm install webpack-cdn-plugin --save
實例化插件
const cdnPlugin = require('webpack-cdn-plugin')
接下來開始在configureWebpack
中引用
new cdnPlugin({ modules: [ { name: 'vue', var: 'Vue', path: 'dist/vue.min.js' }, { name: 'axios', var: 'axios', path: 'dist/axios.min.js' }, { name: 'vuex', var: 'Vuex', path: 'dist/vuex.min.js' }, { name: 'element-ui', var: 'ELEMENT', path: 'lib/index.js', style: 'lib/theme-chalk/index.css' }, { name: 'echarts', var: 'echarts', path: 'dist/echarts.min.js' }, { name: 'vue2-editor', var: 'VueEditor', path: 'dist/vue2-editor.js' }, { name: 'vue-router', var: 'VueRouter', path: 'dist/vue-router.min.js' }, ], publicPath: '/node_modules' })
更多瞭解請參考官方文檔。
整體來講引入第三方cdn
確實能帶來不錯的效果,可是有可能不穩定,所以建議你們在實際開發中本身去申請一個專屬的cdn
域名,將網站所要用到庫直接上傳上去。
本期的打包優化就到這裏啦!感受有不少廢話。哈哈~~,最後感謝你們閱讀,若是有問題以及錯誤請及時指正。