寫一個模組按需載入的babel外掛 解決專案全量引入第三方資源的問題
阿新 • • 發佈:2018-11-25
babel 簡單的理解他是一個語法轉換器
Babel 的三個主要處理步驟分別是: 解析(parse),轉換(transform),生成(generate)
Babel 專案是作為一個 monorepo 來進行管理的,它由無數 npm 包組成 其中babel-core為其核心庫
babel 解析程式碼的過程大致為
1,對輸入的原始碼字串進行解析並生成初始 抽象語法樹(AST)
2,對 AST 進行遍歷,解析出整個樹的 path,
3,遍歷 AST 樹並應用各個外掛 生成變換後的 AST 樹
4, 用 babel-generator 將 AST 輸出為轉碼後的程式碼字串
瞭解了這些思想後接下來我們可以參照各個 模組的文件 來開發一個我們的babel-plugin
程式碼如下
var babel = require('babel-core'); var types = require('babel-types'); //Babel 的三個主要處理步驟分別是: 解析(parse),轉換(transform),生成(generate)。 const visitor = {//訪問者中 獲取抽象語法樹的 函式會在解析和轉換時分別進入一次 // 對import轉碼 ImportDeclaration(path, state = {opts:{}}){ const specifiers = path.node.specifiers; const source = path.node.source; // 只有libraryName滿足才會轉碼 if (state.opts.libraryName == source.value && (!types.isImportDefaultSpecifier(specifiers[0])) ) { //state.opts是傳進來的引數 var declarations = specifiers.map((specifier) => { //遍歷 所又通過{ isEqual } 這種方式引入宣告 return types.ImportDeclaration( //建立importImportDeclaration節點 [types.importDefaultSpecifier(specifier.local)], types.StringLiteral(`${source.value}/${specifier.local.name}`) ) }) path.replaceWithMultiple(declarations) //轉換ast(抽象語法樹) } } }; module.exports = function (babel) { return { visitor }; }
編寫好程式碼後 在我們的node_modules目錄下 新建一個目錄 babel-plugin-我們配置的plugin名字 安裝好我們所需要的依賴後 需要用 'browser', 'module', 'main'其中一個欄位指定我們的主入口檔案
{
"name": "babel-plugin-empty-import",
"version": "0.0.1",
"description": "",
"main": "./lib/index.js",
"dependencies": {},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-types": "^6.26.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "freemenL",
"license": "ISC",
"_from": " [email protected]",
"_resolved": "http://registry.npm.taobao.org/babel-plugin-empty-import/download/babel-plugin-empty-import-0.0.1.tgz"
}
接下來配置我們的babel的plugin
{
"presets": [
["env", { "modules": false }],
"react",
"stage-0"
],
plugins:[
["empty-import",{
"libraryName": "lodash"
}]
]
}
也可以將其上傳到npm上 方便我們以後使用