subpackage-component-placeholder
Version:
微信小程序分包组件占位插件
133 lines (131 loc) • 4.95 kB
JavaScript
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// src/index.ts
var require_src = __commonJS({
"src/index.ts"(exports, module) {
var SubpackageComponentPlaceholderPlugin = class {
constructor(options = {}) {
this.projectRoot = process.env.UNI_INPUT_DIR || process.cwd();
this.subpackages = [];
this.placeholderComponent = options.placeholderComponent || "view";
}
apply(compiler) {
if (process.env.UNI_PLATFORM !== "mp-weixin") {
return;
}
compiler.hooks.emit.tapAsync(
"SubpackageComponentPlaceholder",
(compilation, callback) => {
try {
this.processComponents(compilation);
callback();
} catch (error) {
compilation.errors.push(error);
callback();
}
}
);
}
processComponents(compilation) {
const jsonFiles = Object.keys(compilation.assets).filter(
(file) => file.endsWith(".json")
);
const appJsonFile = jsonFiles.find((file) => this.isAppJson(file));
if (appJsonFile) {
try {
const asset = compilation.assets[appJsonFile];
const content = this.getAssetContent(asset);
if (content.trim()) {
const config = JSON.parse(content);
this.subpackages = config.subPackages || config.subpackages || [];
}
} catch (error) {
compilation.warnings.push(
new Error(`处理app.json时出错: ${error.message}`)
);
}
}
for (const filename of jsonFiles) {
if (this.isAppJson(filename) || filename.includes("node_modules")) {
continue;
}
try {
const asset = compilation.assets[filename];
const content = this.getAssetContent(asset);
if (!content.trim()) {
continue;
}
const config = JSON.parse(content);
if (config.usingComponents) {
const modified = this.processComponentConfig(config, filename);
if (modified) {
this.updateCompilationAsset(compilation, filename, config);
}
}
} catch (error) {
compilation.warnings.push(
new Error(`处理文件 ${filename} 时出错: ${error.message}`)
);
}
}
}
processComponentConfig(config, filename) {
if (!config.usingComponents) {
return false;
}
let modified = false;
const currentSubpackage = this.findTargetSubpackage(`/${filename}`);
Object.entries(config.usingComponents).forEach(([name, componentPath]) => {
if (!this.isValidComponentPath(componentPath)) {
return;
}
const targetSubpackage = this.findTargetSubpackage(componentPath);
if (currentSubpackage && targetSubpackage && currentSubpackage.root === targetSubpackage.root) {
return;
}
if (targetSubpackage) {
this.addComponentPlaceholder(config, name);
modified = true;
}
});
return modified;
}
isValidComponentPath(componentPath) {
return typeof componentPath === "string" && componentPath.startsWith("/") && !componentPath.includes("node_modules");
}
addComponentPlaceholder(config, componentName) {
config.componentPlaceholder = config.componentPlaceholder || {};
config.componentPlaceholder[componentName] = this.placeholderComponent;
}
getAssetContent(asset) {
const content = asset.source();
return Buffer.isBuffer(content) ? content.toString("utf8") : content;
}
updateCompilationAsset(compilation, filename, config) {
const newContent = JSON.stringify(config, null, 2);
compilation.assets[filename] = {
source: () => newContent,
size: () => Buffer.byteLength(newContent, "utf8")
};
}
isAppJson(filename) {
return filename.includes("app.json");
}
findTargetSubpackage(componentPath) {
if (!this.shouldProcessComponent(componentPath))
return null;
const normalizedPath = componentPath.replace(/^\/+/, "");
return this.subpackages.find((pkg) => {
return normalizedPath.startsWith(pkg.root);
}) || null;
}
shouldProcessComponent(componentPath) {
return typeof componentPath === "string" && componentPath.startsWith("/") && !componentPath.includes("node_modules");
}
};
module.exports = SubpackageComponentPlaceholderPlugin;
}
});
export default require_src();