使用antd之类的框架经常需要以下配置用于减少打包后的体积:
1 2 3 4 5
| { "plugins": [ ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] ] }
|
这个插件的功能是利用babel解析后得到抽象语法树,收集导入库的语句,在编译时替换为导入指定文件。
以antd为例,以下代码做的就是根据libraryName
,也就是antd,来判断,如果导入语句符合import {Button} from 'antd'
的形式,即从antd导入了组件,那么就将这条语句加入到待替换列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ImportDeclaration(path) { const { node } = path;
if (!node) return;
const { value } = node.source; const libraryName = this.libraryName; const types = this.types; if (value === libraryName) { node.specifiers.forEach(spec => { if (types.isImportSpecifier(spec)) { this.specified[spec.local.name] = spec.imported.name; } else { this.libraryObjs[spec.local.name] = true; } }); this.pathsToRemove.push(path); } }
|
得到了要替换的语句,就可以根据插件中配置的选项进行替换。例如:
1
| import {Button} from 'antd'
|
根据插件配置解析后得到的文件路径为antd/es/button
,其中es
是插件中的libraryDirectory
选项,指定组件所在的源文件目录。因此,上面的语句就变成了下面的形式:
1
| import Button from 'antd/es/button'
|
这样就不必导入整个库了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| importMethod(methodName, file) { if (!this.selectedMethods[methodName]) { const libraryDirectory = this.libraryDirectory; const style = this.style; const transformedMethodName = this.camel2UnderlineComponentName ? camel2Underline(methodName) : this.camel2DashComponentName ? camel2Dash(methodName) : methodName; const path = winPath( this.customName ? this.customName(transformedMethodName) : join(this.libraryName, libraryDirectory, transformedMethodName, this.fileName) ); this.selectedMethods[methodName] = addDefault(file.path, path, { nameHint: methodName }); if (style === true) { addSideEffect(file.path, `${path}/style`); } else if (style === 'css') { addSideEffect(file.path, `${path}/style/css`); } else if (typeof style === 'function') { const stylePath = style(path, file); if (stylePath) { addSideEffect(file.path, stylePath); } } } return Object.assign({}, this.selectedMethods[methodName]); }
|
总结下来就一句话:按需加载不过是将import {Button} from 'antd'
的形式转换为import Button from 'antd/es/button'
的形式的过程。