前段時間一直在基于webpack進行前端資源包的瘦身梦皮。在項目中基于路由進行代碼分離扣讼,http://www.cnblogs.com/legu/p/7251562.html。對于公司內(nèi)部的組件庫,所有內(nèi)容一次性加載源文件很大嘉竟。比如登錄主要就用了button和input,不需要打包table, tree這種復(fù)雜組件的睦柴。
在使用ant-design的時候诽凌,發(fā)現(xiàn)ant實現(xiàn)了按需加載,https://ant.design/docs/react/introduce-cn坦敌。所以想著自己的組件也支持相關(guān)的功能
那先看看ant-design怎么實現(xiàn)的侣诵。ant-design主要是借助了自己寫的babel插件babel-plugin-import,https://github.com/ant-design/babel-plugin-import狱窘。
原理很簡單杜顺,見下圖
在babel轉(zhuǎn)碼的時候,把整個庫‘a(chǎn)ntd’的引用蘸炸,變?yōu)?antd/lib/button'具體模塊的引用躬络。這樣webpack收集依賴module就不是整個antd,而是里面的button.
那我們的組件也能通過這個插件處理嗎搭儒?
在處理中穷当,項目的組件根據(jù)功能進行的路徑拆分,有的在src/form下面淹禾,有的在src/layout下面馁菜,有的比較復(fù)雜的單獨進行文件夾保存,比如src/table,src/tree;
不是千篇一律的在src下面稀拐,那么我們需要組件查找的對應(yīng)關(guān)系去處理火邓,這就只能看看組件babel-plugin-import的源代碼是怎么進行轉(zhuǎn)換的,看看能不能支持
https://github.com/ant-design/babel-plugin-import/blob/master/src/Plugin.js
上面的代碼比較關(guān)鍵,我們發(fā)現(xiàn)如果定義了customName方法铲咨,就會通過customName進行路徑轉(zhuǎn)換躲胳。
在.babelrc文件中加入相關(guān)配置如下。
![image](http://upload-images.jianshu.io/upload_images/13664743-7a78597c6b88759e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
一切看著就這么結(jié)束了纤勒,但是怎么報錯了~~~原來.babelrc是json文件坯苹,是不支持function的,這就只能求助萬能的Google了~~
不是不想百度摇天,主要是百度啥都沒有~~Google了半天粹湃,原來還不支持,babel7才會支持,現(xiàn)在只能通過下面方式進行處理
https://github.com/babel/babel/issues/4630
.babelrc文件寫成這樣
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">{
"presets": ["./.babelrc.js"]
}</pre>
原來.babelrc的配置挪到.babelrc.js中泉坐,自己處理下map的對應(yīng)關(guān)系
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">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]}`;
}
}]
]
}</pre>
這邊就簡單介紹下怎么實現(xiàn)按需打包吧为鳄。其實底層功能是通過babel插件實現(xiàn)的,技術(shù)難點是在怎么實現(xiàn)這個插件腕让,這方面沒涉及到過孤钦,也沒辦法給大家介紹下。大家可以自己看看文檔纯丸,主要還是語法樹層面的東西偏形。
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md