編寫(xiě)一個(gè)模塊按需加載的babel插件
當(dāng)我們導(dǎo)入lodash中指定的工具函數(shù)時(shí) 會(huì)將整個(gè)lodash打包進(jìn)來(lái)
import {flattenDeep, chunk} from 'lodash'
換成按需引入的寫(xiě)法 但是這樣寫(xiě)有些麻煩 我們想由上面寫(xiě)法 自動(dòng)分解為下面寫(xiě)法 所以我們就編寫(xiě)一個(gè)babel插件
import flattenDeep from 'lodash/flattenDeep'
import chunk from 'lodash/chunk'
Install package
npm i babel-core -D
npm i babel-types -D
插件編寫(xiě)
在當(dāng)前工程的node_modules下創(chuàng)建一個(gè)babel-plugin-extract目錄 里面創(chuàng)建index.js
const babel = require('babel-core');
const types = require('babel-types');
// 將import {flattenDeep, chunk} from 'lodash' 轉(zhuǎn)化為下面這種寫(xiě)法:
// import flattenDeep from 'lodash/flattenDepp'
// import chunk from 'lodash/chunk'
// Babel將源碼轉(zhuǎn)換AST之后,通過(guò)遍歷AST樹(shù)(其實(shí)就是一個(gè)js對(duì)象),對(duì)樹(shù)做一些修改,然后再將AST轉(zhuǎn)成code,即成源碼。
let visitor = {
// import 語(yǔ)句解析時(shí)觸發(fā)該函數(shù)
ImportDeclaration(path, ref = {opts: {}}) { //path 語(yǔ)句抽象語(yǔ)法樹(shù) opts 插件參數(shù)
let node = path.node;
let {specifiers} = node; // 導(dǎo)入的包的說(shuō)明符 是個(gè)數(shù)組集合
// 確認(rèn)導(dǎo)入庫(kù) 是否是 .babelrc library屬性指定庫(kù) 以及 如果不是默認(rèn)導(dǎo)入 才進(jìn)行按需導(dǎo)入加載
if (ref.opts.library === node.source.value && !types.isImportDefaultSpecifier(specifiers[0])) {
let newImports = specifiers.map(specifier => ( // 遍歷 出導(dǎo)入的每個(gè)包的說(shuō)明描述符
types.importDeclaration([types.importDefaultSpecifier(specifier.local)],
// 生成import語(yǔ)句如 import chunk from 'lodash/chunk'
types.stringLiteral(`${node.source.value}/${specifier.local.name}`))
));
// 將原有語(yǔ)句寫(xiě)法替換掉 新寫(xiě)法
path.replaceWithMultiple(newImports);
}
}
}
module.exports = function(babel) { // 將插件導(dǎo)出
return {visitor} // 屬性名固定為visitor
};
配置.babelrc
{
"presets": [
"env",
"stage-0"
],
"plugins": [
[
"extract", // 配置插件
{
"library": "lodash" // 指定處理的庫(kù)
}
]
]
}
build
npm run build // 此時(shí)編譯后的bundle.js變小了
源碼地址
先npm install 然后將源碼目錄中babel-plugin-extract目錄 挪到 node_modules下,npm run build
babel-plugin-extract
參考
剖析Babel
Babel 插件開(kāi)發(fā)指南
Babel 從零入門(mén)
Babel plugin
AST 抽象語(yǔ)法樹(shù)在線(xiàn)轉(zhuǎn)換
babel-types