公司項目使用webpack2.x,搭建得比較早,沒有用vue-cli(沒啥影響),這是大背景。
"dependencies": { "babel-core": "^6.26.0", "es6-promise": "^4.2.4", "eslint-config-vue": "^2.0.2", "vue": "^2.5.16", "vue-router": "^2.8.1", "webpack-cli": "^3.1.0", "webpack-dev-middleware": "^3.1.3", "webpack-hot-middleware": "^2.22.2" }, "devDependencies": { "babel-eslint": "^7.2.3", "babel-loader": "^7.1.4", "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.22.0", "babel-preset-es2016": "^6.24.1", "babel-preset-stage-3": "^6.22.0", "copy-webpack-plugin": "^4.5.2", "css-loader": "^0.28.11", "ejs-loader": "^0.3.1", "eslint": "^3.18.0", "eslint-loader": "^2.0.0", "eslint-plugin-html": "^4.0.5", "eslint-plugin-vue": "^2.1.0", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^1.1.11", "html-loader": "^1.0.0-alpha.0", "html-webpack-plugin": "^4.0.0-alpha", "less": "^3.0.4", "less-loader": "^4.1.0", "lodash": "^4.17.4", "node-sass": "^4.9.0", "sass-loader": "^6.0.7", "style-loader": "^0.21.0", "stylus": "^0.54.5", "stylus-loader": "^3.0.2", "url-loader": "^1.0.1", "vue-loader": "^15.2.6", "vue-template-compiler": "^2.5.16", "webpack": "^4.16.2", "webpack-dev-server": "^3.1.1" },
這些只是依賴包的其中一部分,每一個點拿出來均可以是一個深刻研究的問題,所以這裏主要闡述一下各類包的主要邏輯與聯繫(其實就是各類坑)。css
先看vue-template-compiler的官方說明:html
This package can be used to pre-compile Vue 2.0 templates into render functions to avoid runtime-compilation overhead and CSP restrictions.
You will only need it if you are writing build tools with very specific needs. In most cases you should be using vue-loader or vueify instead, both of which use this package internally.
通常狀況下,vue-loader與vueify自身會在內部使用此包,只有在比較特殊的狀況下才須要用到。單文件組件(.vue爲擴展名的文件)就是這種狀況的其中一種。前端
*在使用vue-template-compiler的時候,版本號要和vue版本號一致。vue
在這裏把vue-router拿出來講,是由於在這裏踩了一個坑。在此次預研任務裏,主要目標就是理解webpack打包構建的原理和過程。在網上看了諸多筆記和教程,沒有一篇提到過與vue-router發生衝突或者報錯的。可是項目在升級webpack4後頁面數據<router-view></router-view>的部分渲染不出來,報錯以下:
在網上搜索了不少,以及去github看了issue,沒有定向到問題所在。總結出大概方向應該是解析器版本沒對上,而後vue-loader什麼的,一個個版本都試過了也沒有用。
最後把vue-router從2.5.x升級到最新2.8.1,立馬解決。node
extract-text-webpack-plugin主要是爲了抽離css樣式,防止將樣式打包在js中引發頁面樣式加載錯亂的現象。
webpack升4以後,extract-text-webpack-plugin的做者一度沒有時間更新插件,這時比較多人推薦的是mini-css-extract-plugin,二者做用接近。
如今,extract-text-webpack-plugin的4.0beta版本已經出來了,與webpack4兼容性良好。由於項目用的是這個,因此繼續沿用。webpack
1.更新工具/依賴的時候,第一步必定是儘量把全部核心的依賴所有都升到最新,通常能夠解決問題(其實已經作到)。
2.出現報錯,首先考慮更新有直接關係的依賴,而不是回想本身以前的更新是否不對。(我就是一直在想是否vue-loader/html-webpack-plugin...等版本不吻合,卡了好久,其實就是vue-router沒更新,固然這主要是本身的問題,被網上資料引導了,沒看到任何相關問題,就一直沒往這方面考慮)。
3.若是須要了解一個依賴包,第一選擇是上github,篩選對本身有用的問題;其次再去搜索網上的資源。不建議在沒有讀懂原理的時候就直接套用網上的配置,即便一時生效,日後可能也是個大坑。git
直接採用了官方文檔的example 1,以下:es6
splitChunks: { cacheGroups: { commons: { name: 'commons', chunks: 'initial', minChunks: 2 } } }
而後打包(run build),運行成功,耗時從240s縮減爲110s,主要的vendor.js體積也從540k減少到了440k左右。github
run dev,能夠正常運行,可是過不了多久,就會報內存溢出:web
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
JavaScript堆內存不足,這裏說的 JavaScript 其實就是 Node,Node 是基於V8引擎的,在通常的後端開發語言中,在基本的內存使用上沒有什麼限制,可是實際上,在 Node 中經過 JavaScript 使用內存時只能使用部份內存(64位系統下約爲1.4 GB,32位系統下約爲0.7 GB)因此當前端項目龐大的話,webpack 編譯時就會佔用不少的系統資源,若是超出了V8對 Node 默認的內存限制大小就會出現這個錯誤,那怎麼解決呢?V8依然提供了選項讓咱們使用更多的內存。Node 在啓動時能夠傳遞 --max-old-space-size 或 --max-new-space-size 來調整內存大小的使用限制。
若是遇到 Node 沒法分配足夠內存給 JavaScript 的狀況,能夠用這個辦法來放寬V8默認的內存限制,避免在執行過程當中稍微多用了一些內存就輕易崩潰,既然知道了解決辦法那就好辦了,在 package.json 裏,咱們直接把上面v8提供的選項參數直接寫入scripts 字段的 node 命令後就行了,示例以下:
"scripts": { "dev": "node --max_old_space_size=4096 build/dev-server.js", "build": "node --max_old_space_size=4096 build/build.js" }
直接在 node 後面寫上 --max_old_space_size=4096 就行了,我這裏設置的內存大小是4G,這個具體的大小能夠根據本身的項目狀況來設置就行了。而後再從新運行 npm run dev/build 就能夠正常運行和打包了。
最後:打開F12,會發現一些頁面子組件尚未被渲染的時候,js方法會被預先加載出來。這裏初步推測與splitChunk的配置有關,從此有機會繼續研究一下,會在這裏續寫。