问题
在开发中,我们经常会维护一下常用的组件库、工具库,但是随着业务的开展这些组件库往往功能越来越多,体积越来越大,不利于项目的加载。为此我们需要进行组件库的按需引入,没有用到的功能不会打包到项目当中。
解决方案
思路
1.根据js模块引入规则,当有相互依赖的模块最终会打包到项目中
2.所以我们需要将组件库中的各种组件进行解耦并单独导出
3.为此我们在组件库中维护一个packages文件夹,用于存放各个独立的导出的组件
4.这时我们就可以通过 import aaa from "xxx/packages/aaa" 的方式进行按需引入了
5.但是我们在组件使用中习惯于 import { aaa, bbb} from "xxx" 的语法形式
6.为此我们需要对于上述的语法进行解析
7.可以通过webpack的loader机制进行语法的解析
代码实现
const getOptions = require("loader-utils").getOptions;
function handlePackage(source, packageName, packageDirName = "packages") {
const regStr = `import.*{(.*)}.*"${packageName}"`;
const reg = new RegExp(regStr, "g");
let match;
let tempSource = source;
while ((match = reg.exec(source))) {
const importStr = match[0];
const moduleStr = match[1];
reg.lastIndex = match.index + importStr.length;
const resStr = moduleStr
.trim()
.split(",")
.map((moduleName) => {
moduleName = moduleName.trim();
return `import ${moduleName} from "${packageName}/${packageDirName}/${moduleName}"`;
})
.join("\n");
tempSource = tempSource.replace(importStr, resStr);
}
return tempSource;
}
function simpleImportLoader(source) {
const { packageArr } = getOptions(this);
let tempSource = source;
packageArr.forEach(({ packageName, packageDirName }) => {
tempSource = handlePackage(tempSource, packageName, packageDirName);
});
return tempSource;
}
module.exports = simpleImportLoader;