/* eslint-disable no-console -- 构建脚本,向终端打印检查结果是它的正当输出 */ // 检查打包产物能被扩展宿主加载:给一个桩 vscode 模块,require 产物,顶层代码一抛错就以非零退出。 // 单元测试跑的是源码,看不见打包带来的问题(比如依赖被打成运行时还要 require 自家文件的版本),只有加载产物才能发现。 // 用法:node check-bundle.mjs [产物路径,默认 dist/index.cjs] import Module, { createRequire } from 'node:module' import path from 'node:path' import process from 'node:process' const bundle = path.resolve(process.argv[2] ?? 'dist/index.cjs') // 桩:取任何属性、调用、new 都得到它自己,够顶层代码(建 EventEmitter、继承 TreeItem 之类)跑完; // 被当成值用时(拿枚举成员当对象的键)转成 0,跟真的枚举值一样是个数。底下垫一个类,调用和 new 才都能被截住 const vscodeStub = new Proxy(class {}, { get: (_, key) => key === Symbol.toPrimitive ? () => 0 : vscodeStub, apply: () => vscodeStub, construct: () => vscodeStub, }) // 扩展宿主也是这样把 vscode 交给扩展的:截住模块加载,请求的是 vscode 就给 API 对象 const load = Module._load Module._load = function (request, ...rest) { return request === 'vscode' ? vscodeStub : load.call(this, request, ...rest) } try { createRequire(import.meta.url)(bundle) console.log(`[check-bundle] ${bundle} 加载正常`) } catch (err) { console.error(`[check-bundle] ${bundle} 加载失败:`) console.error(err) process.exit(1) }