diff --git a/package-lock.json b/package-lock.json index e89cb1e5..22a40145 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "svelte": "3.37.0", "ts-essentials": "^7.0.1", "ts-jest": "^26.5.5", + "tsconfig-paths": "^3.12.0", "tsup": "^5.7.2", "typescript": "^4.2.4", "wait-for-expect": "^3.0.2" @@ -1035,6 +1036,12 @@ "pretty-format": "^26.0.0" } }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "node_modules/@types/node": { "version": "14.17.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", @@ -6734,6 +6741,39 @@ "node": ">=10" } }, + "node_modules/tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/tsup": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/tsup/-/tsup-5.7.2.tgz", @@ -8072,6 +8112,12 @@ "pretty-format": "^26.0.0" } }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/node": { "version": "14.17.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", @@ -12414,6 +12460,35 @@ } } }, + "tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "tsup": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/tsup/-/tsup-5.7.2.tgz", diff --git a/package.json b/package.json index d80dcfdc..ef29dd12 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "svelte": "3.37.0", "ts-essentials": "^7.0.1", "ts-jest": "^26.5.5", + "tsconfig-paths": "^3.12.0", "tsup": "^5.7.2", "typescript": "^4.2.4", "wait-for-expect": "^3.0.2" diff --git a/src/esbuild/index.ts b/src/esbuild/index.ts index eed14ce6..310e527f 100644 --- a/src/esbuild/index.ts +++ b/src/esbuild/index.ts @@ -4,7 +4,7 @@ import { transform as transformToEs5 } from 'buble' import { build as esbuild, BuildResult, formatMessages } from 'esbuild' import { NormalizedOptions, Format } from '..' import { getDeps, loadPkg } from '../load' -import { log } from '../log' +import { Logger } from '../log' import { nodeProtocolPlugin } from './node-protocol' import { externalPlugin } from './external' import { postcssPlugin } from './postcss' @@ -34,7 +34,11 @@ const getOutputExtensionMap = ( export async function runEsbuild( options: NormalizedOptions, - { format, css }: { format: Format; css?: Map } + { + format, + css, + logger, + }: { format: Format; css?: Map; logger: Logger } ) { const pkg = await loadPkg(process.cwd()) const deps = await getDeps(process.cwd()) @@ -55,7 +59,7 @@ export async function runEsbuild( options.minify || options.minifyWhitespace ? 'production' : 'development' } - log(format, 'info', 'Build start') + logger.info(format, 'Build start') const startTime = Date.now() @@ -84,6 +88,7 @@ export async function runEsbuild( target: options.target === 'es5' ? 'es2016' : options.target, footer: options.footer, banner: options.banner, + tsconfig: options.tsconfig, loader: { '.aac': 'file', '.css': 'file', @@ -172,7 +177,7 @@ export async function runEsbuild( metafile: Boolean(options.metafile), }) } catch (error) { - log(format, 'error', 'Build failed') + logger.error(format, 'Build failed') throw error } @@ -200,7 +205,7 @@ export async function runEsbuild( // Manually write files if (result && result.outputFiles) { const timeInMs = Date.now() - startTime - log(format, 'success', `Build success in ${Math.floor(timeInMs)}ms`) + logger.success(format, `Build success in ${Math.floor(timeInMs)}ms`) await Promise.all( result.outputFiles.map(async (file) => { diff --git a/src/index.ts b/src/index.ts index 5de7edee..e3fa5de6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import fs from 'fs' import { Worker } from 'worker_threads' import type { MarkRequired, Buildable } from 'ts-essentials' import { removeFiles, debouncePromise } from './utils' -import { loadTsConfig, loadTsupConfig } from './load' +import { loadTsupConfig, resolveTsConfig } from './load' import glob from 'globby' import { handleError, PrettyError } from './errors' import resolveFrom from 'resolve-from' @@ -12,7 +12,7 @@ import type { ChildProcess } from 'child_process' import execa from 'execa' import kill from 'tree-kill' import { version } from '../package.json' -import { log, setSilent } from './log' +import { createLogger, setSilent } from './log' import { Format, Options } from './options' import { runEsbuild } from './esbuild' @@ -26,10 +26,11 @@ export type NormalizedOptions = MarkRequired< export const defineConfig = ( options: | Options + | Options[] | (( /** The options derived from CLI flags */ overrideOptions: Options - ) => Options) + ) => Options | Options[]) ) => options const killProcess = ({ @@ -44,6 +45,7 @@ const killProcess = ({ }) const normalizeOptions = async ( + logger: ReturnType, optionsFromConfigFile: Options | undefined, optionsOverride: Options ) => { @@ -66,7 +68,7 @@ const normalizeOptions = async ( if (!options.entryPoints || options.entryPoints.length === 0) { throw new PrettyError(`Cannot find ${input}`) } else { - log('CLI', 'info', `Building entry: ${options.entryPoints.join(', ')}`) + logger.info('CLI', `Building entry: ${options.entryPoints.join(', ')}`) } } else { Object.keys(input).forEach((alias) => { @@ -75,7 +77,7 @@ const normalizeOptions = async ( throw new PrettyError(`Cannot find ${alias}: ${filename}`) } }) - log('CLI', 'info', `Building entry: ${JSON.stringify(input)}`) + logger.info('CLI', `Building entry: ${JSON.stringify(input)}`) } options.outDir = options.outDir || 'dist' @@ -85,15 +87,15 @@ const normalizeOptions = async ( options.format = ['cjs'] } - const tsconfig = await loadTsConfig(process.cwd()) - if (tsconfig.path && tsconfig.data) { - log('CLI', 'info', `Using tsconfig: ${tsconfig.path}`) - if (!options.jsxFactory) { - options.jsxFactory = tsconfig.data.compilerOptions?.jsxFactory - } - if (!options.jsxFragment) { - options.jsxFragment = tsconfig.data.compilerOptions?.jsxFragmentFactory - } + const tsconfig = await resolveTsConfig(process.cwd(), options.tsconfig) + if (tsconfig) { + logger.info( + 'CLI', + `Using tsconfig: ${path.relative(process.cwd(), tsconfig)}` + ) + options.tsconfig = tsconfig + } else if (options.tsconfig) { + throw new PrettyError(`Cannot find tsconfig: ${options.tsconfig}`) } if (!options.target) { @@ -110,143 +112,158 @@ export async function build(_options: Options) { const configData = typeof config.data === 'function' ? config.data(_options) : config.data - const options = await normalizeOptions(configData, _options) - - log('CLI', 'info', `tsup v${version}`) - - if (config.path) { - log('CLI', 'info', `Using tsup config: ${config.path}`) - } - - if (options.watch) { - log('CLI', 'info', 'Running in watch mode') - } - - let existingOnSuccess: ChildProcess | undefined - - async function killPreviousProcess() { - if (existingOnSuccess) { - await killProcess({ - pid: existingOnSuccess.pid, - }) - existingOnSuccess = undefined - } - } - - const debouncedBuildAll = debouncePromise( - () => { - return buildAll() - }, - 100, - handleError - ) - - const buildAll = async () => { - const killPromise = killPreviousProcess() - - if (options.clean) { - const extraPatterns = Array.isArray(options.clean) ? options.clean : [] - await removeFiles( - ['**/*', '!**/*.d.ts', ...extraPatterns], - options.outDir - ) - log('CLI', 'info', 'Cleaning output folder') - } - - const css: Map = new Map() - await Promise.all([ - ...options.format.map((format, index) => - runEsbuild(options, { format, css: index === 0 ? css : undefined }) - ), - ]) - await killPromise - if (options.onSuccess) { - const parts = parseArgsStringToArgv(options.onSuccess) - const exec = parts[0] - const args = parts.splice(1) - existingOnSuccess = execa(exec, args, { - stdio: 'inherit', - }) - } - } - - const startWatcher = async () => { - if (!options.watch) return - - const { watch } = await import('chokidar') - - const customIgnores = options.ignoreWatch - ? Array.isArray(options.ignoreWatch) - ? options.ignoreWatch - : [options.ignoreWatch] - : [] - - const ignored = [ - '**/{.git,node_modules}/**', - options.outDir, - ...customIgnores, - ] - - const watchPaths = - typeof options.watch === 'boolean' - ? '.' - : Array.isArray(options.watch) - ? options.watch.filter( - (path): path is string => typeof path === 'string' + await Promise.all( + [...(Array.isArray(configData) ? configData : [configData])].map( + async (item) => { + const logger = createLogger(item?.name) + const options = await normalizeOptions(logger, item, _options) + + logger.info('CLI', `tsup v${version}`) + + if (config.path) { + logger.info('CLI', `Using tsup config: ${config.path}`) + } + + if (options.watch) { + logger.info('CLI', 'Running in watch mode') + } + + let existingOnSuccess: ChildProcess | undefined + + async function killPreviousProcess() { + if (existingOnSuccess) { + await killProcess({ + pid: existingOnSuccess.pid, + }) + existingOnSuccess = undefined + } + } + + const debouncedBuildAll = debouncePromise( + () => { + return buildAll() + }, + 100, + handleError + ) + + const buildAll = async () => { + const killPromise = killPreviousProcess() + + if (options.clean) { + const extraPatterns = Array.isArray(options.clean) + ? options.clean + : [] + await removeFiles( + ['**/*', '!**/*.d.ts', ...extraPatterns], + options.outDir + ) + logger.info('CLI', 'Cleaning output folder') + } + + const css: Map = new Map() + await Promise.all([ + ...options.format.map((format, index) => + runEsbuild(options, { + format, + css: index === 0 ? css : undefined, + logger, + }) + ), + ]) + await killPromise + if (options.onSuccess) { + const parts = parseArgsStringToArgv(options.onSuccess) + const exec = parts[0] + const args = parts.splice(1) + existingOnSuccess = execa(exec, args, { + stdio: 'inherit', + }) + } + } + + const startWatcher = async () => { + if (!options.watch) return + + const { watch } = await import('chokidar') + + const customIgnores = options.ignoreWatch + ? Array.isArray(options.ignoreWatch) + ? options.ignoreWatch + : [options.ignoreWatch] + : [] + + const ignored = [ + '**/{.git,node_modules}/**', + options.outDir, + ...customIgnores, + ] + + const watchPaths = + typeof options.watch === 'boolean' + ? '.' + : Array.isArray(options.watch) + ? options.watch.filter( + (path): path is string => typeof path === 'string' + ) + : options.watch + + logger.info( + 'CLI', + `Watching for changes in ${ + Array.isArray(watchPaths) + ? watchPaths.map((v) => '"' + v + '"').join(' | ') + : '"' + watchPaths + '"' + }` + ) + logger.info( + 'CLI', + `Ignoring changes in ${ignored + .map((v) => '"' + v + '"') + .join(' | ')}` ) - : options.watch - - log( - 'CLI', - 'info', - `Watching for changes in ${ - Array.isArray(watchPaths) - ? watchPaths.map((v) => '"' + v + '"').join(' | ') - : '"' + watchPaths + '"' - }` - ) - log( - 'CLI', - 'info', - `Ignoring changes in ${ignored.map((v) => '"' + v + '"').join(' | ')}` - ) - - const watcher = watch(watchPaths, { - ignoreInitial: true, - ignorePermissionErrors: true, - ignored, - }) - watcher.on('all', async (type, file) => { - log('CLI', 'info', `Change detected: ${type} ${file}`) - debouncedBuildAll() - }) - } - - log('CLI', 'info', `Target: ${options.target}`) - - await buildAll() - - startWatcher() - - if (options.dts) { - const hasTypescript = resolveFrom.silent(process.cwd(), 'typescript') - if (!hasTypescript) { - throw new Error(`You need to install "typescript" in your project`) - } - const worker = new Worker(path.join(__dirname, './rollup.js')) - worker.postMessage({ - options: { - ...options, // functions cannot be cloned - esbuildPlugins: undefined, - }, - }) - worker.on('message', (data) => { - if (data === 'error') { - process.exitCode = 1 - } else if (data === 'success') { - process.exitCode = 0 + const watcher = watch(watchPaths, { + ignoreInitial: true, + ignorePermissionErrors: true, + ignored, + }) + watcher.on('all', async (type, file) => { + logger.info('CLI', `Change detected: ${type} ${file}`) + debouncedBuildAll() + }) + } + + logger.info('CLI', `Target: ${options.target}`) + + await buildAll() + + startWatcher() + + if (options.dts) { + const hasTypescript = resolveFrom.silent(process.cwd(), 'typescript') + if (!hasTypescript) { + throw new Error(`You need to install "typescript" in your project`) + } + + const worker = new Worker(path.join(__dirname, './rollup.js')) + worker.postMessage({ + configName: item?.name, + options: { + ...options, // functions cannot be cloned + esbuildPlugins: undefined, + esbuildOptions: undefined, + }, + }) + worker.on('message', (data) => { + if (data === 'error') { + process.exitCode = 1 + } else if (data === 'success') { + process.exitCode = 0 + } + }) + } } - }) - } + ) + ) } diff --git a/src/load.ts b/src/load.ts index e83e9b0e..4c72a4b9 100644 --- a/src/load.ts +++ b/src/load.ts @@ -4,6 +4,7 @@ import JoyCon from 'joycon' import path from 'path' import { Loader } from 'esbuild' import stripJsonComments from 'strip-json-comments' +import { defineConfig } from './' const joycon = new JoyCon() @@ -31,15 +32,13 @@ const jsonLoader = { joycon.addLoader(jsonLoader) -export function loadTsConfig(cwd: string) { - return joycon.load( - ['tsconfig.build.json', 'tsconfig.json'], - cwd, - path.dirname(cwd) - ) +export function resolveTsConfig(cwd: string, tsconfig = 'tsconfig.json') { + return joycon.resolve([tsconfig], cwd, path.dirname(cwd)) } -export async function loadTsupConfig(cwd: string) { +export async function loadTsupConfig( + cwd: string +): Promise<{ path?: string; data?: ReturnType }> { const configJoycon = new JoyCon() const configPath = await configJoycon.resolve( [ diff --git a/src/log.ts b/src/log.ts index f083cdd5..7fdb8dac 100644 --- a/src/log.ts +++ b/src/log.ts @@ -1,27 +1,56 @@ import colors from 'chalk' -export const makeLabel = (input: string, type: 'info' | 'success' | 'error') => - colors[type === 'info' ? 'bgBlue' : type === 'error' ? 'bgRed' : 'bgGreen']( - colors.black(` ${input.toUpperCase()} `) - ) +export const makeLabel = ( + name: string | undefined, + input: string, + type: 'info' | 'success' | 'error' +) => { + return [ + name && `${colors.dim('[')}${name.toUpperCase()}${colors.dim(']')}`, + colors[type === 'info' ? 'blue' : type === 'error' ? 'red' : 'green']( + input.toUpperCase() + ), + ] + .filter(Boolean) + .join(colors.dim(' ')) +} let silent = false + export function setSilent(isSilent?: boolean) { silent = !!isSilent } -export function log( - label: string, - type: 'info' | 'success' | 'error', - ...data: unknown[] -) { - switch (type) { - case 'error': { - return console.error(makeLabel(label, type), ...data) - } - default: - if (silent) return - - console.log(makeLabel(label, type), ...data) +export type Logger = ReturnType + +export const createLogger = (name?: string) => { + return { + setName(_name: string) { + name = _name + }, + + success(label: string, ...args: any[]) { + return this.log(label, 'success', ...args) + }, + + info(label: string, ...args: any[]) { + return this.log(label, 'info', ...args) + }, + + error(label: string, ...args: any[]) { + return this.log(label, 'error', ...args) + }, + + log(label: string, type: 'info' | 'success' | 'error', ...data: unknown[]) { + switch (type) { + case 'error': { + return console.error(makeLabel(name, label, type), ...data) + } + default: + if (silent) return + + console.log(makeLabel(name, label, type), ...data) + } + }, } } diff --git a/src/options.ts b/src/options.ts index 1e9ef809..9ed803b5 100644 --- a/src/options.ts +++ b/src/options.ts @@ -8,6 +8,8 @@ export type Format = 'cjs' | 'esm' | 'iife' * Not all of them are available from CLI flags */ export type Options = { + /** Optional config name to show in CLI output */ + name?: string entryPoints?: BuildOptions['entryPoints'] /** * Output different formats to differen folder instead of using different extensions @@ -109,4 +111,8 @@ export type Options = { * Disable config file with `false` */ config?: boolean + /** + * Use a custom tsconfig + */ + tsconfig?: string } diff --git a/src/rollup.ts b/src/rollup.ts index 9a2bf521..dbc4f2ed 100644 --- a/src/rollup.ts +++ b/src/rollup.ts @@ -1,14 +1,28 @@ -import path from 'path' import { parentPort } from 'worker_threads' import { InputOptions, OutputOptions, Plugin } from 'rollup' import { NormalizedOptions } from './' +import ts from 'typescript' import hashbangPlugin from 'rollup-plugin-hashbang' import jsonPlugin from '@rollup/plugin-json' import { handleError } from './errors' import { removeFiles } from './utils' import { TsResolveOptions, tsResolvePlugin } from './rollup/ts-resolve' -import { log, setSilent } from './log' -import { getDeps, loadTsConfig } from './load' +import { createLogger, setSilent } from './log' +import { getDeps } from './load' +import path from 'path' + +const logger = createLogger() + +const loadCompilerOptions = (tsconfig?: string) => { + if (!tsconfig) return {} + const configFile = ts.readConfigFile(tsconfig, ts.sys.readFile) + const { options } = ts.parseJsonConfigFileContent( + configFile.config, + ts.sys, + './' + ) + return options +} // Use `require` to esbuild use the cjs build of rollup-plugin-dts // the mjs build of rollup-plugin-dts uses `import.meta.url` which makes Node throws syntax error @@ -66,12 +80,8 @@ const getRollupConfig = async ( options: NormalizedOptions ): Promise => { setSilent(options.silent) - const compilerOptions: { - baseUrl?: string - paths?: Record - } = await loadTsConfig(process.cwd()).then( - (res) => res.data?.compilerOptions || {} - ) + + const compilerOptions = loadCompilerOptions(options.tsconfig) const dtsOptions = typeof options.dts === 'string' @@ -144,13 +154,10 @@ const getRollupConfig = async ( jsonPlugin(), ignoreFiles, dtsPlugin.default({ - compilerOptions: - compilerOptions.baseUrl && compilerOptions.paths - ? { - baseUrl: compilerOptions.baseUrl, - paths: compilerOptions.paths, - } - : undefined, + compilerOptions: { + ...compilerOptions, + baseUrl: path.resolve(compilerOptions.baseUrl || '.'), + }, }), ].filter(Boolean), external: [...deps, ...(options.external || [])], @@ -170,12 +177,12 @@ async function runRollup(options: RollupConfig) { const getDuration = () => { return `${Math.floor(Date.now() - start)}ms` } - log('dts', 'info', 'Build start') + logger.info('dts', 'Build start') const bundle = await rollup(options.inputConfig) await bundle.write(options.outputConfig) - log('dts', 'success', `Build success in ${getDuration()}`) + logger.success('dts', `Build success in ${getDuration()}`) } catch (error) { - log('dts', 'error', 'Build error') + logger.error('dts', 'Build error') parentPort?.postMessage('error') handleError(error) } @@ -193,12 +200,12 @@ async function watchRollup(options: { output: options.outputConfig, }).on('event', async (event) => { if (event.code === 'START') { - log('dts', 'info', 'Build start') + logger.info('dts', 'Build start') } else if (event.code === 'BUNDLE_END') { - log('dts', 'success', `Build success in ${event.duration}ms`) + logger.success('dts', `Build success in ${event.duration}ms`) parentPort?.postMessage('success') } else if (event.code === 'ERROR') { - log('dts', 'error', 'Build failed') + logger.error('dts', 'Build failed') parentPort?.postMessage('error') handleError(event.error) } @@ -216,5 +223,6 @@ const startRollup = async (options: NormalizedOptions) => { } parentPort?.on('message', (data) => { + logger.setName(data.configName) startRollup(data.options) }) diff --git a/src/rollup/ts-resolve.ts b/src/rollup/ts-resolve.ts index 5b7d5a2d..3dd9c4ea 100644 --- a/src/rollup/ts-resolve.ts +++ b/src/rollup/ts-resolve.ts @@ -13,6 +13,8 @@ const resolveModule = ( ): Promise => new Promise((resolve, reject) => { _resolve(id, opts, (err, res) => { + // @ts-expect-error + if (err?.code === 'MODULE_NOT_FOUND') return resolve(null) if (err) return reject(err) resolve(res || null) }) @@ -35,6 +37,9 @@ export const tsResolvePlugin: PluginImpl = ({ async resolveId(source, importer) { debug('resolveId source: %s', source) debug('resolveId importer: %s ', importer) + + if (!importer) return null + // ignore IDs with null character, these belong to other plugins if (/\0/.test(source)) return null @@ -50,11 +55,17 @@ export const tsResolvePlugin: PluginImpl = ({ if (typeof v === 'string') return v === source return v.test(source) }) - if (!shouldResolve) return null + if (!shouldResolve) { + debug('skipped by matching resolveOnly: %s', source) + return null + } } // Skip absolute path - if (path.isAbsolute(source)) return null + if (path.isAbsolute(source)) { + debug(`skipped absolute path: %s`, source) + return null + } const basedir = importer ? await fs.promises.realpath(path.dirname(importer)) @@ -93,9 +104,12 @@ export const tsResolvePlugin: PluginImpl = ({ if (id) { debug('resolved %s to %s', source, id) + return id } - return id + debug('mark %s as external', source) + // Just make it external if can't be resolved, i.e. tsconfig path alias + return false }, } } diff --git a/src/run.ts b/src/run.ts index 528fc146..3930a343 100644 --- a/src/run.ts +++ b/src/run.ts @@ -1,12 +1,10 @@ -import {spawn} from 'child_process' +import { spawn } from 'child_process' -export function runCode(filename: string, { - args -}: {args: string[]}) { +export function runCode(filename: string, { args }: { args: string[] }) { const cmd = spawn('node', [filename, ...args], { - stdio: 'inherit' + stdio: 'inherit', }) - cmd.on('exit', code => { + cmd.on('exit', (code) => { process.exitCode = code || 0 }) -} \ No newline at end of file +} diff --git a/tsup.config.ts b/tsup.config.ts index 18091652..f69b8928 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -2,6 +2,7 @@ import fs from 'fs' import { defineConfig } from './src' export default defineConfig({ + name: 'tsup', esbuildPlugins: [ { name: 'patch-rollup-plugin-dts',