UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

103 lines (102 loc) 4.26 kB
"use strict"; 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;