@lark-project/cli
Version:
飞书项目插件开发工具
103 lines (102 loc) • 4.26 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const webpack_1 = require("webpack");
const model_1 = require("../model");
const types_1 = require("../types");
const constants_1 = require("../config/constants");
const { RawSource } = require('webpack').sources;
class HotUpdatePlugin {
constructor() {
var _a, _b;
const config = model_1.ConfigFactory.getConfig(types_1.EConfigType.Plugin);
const plugin_id = (_a = config.get('pluginID', false)) !== null && _a !== void 0 ? _a : '';
const plugin_version = ((_b = config.get('version', false)) !== null && _b !== void 0 ? _b : '').replace(/\./g, '_');
this.options = {
regexp: new RegExp(`window\\[("${constants_1.HOT_UPDATE_FUNC_NAME}"|'${constants_1.HOT_UPDATE_FUNC_NAME}')\\]\\s*=\\s*function\\s*\\(`),
newContent: `
var pluginKey = '${plugin_id}_v_${plugin_version}';
var iframeWindow = window[pluginKey];
try {
window.parent["${constants_1.HOT_UPDATE_FUNC_NAME}"] = function(chunkId, moreModules, runtime) {
for(var moduleId in moreModules) {
if(__webpack_require__.o(moreModules, moduleId)) {
currentUpdate[moduleId] = (() => {with(
{
...((iframeWindow||{ Comm: undefined})),
...((iframeWindow||{}).hostProxy||{}),
...((iframeWindow||{}).hostDep||{}),
__require_external__:(external)=>{return ((pluginKey||{}).hostDep||{})[external];},
Promise:__createFakePromise()
}){
try {
return eval('(' + moreModules[moduleId].toString() + ')')
} catch(e) {
console.error('[plugin-hot-update] eval new chunk error: ', e);
}
}})();
if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);
}
}
if(runtime) currentUpdateRuntime.push(runtime);
if(waitingUpdateResolves[chunkId]) {
waitingUpdateResolves[chunkId]();
waitingUpdateResolves[chunkId] = undefined;
}
};
} catch(e) {
console.error('[plugin-hot-update] error: ', e);
}
`,
};
}
apply(compiler) {
compiler.hooks.compilation.tap('HotUpdatePlugin', compilation => {
compilation.hooks.processAssets.tap({
name: 'HotUpdatePlugin',
stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
}, assets => {
for (const fileName in assets) {
if (fileName.endsWith('.js')) {
const source = assets[fileName].source();
const modifiedSource = this.replaceFunctionBody(source, this.options);
assets[fileName] = new RawSource(modifiedSource);
}
}
});
});
}
replaceFunctionBody(source, options) {
const { regexp, newContent = '' } = options;
const sourceStr = Buffer.isBuffer(source) ? source.toString() : source;
const index = sourceStr.search(regexp);
if (index === -1) {
return sourceStr;
}
const beginIndex = sourceStr.indexOf('{', index);
if (beginIndex === -1) {
return sourceStr;
}
const endIndex = this.findMatchingBrace(sourceStr, beginIndex);
if (endIndex === -1) {
return sourceStr;
}
const modifiedSource = sourceStr.slice(0, index) + `\n${newContent}\n` + sourceStr.slice(endIndex + 1);
return modifiedSource;
}
findMatchingBrace(source, index) {
let count = 1;
for (let i = index + 1; i < source.length; i++) {
if (source[i] === '{') {
count++;
}
else if (source[i] === '}') {
count--;
if (count === 0) {
return i;
}
}
}
return -1;
}
}
exports.default = HotUpdatePlugin;