technology-blog
technology-blog copied to clipboard
第 9 题: 简单实现项目代码按需加载,例如import { Button } from 'antd',打包的时候只打包button
原理很简单,就是将
import { Select, Pagination, Button } from 'xxx-ui';
通过babel转化成
import Button from `xxx-ui/src/components/ui-base/Button/Button`;
import Pagination from `xxx-ui/src/components/ui-base/Pagination/Pagination`;
import Select from `xxx-ui/src/components/ui-base/Select/Select`;
自定义拓展一个babel插件,代码如下:
visitor: {
ImportDeclaration (path, { opts }) {
const specifiers = path.node.specifiers;
const source = path.node.source;
// 判断传入的配置参数是否是数组形式
if (Array.isArray(opts)) {
opts.forEach(opt => {
assert(opt.libraryName, 'libraryName should be provided');
});
if (!opts.find(opt => opt.libraryName === source.value)) return;
} else {
assert(opts.libraryName, 'libraryName should be provided');
if (opts.libraryName !== source.value) return;
}
const opt = Array.isArray(opts) ? opts.find(opt => opt.libraryName === source.value) : opts;
opt.camel2UnderlineComponentName = typeof opt.camel2UnderlineComponentName === 'undefined'
? false
: opt.camel2UnderlineComponentName;
opt.camel2DashComponentName = typeof opt.camel2DashComponentName === 'undefined'
? false
: opt.camel2DashComponentName;
if (!types.isImportDefaultSpecifier(specifiers[0]) && !types.isImportNamespaceSpecifier(specifiers[0])) {
// 遍历specifiers生成转换后的ImportDeclaration节点数组
const declarations = specifiers.map((specifier) => {
// 转换组件名称
const transformedSourceName = opt.camel2UnderlineComponentName
? camel2Underline(specifier.imported.name)
: opt.camel2DashComponentName
? camel2Dash(specifier.imported.name)
: specifier.imported.name;
// 利用自定义的customSourceFunc生成绝对路径,然后创建新的ImportDeclaration节点
return types.ImportDeclaration([types.ImportDefaultSpecifier(specifier.local)],
types.StringLiteral(opt.customSourceFunc(transformedSourceName)));
});
// 将当前节点替换成新建的ImportDeclaration节点组
path.replaceWithMultiple(declarations);
}
}
}
請問何時會需要如此功能呢?(搔頭
請問何時會需要如此功能呢?(搔頭
看来你还不知道按需使用antd,或者其他第三方的库,这是减少包体积的常见问题呀
請問何時會需要如此功能呢?(搔頭
看来你还不知道按需使用antd,或者其他第三方的库,这是减少包体积的常见问题呀
喔 現在看懂了,原本以為是要延伸或是縮小第三方庫單一組件代碼。 應該是當時眼花了哈哈
請問何時會需要如此功能呢?(搔頭
看来你还不知道按需使用antd,或者其他第三方的库,这是减少包体积的常见问题呀
喔 現在看懂了,原本以為是要延伸或是縮小第三方庫組件代碼。 應該是當時眼花了哈哈
嗯 现在webpack的tree shaking 和antd自带的一个plugin也有按需加载 这题就考一下按需加载的实现原理 当然 我的答案是通过编写babel插件去实现按需加载 你要是有别的方法 也可以共享出来
webpack4 + babel7 已经可以实现tree shaking了
太苦了吧