前段時間一直在基於webpack進行前端資源包的瘦身。在項目中基於路由進行代碼分離,http://www.cnblogs.com/legu/p/7251562.html。對於公司內部的組件庫,全部內容一次性加載源文件很大。好比登陸主要就用了button和input,不須要打包table, tree這種複雜組件的。html
在使用ant-design的時候,發現ant實現了按需加載,https://ant.design/docs/react/introduce-cn。因此想着本身的組件也支持相關的功能。前端
那先看看ant-design怎麼實現的。ant-design主要是藉助了本身寫的babel插件babel-plugin-import,https://github.com/ant-design/babel-plugin-import。react
原理很簡單,見下圖webpack
在babel轉碼的時候,把整個庫‘antd’的引用,變爲'antd/lib/button'具體模塊的引用。這樣webpack收集依賴module就不是整個antd,而是裏面的button.git
那咱們的組件也能經過這個插件處理嗎?github
在處理中,項目的組件根據功能進行的路徑拆分,有的在src/form下面,有的在src/layout下面,有的比較複雜的單獨進行文件夾保存,好比src/table,src/tree;web
不是千篇一概的在src下面,那麼咱們須要組件查找的對應關係去處理,這就只能看看組件babel-plugin-import的源代碼是怎麼進行轉換的,看看能不能支持json
https://github.com/ant-design/babel-plugin-import/blob/master/src/Plugin.jsbabel
上面的代碼比較關鍵,咱們發現若是定義了customName方法,就會經過customName進行路徑轉換。antd
在.babelrc文件中加入相關配置以下。
一切看着就這麼結束了,可是怎麼報錯了~~~原來.babelrc是json文件,是不支持function的,這就只能求助萬能的Google了~~
不是不想百度,主要是百度啥都沒有~~Google了半天,原來還不支持,babel7纔會支持,如今只能經過下面方式進行處理
https://github.com/babel/babel/issues/4630
.babelrc文件寫成這樣
{ "presets": ["./.babelrc.js"] }
原來.babelrc的配置挪到.babelrc.js中,本身處理下map的對應關係
module.exports = { "presets": ["react", "es2015", "stage-0"], "plugins": [ "transform-runtime", "lodash", "transform-decorators-legacy", "jsx-control-statements", ["transform-react-remove-prop-types", { "removeImport": true, "mode": "remove" }], ["import", { "libraryName": "my-react", camel2UnderlineComponentName: false, camel2DashComponentName: false, customName: function (name) { if (!map[name]) { console.log(name); } return `my-react/src${map[name]}`; } }] ] }
這邊就簡單介紹下怎麼實現按需打包吧。其實底層功能是經過babel插件實現的,技術難點是在怎麼實現這個插件,這方面沒涉及到過,也沒辦法給你們介紹下。你們能夠本身看看文檔,主要仍是語法樹層面的東西。
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md