最近新啟了一個專案,由於之前沒有從零新建過專案,在專案的配置上花了很長時間。簡單記錄下配置中遇到的最大的坑:webpack + gulp + babel-loader 的問題。
先說一下配置的需求,整個專案工作流主要用 gulp 管理。引入 webpack 只用來打包壓縮 js。
很早以前就聽過 Webpack 2 有 Tree Shaking 的功能,配合 ES6 的 export 和 import 語法,可以只引入使用的模組,減少最終壓縮後的程式碼量。於是各種看文件、google 配置示例,終於把 gulp + webpack 2 配置了起來。試著用 import 引入一段公共程式碼,發現也正常引入打包正常工作了,開心的覺得 Voila,搞定!^_^
==然鵝,還是 too young too simple..==
下午同事把專案配置到本地,搗鼓了一會兒過來問我,為什麼只 import 了公共程式碼(utils.js)裡的一個 module, 但還是把整個檔案都打包了呢?我當時就黑人問號臉:納尼,文件上不是寫的只打包 import 的 module 嗎?文件為什麼騙我。。
又認真讀了一遍文件,發現沒有需要配置的地方啊,Tree shaking 是預設功能。百思不得其解的時候,只能使用 google 大法,把自己使用的工作流工具名 webpack + gulp 全輸進去,再加一個 tree shaking not working... 畫美不看.. 果然,早已經有大神遇到相同問題。
原來是 webpack 使用的 babel-loader 造成的問題。具體原因說白了就是,babel-loader 將 ES6 的 modules 先轉換成了 CommonJS modules, 再交給 webpack 去打包。而 CommonJs modules 是動態的,webpack 不能在打包的時候 shake 掉無用的程式碼。
好吧,雖然還不明白什麼是動態 module 什麼是靜態 module,但是找到問題所在了。 那麼怎麼解決呢?估計是 Babel 也發現了這個問題,已經提供了一個配置項可以關掉 ES6 module 的轉換。給 babel-loader 加一項配置:
options: { presets: [ [ 'es2015', { modules: false } ] ] }
重啟 webpack 再打包壓縮一遍檔案,果然~ 只有被 import 的 module 打包了。沒有 import 的 module 在最終打包壓縮過的程式碼裡是找不到的。
至此,才算大功告成~ 可以開心的繼續寫程式碼去了~
附上解決我問題的文章連結,這位大神遇到了跟我一模一樣的坑,才決定寫一篇文章記錄一下。 看到被坑的不只一個人,我就放心了~
部落格連結 http://varnull.cn/webpack-gulp-babel-loader-config/