UNPKG

@idlebox/esbuild-executer

Version:

A simple script to execute typescript file during development.

94 lines 3.53 kB
import { error } from 'node:console'; import module from 'node:module'; import { MessageChannel } from 'node:worker_threads'; import { debugs, inspectEnabled, isTrue } from './common/cli.js'; const schema = /^file:\/\//; // const tsExt = /\.ts$/; const debugMap = debugs.master.extend('source-map'); export async function execute(tsFile, options) { if (!tsFile.startsWith('file:')) { throw new Error(`execute() must be a file:// URL, got: ${tsFile}`); } const sourceMaps = new Map(); await registerSourceMap(sourceMaps); const { port1, port2 } = new MessageChannel(); port1.on('message', (data) => { if (data.type === 'source-map') { debugMap(`received source map for: ${data.fileUrl}`); sourceMaps.set(data.fileUrl, JSON.parse(Buffer.from(data.sourceMap).toString('utf-8'))); } else if (data.type === 'debug') { debugs[data.kind]('\x1B[2m%s\x1B[0m', data.message); } else if (data.type === 'warning') { error(data.message); } else if (data.type === 'initialize' || data.type === 'error') { // empty } else { debugs.master(`unknown message type: ${JSON.stringify(data)}`); } }); const ready = new Promise((resolve, reject) => { function waitForPort(data) { if (data.type === 'initialize') { port1.off('message', waitForPort); debugs.master('port1 is ready'); resolve(data.entryFileUrl); } else if (data.type === 'error') { const e = new Error(`import worker error: ${data.message}`); e.stack = data.stack; reject(e); } } port1.on('message', waitForPort); }); debugs.master('register worker'); module.register(import.meta.resolve('./hook-worker.js'), { data: { options, tsFile, port: port2 }, transferList: [port2], }); debugs.master('watting for worker to be ready'); const entryFileUrl = await ready; port1.unref(); debugs.master('worker is ready!'); process.argv[1] = entryFileUrl; const exports = await import(entryFileUrl); port1.postMessage({ type: 'imported', quit: !options?.entries?.length }); return exports; } const preventDuplicate = Symbol('duplicate/source-map-support'); async function registerSourceMap(sourceMaps) { if (Object.hasOwn(globalThis, preventDuplicate)) { return; } Object.defineProperty(globalThis, preventDuplicate, { value: true, writable: false, enumerable: false, configurable: false, }); const userDisabled = isTrue('DISABLE_SOURCE_MAP'); const systemDisabled = inspectEnabled || process.execArgv.includes('--enable-source-maps'); if (!userDisabled && !systemDisabled) { debugMap('register source-map'); const { install } = await import('source-map-support'); install({ retrieveSourceMap(source) { const map = sourceMaps.get(source); if (map) { debugMap(`matched source map for: ${source}`); return { url: source.replace(schema, ''), map: map }; } debugMap(`need to resolve source map for: ${source}`); return null; }, }); } else { debugMap('not register source-map'); } } //# sourceMappingURL=index.js.map