diff --git a/src/plugins/pluginManager.ts b/src/plugins/pluginManager.ts index f03760c..64a0018 100644 --- a/src/plugins/pluginManager.ts +++ b/src/plugins/pluginManager.ts @@ -561,29 +561,68 @@ export class PluginManager { // 让 with(fakeGlobal) 在查找这些未覆盖变量时自动回落到浏览器真实全局作用域 // 确保 window.location.href / document.cookie / navigator.userAgent 等正常工作 - // 用 with(fakeGlobal) 包裹代码,让所有嵌套层都能访问 - // require / module / exports / process / Buffer / zlib / http 等 - // 这是 webpack 打包的 CommonJS 插件在浏览器环境下能正确运行的关键 - const wrapperCode = - '(function(__g){' + - 'with(__g){' + - code + - ';return module.exports;' + - '}' + - '})'; - const fn: any = (new Function('return ' + wrapperCode))(); - - const result = fn(fakeGlobal); - const mod = (result && typeof result === 'object' && (result as any).exports) - ? (result as any).exports - : result; - - if (!mod || (typeof mod === 'object' && Object.keys(mod).length === 0)) { - const direct = (fakeGlobal.__plugin_install__ as any) || (fakeGlobal as any).plugin; - if (direct && typeof direct === 'object' && direct.pluginInfo) return direct as PluginModule; + // ============================================================ + // 关键修复:临时把 Node 风格全局挂到 window 上 + // webpack/ncc 内部的 __nccwpck_require__ 会通过嵌套 eval/Function + // 在**全局作用域**查找 require/process/Buffer 等,with(fakeGlobal) 覆盖不到它们 + // 执行后立即恢复,避免污染页面其他代码 + // ============================================================ + const win: any = typeof window !== 'undefined' ? window : globalThis; + const backup: Record = {}; + const globalsToInject: [string, any][] = [ + ['require', requireFn], + ['process', processObj], + ['Buffer', BufferCtor], + ['module', moduleObj], + ['exports', moduleObj.exports], + ['__dirname', '/'], + ['__filename', '/plugin.js'], + ['global', globalThis], + ['globalThis', globalThis], + ['setImmediate', (function (fn: (...rest: any[]) => void, ...rest: any[]) { return setTimeout(fn, 0, ...rest); }) as any], + ['clearImmediate', (id: any) => clearTimeout(id)], + ]; + for (const [key, value] of globalsToInject) { + backup[key] = (win as any)[key]; + try { (win as any)[key] = value; } catch { /* ignore readonly */ } } - return mod as PluginModule; + try { + // 用 with(fakeGlobal) 包裹插件代码,同时在顶层参数显式绑定 CommonJS 变量 + const wrapperCode = + '(function(require,__dirname,__filename,module,exports,process,Buffer){' + + code + + '\n;return module.exports;' + + '})'; + const fn: any = (new Function('return ' + wrapperCode))(); + const args: any[] = [ + requireFn, '/', '/plugin.js', moduleObj, moduleObj.exports, processObj, BufferCtor + ]; + // 通过 with(fakeGlobal) 调用,让自由变量查找回落到 fakeGlobal + const withWrapper: any = new Function( + '__g__', '__fn__', '__args__', + 'with(__g__){ return __fn__.apply(null,__args__); }' + ); + const result = withWrapper(fakeGlobal, fn, args); + const mod = (result && typeof result === 'object' && (result as any).exports) + ? (result as any).exports + : result; + + if (!mod || (typeof mod === 'object' && Object.keys(mod).length === 0)) { + const direct = (fakeGlobal.__plugin_install__ as any) || (fakeGlobal as any).plugin; + if (direct && typeof direct === 'object' && direct.pluginInfo) return direct as PluginModule; + } + + return mod as PluginModule; + } finally { + // 恢复原始全局,避免污染页面其他代码 + for (const key of Object.keys(backup)) { + try { + if (backup[key] === undefined) delete (win as any)[key]; + else (win as any)[key] = backup[key]; + } catch { /* ignore readonly */ } + } + } } } diff --git a/src/views/LogView.vue b/src/views/LogView.vue index 75d5cbc..887665b 100644 --- a/src/views/LogView.vue +++ b/src/views/LogView.vue @@ -39,8 +39,23 @@ - + + + + + @@ -78,7 +116,7 @@