Files

77 lines
3.0 KiB
JavaScript
Raw Permalink Normal View History

2025-11-14 11:39:33 +08:00
const fs = require('fs-extra');
const { generateAsset } = require('./utils');
const t = require('@babel/types');
const babelGenerator = require('@babel/generator');
const babelParser = require('@babel/parser');
const { default: babelTraverse } = require('@babel/traverse');
const getWxMpRuntime = require('../runtime/index');
// TODO 这个工作应该放在loader中做后续优化
class AddWxMpRuntimePlugin {
apply (compiler) {
compiler.hooks.emit.tapPromise('AddWxMpRuntimePlugin', compilation => {
return new Promise((resolve, reject) => {
try {
// 收集独立分包路径下面的所有js文件
// js文件都存储在 compilation.assets中 因为需要注入 require(`${pkgRoot/common/index.js}`)
const thisCompilationAssets = compilation.assets;
const independentPkgsInfo = Object.values(process.UNI_SUBPACKAGES).filter(info => info.independent) || [];
const independentPkgRoots = independentPkgsInfo.map(info => `${info.root}`);
if (!independentPkgRoots.length) {
resolve();
}
const mpRuntimePath = getWxMpRuntime();
const wxMpRuntimeContent = fs.readFileSync(mpRuntimePath, 'utf8');
const ast = babelParser.parse(wxMpRuntimeContent, {
sourceType: 'module',
plugins: ['classProperties'],
});
babelTraverse(ast, {
VariableDeclaration (path) {
const v = path.node.declarations[0];
const name = v.id.name;
const value = v.init;
if (name === 'independentRoots' && t.isArrayExpression(value)) {
value.elements = independentPkgRoots.map(pkgRoot => t.StringLiteral(pkgRoot));
}
},
});
const { code } = babelGenerator.default(ast);
const runtimeAssetsInfo = generateAsset(code);
const mpRuntimeRelativePath = 'common/wxMpRuntime.js';
// 处理app.js
const appJsName = 'app.js';
thisCompilationAssets[mpRuntimeRelativePath] = runtimeAssetsInfo;
const assetInfo = thisCompilationAssets[appJsName];
if (!assetInfo) {
return resolve();
}
const content = assetInfo.source();
thisCompilationAssets[appJsName] = generateAsset(`require('./common/wxMpRuntime.js');${content}`);
// 处理独立分包
independentPkgRoots.forEach(pkgRoot => {
thisCompilationAssets[`${pkgRoot}/${mpRuntimeRelativePath}`] = runtimeAssetsInfo;
const entryJsName = `${pkgRoot}/common/index.js`;
const assetInfo = thisCompilationAssets[entryJsName];
let content = assetInfo.source();
content = generateAsset(`require('./wxMpRuntime.js');${content}`);
thisCompilationAssets[entryJsName] = content;
});
resolve();
} catch (e) {
console.error('AddWxMpRuntimePlugin', e);
reject(e);
}
});
});
}
}
module.exports = AddWxMpRuntimePlugin;