diff --git a/src/cjs/api/module-extensions.ts b/src/cjs/api/module-extensions.ts index fa583c02..ed4d5ef1 100644 --- a/src/cjs/api/module-extensions.ts +++ b/src/cjs/api/module-extensions.ts @@ -1,13 +1,12 @@ import fs from 'node:fs'; import Module from 'node:module'; -import { createFilesMatcher } from 'get-tsconfig'; import type { TransformOptions } from 'esbuild'; import { transformSync } from '../../utils/transform/index.js'; import { transformDynamicImport } from '../../utils/transform/transform-dynamic-import.js'; import { isESM } from '../../utils/esm-pattern.js'; import { shouldApplySourceMap, inlineSourceMap } from '../../source-map.js'; import { parent } from '../../utils/ipc/client.js'; -import { tsconfig } from './utils.js'; +import { fileMatcher } from '../../utils/tsconfig.js'; const typescriptExtensions = [ '.cts', @@ -23,8 +22,6 @@ const transformExtensions = [ '.mjs', ]; -const fileMatcher = tsconfig && createFilesMatcher(tsconfig); - // Clone Module._extensions with null prototype export const extensions = Object.assign(Object.create(null), Module._extensions); diff --git a/src/cjs/api/module-resolve-filename.ts b/src/cjs/api/module-resolve-filename.ts index 70eee470..1490c526 100644 --- a/src/cjs/api/module-resolve-filename.ts +++ b/src/cjs/api/module-resolve-filename.ts @@ -1,20 +1,13 @@ import path from 'node:path'; import Module from 'node:module'; import { fileURLToPath } from 'node:url'; -import { createPathsMatcher } from 'get-tsconfig'; import { resolveTsPath } from '../../utils/resolve-ts-path.js'; import type { NodeError } from '../../types.js'; -import { isRelativePath } from '../../utils/path-utils.js'; -import { fileUrlPrefix } from '../../utils/file-url.js'; -import { - isTsFilePatten, - tsconfig, -} from './utils.js'; +import { isRelativePath, fileUrlPrefix, tsExtensionsPattern } from '../../utils/path-utils.js'; +import { tsconfigPathsMatcher, allowJs } from '../../utils/tsconfig.js'; const nodeModulesPath = `${path.sep}node_modules${path.sep}`; -const tsconfigPathsMatcher = tsconfig && createPathsMatcher(tsconfig); - type ResolveFilename = typeof Module._resolveFilename; const defaultResolver = Module._resolveFilename.bind(Module); @@ -33,8 +26,8 @@ const resolveTsFilename = ( if ( parent?.filename && ( - isTsFilePatten.test(parent.filename) - || tsconfig?.config.compilerOptions?.allowJs + tsExtensionsPattern.test(parent.filename) + || allowJs ) && tsPath ) { diff --git a/src/cjs/api/utils.ts b/src/cjs/api/utils.ts deleted file mode 100644 index a01d8383..00000000 --- a/src/cjs/api/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import path from 'node:path'; -import { - getTsconfig, - parseTsconfig, -} from 'get-tsconfig'; - -export const isTsFilePatten = /\.[cm]?tsx?$/; - -export const tsconfig = ( - process.env.TSX_TSCONFIG_PATH - ? { - path: path.resolve(process.env.TSX_TSCONFIG_PATH), - config: parseTsconfig(process.env.TSX_TSCONFIG_PATH), - } - : getTsconfig() -); diff --git a/src/esm/hook/load.ts b/src/esm/hook/load.ts index cc237692..de8427c4 100644 --- a/src/esm/hook/load.ts +++ b/src/esm/hook/load.ts @@ -7,12 +7,9 @@ import { inlineSourceMap } from '../../source-map.js'; import { isFeatureSupported, importAttributes } from '../../utils/node-features.js'; import { parent } from '../../utils/ipc/client.js'; import type { Message } from '../types.js'; -import { - fileMatcher, - tsExtensionsPattern, - isJsonPattern, - getNamespace, -} from './utils.js'; +import { fileMatcher } from '../../utils/tsconfig.js'; +import { isJsonPattern, tsExtensionsPattern } from '../../utils/path-utils.js'; +import { getNamespace } from './utils.js'; import { data } from './initialize.js'; const contextAttributesProperty = ( diff --git a/src/esm/hook/resolve.ts b/src/esm/hook/resolve.ts index ef8ce40e..3d436bd9 100644 --- a/src/esm/hook/resolve.ts +++ b/src/esm/hook/resolve.ts @@ -5,21 +5,21 @@ import type { } from 'node:module'; import { resolveTsPath } from '../../utils/resolve-ts-path.js'; import type { NodeError } from '../../types.js'; -import { requestAcceptsQuery } from '../../utils/path-utils.js'; -import { fileUrlPrefix } from '../../utils/file-url.js'; +import { tsconfigPathsMatcher, allowJs } from '../../utils/tsconfig.js'; import { - tsconfigPathsMatcher, + requestAcceptsQuery, + fileUrlPrefix, tsExtensionsPattern, + isDirectoryPattern, +} from '../../utils/path-utils.js'; +import { getFormatFromFileUrl, - allowJs, namespaceQuery, getNamespace, type MaybePromise, } from './utils.js'; import { data } from './initialize.js'; -const isDirectoryPattern = /\/(?:$|\?)/; - type NextResolve = ( specifier: string, context?: ResolveHookContext, diff --git a/src/esm/hook/utils.ts b/src/esm/hook/utils.ts index e9a6ecb1..d6470d06 100644 --- a/src/esm/hook/utils.ts +++ b/src/esm/hook/utils.ts @@ -1,33 +1,15 @@ import path from 'node:path'; import type { ModuleFormat } from 'node:module'; -import { - getTsconfig, - parseTsconfig, - createPathsMatcher, - createFilesMatcher, -} from 'get-tsconfig'; +import { tsExtensionsPattern } from '../../utils/path-utils.js'; import { getPackageType } from './package-json.js'; -const tsconfig = ( - process.env.TSX_TSCONFIG_PATH - ? { - path: path.resolve(process.env.TSX_TSCONFIG_PATH), - config: parseTsconfig(process.env.TSX_TSCONFIG_PATH), - } - : getTsconfig() -); - -export const fileMatcher = tsconfig && createFilesMatcher(tsconfig); -export const tsconfigPathsMatcher = tsconfig && createPathsMatcher(tsconfig); -export const allowJs = tsconfig?.config.compilerOptions?.allowJs ?? false; - -export const tsExtensionsPattern = /\.([cm]?ts|[tj]sx)($|\?)/; - -export const isJsonPattern = /\.json(?:$|\?)/; - const getFormatFromExtension = (fileUrl: string): ModuleFormat | undefined => { - const extension = path.extname(fileUrl.split('?')[0]); - + const queryIndex = fileUrl.indexOf('?'); + const extension = path.extname( + queryIndex === -1 + ? fileUrl + : fileUrl.slice(0, queryIndex), + ); if (extension === '.json') { return 'json'; } diff --git a/src/utils/esm-pattern.ts b/src/utils/esm-pattern.ts index 3408f96b..2e2b6689 100644 --- a/src/utils/esm-pattern.ts +++ b/src/utils/esm-pattern.ts @@ -21,17 +21,17 @@ const esmPattern = /\b(?:import|export)\b/; */ export const isESM = (code: string) => { - if (code.includes('import') || code.includes('export')) { - try { - const hasModuleSyntax = parseEsm(code)[3]; - return hasModuleSyntax; - } catch { - /** - * If it fails to parse, there's a syntax error - * Let esbuild handle it for better error messages - */ - return true; - } + if (!code.includes('import') && !code.includes('export')) { + return false; + } + try { + const hasModuleSyntax = parseEsm(code)[3]; + return hasModuleSyntax; + } catch { + /** + * If it fails to parse, there's a syntax error + * Let esbuild handle it for better error messages + */ + return true; } - return false; }; diff --git a/src/utils/file-url.ts b/src/utils/file-url.ts deleted file mode 100644 index e3ea24e1..00000000 --- a/src/utils/file-url.ts +++ /dev/null @@ -1 +0,0 @@ -export const fileUrlPrefix = 'file://'; diff --git a/src/utils/path-utils.ts b/src/utils/path-utils.ts index 3b3426b5..68a5a181 100644 --- a/src/utils/path-utils.ts +++ b/src/utils/path-utils.ts @@ -43,3 +43,11 @@ export const requestAcceptsQuery = (request: string) => { && scheme !== 'node' ); }; + +export const fileUrlPrefix = 'file://'; + +export const tsExtensionsPattern = /\.([cm]?ts|[tj]sx)($|\?)/; + +export const isJsonPattern = /\.json($|\?)/; + +export const isDirectoryPattern = /\/(?:$|\?)/; diff --git a/src/utils/tsconfig.ts b/src/utils/tsconfig.ts new file mode 100644 index 00000000..0d070045 --- /dev/null +++ b/src/utils/tsconfig.ts @@ -0,0 +1,22 @@ +import path from 'node:path'; +import { + getTsconfig, + parseTsconfig, + createFilesMatcher, + createPathsMatcher, +} from 'get-tsconfig'; + +const tsconfig = ( + process.env.TSX_TSCONFIG_PATH + ? { + path: path.resolve(process.env.TSX_TSCONFIG_PATH), + config: parseTsconfig(process.env.TSX_TSCONFIG_PATH), + } + : getTsconfig() +); + +export const fileMatcher = tsconfig && createFilesMatcher(tsconfig); + +export const tsconfigPathsMatcher = tsconfig && createPathsMatcher(tsconfig); + +export const allowJs = tsconfig?.config.compilerOptions?.allowJs ?? false; diff --git a/tests/fixtures.ts b/tests/fixtures.ts index 2c13658c..b31d789b 100644 --- a/tests/fixtures.ts +++ b/tests/fixtures.ts @@ -1,3 +1,9 @@ +import type { PackageJson, TsConfigJson } from 'type-fest'; + +export const createPackageJson = (packageJson: PackageJson) => JSON.stringify(packageJson); + +export const createTsconfig = (tsconfig: TsConfigJson) => JSON.stringify(tsconfig); + const cjsContextCheck = 'typeof module !== \'undefined\''; const tsCheck = '1 as number'; @@ -85,8 +91,8 @@ const sourcemap = { }; export const expectErrors = { - 'expect-errors.js': ` - export const expectErrors = async (...assertions) => { + 'node_modules/expect-errors/index.js': ` + exports.expectErrors = async (...assertions) => { let errors = await Promise.all( assertions.map(async ([fn, expectedError]) => { let thrown; @@ -227,13 +233,13 @@ export const files = { node_modules: { 'pkg-commonjs': { - 'package.json': JSON.stringify({ + 'package.json': createPackageJson({ type: 'commonjs', }), 'index.js': syntaxLowering, }, 'pkg-module': { - 'package.json': JSON.stringify({ + 'package.json': createPackageJson({ type: 'module', main: './index.js', }), diff --git a/tests/specs/api.ts b/tests/specs/api.ts index ff4b0b88..208c8aac 100644 --- a/tests/specs/api.ts +++ b/tests/specs/api.ts @@ -9,6 +9,7 @@ import { tsxEsmApiCjsPath, type NodeApis, } from '../utils/tsx.js'; +import { createPackageJson } from '../fixtures.js'; const tsFiles = { 'file.ts': ` @@ -21,7 +22,7 @@ const tsFiles = { `, 'bar.ts': 'export type A = 1; export { bar } from "pkg"', 'node_modules/pkg': { - 'package.json': JSON.stringify({ + 'package.json': createPackageJson({ name: 'pkg', type: 'module', exports: './index.js', @@ -144,7 +145,7 @@ export default testSuite(({ describe }, node: NodeApis) => { describe('module', ({ describe, test }) => { test('cli', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'index.ts': 'import { message } from \'./file\';\n\nconsole.log(message, new Error().stack);', ...tsFiles, }); @@ -160,7 +161,7 @@ export default testSuite(({ describe }, node: NodeApis) => { if (node.supports.moduleRegister) { test('module.register', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'module-register.mjs': ` import { register } from 'node:module'; @@ -190,7 +191,7 @@ export default testSuite(({ describe }, node: NodeApis) => { describe('register / unregister', ({ test }) => { test('register / unregister', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'register.mjs': ` import { register } from ${JSON.stringify(tsxEsmApiPath)}; try { @@ -235,7 +236,7 @@ export default testSuite(({ describe }, node: NodeApis) => { test('onImport', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'register.mjs': ` import { register } from ${JSON.stringify(tsxEsmApiPath)}; @@ -259,7 +260,7 @@ export default testSuite(({ describe }, node: NodeApis) => { test('namespace & onImport', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'register.mjs': ` import { setTimeout } from 'node:timers/promises'; import { register } from ${JSON.stringify(tsxEsmApiPath)}; @@ -290,7 +291,7 @@ export default testSuite(({ describe }, node: NodeApis) => { describe('tsImport()', ({ test }) => { test('module', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'import.mjs': ` import { tsImport } from ${JSON.stringify(tsxEsmApiPath)}; @@ -321,7 +322,7 @@ export default testSuite(({ describe }, node: NodeApis) => { test('commonjs', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'import.cjs': ` const { tsImport } = require(${JSON.stringify(tsxEsmApiCjsPath)}); @@ -374,7 +375,7 @@ export default testSuite(({ describe }, node: NodeApis) => { test('namespace allows async nested calls', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'import.mjs': ` import { tsImport } from ${JSON.stringify(tsxEsmApiPath)}; tsImport('./file.ts', import.meta.url); @@ -393,7 +394,7 @@ export default testSuite(({ describe }, node: NodeApis) => { test('onImport & doesnt cache files', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'import.mjs': ` import { setTimeout } from 'node:timers/promises'; import { tsImport } from ${JSON.stringify(tsxEsmApiPath)}; @@ -439,7 +440,7 @@ export default testSuite(({ describe }, node: NodeApis) => { } else { test('no module.register error', async () => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'register.mjs': ` import { register } from ${JSON.stringify(tsxEsmApiPath)}; diff --git a/tests/specs/loaders.ts b/tests/specs/loaders.ts index b80d8dec..c98493a3 100644 --- a/tests/specs/loaders.ts +++ b/tests/specs/loaders.ts @@ -1,12 +1,13 @@ import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; import type { NodeApis } from '../utils/tsx.js'; +import { createPackageJson } from '../fixtures.js'; export default testSuite(({ describe }, node: NodeApis) => { describe('Loaders', ({ describe }) => { describe('Hooks', async ({ test }) => { const fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'module' }), + 'package.json': createPackageJson({ type: 'module' }), 'ts.ts': ` import fs from 'node:fs'; @@ -50,7 +51,7 @@ export default testSuite(({ describe }, node: NodeApis) => { describe('CJS patching', async ({ test }) => { const fixture = await createFixture({ - 'package.json': JSON.stringify({ type: 'commonjs' }), + 'package.json': createPackageJson({ type: 'commonjs' }), 'ts.ts': ` import fs from 'node:fs'; diff --git a/tests/specs/smoke.ts b/tests/specs/smoke.ts index 62082266..ed28f29b 100644 --- a/tests/specs/smoke.ts +++ b/tests/specs/smoke.ts @@ -6,7 +6,7 @@ import outdent from 'outdent'; import type { NodeApis } from '../utils/tsx.js'; import { hasCoverageSourcesContent } from '../utils/coverage-sources-content.js'; import { isWindows } from '../utils/is-windows.js'; -import { files } from '../fixtures.js'; +import { files, createPackageJson } from '../fixtures.js'; import { packageTypes } from '../utils/package-types.js'; const wasmPath = path.resolve('tests/fixtures/test.wasm'); @@ -20,10 +20,10 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { describe(packageType, ({ test }) => { test('from .js', async ({ onTestFail }) => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: packageType }), + 'package.json': createPackageJson({ type: packageType }), 'import-from-js.js': outdent` import assert from 'assert'; - import { expectErrors } from './expect-errors'; + import { expectErrors } from 'expect-errors'; const shouldntAffectFile = \` //# sourceMappingURL=\`; @@ -155,11 +155,11 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { test('from .ts', async ({ onTestFail }) => { await using fixture = await createFixture({ - 'package.json': JSON.stringify({ type: packageType }), + 'package.json': createPackageJson({ type: packageType }), 'import-from-ts.ts': ({ fixturePath }) => outdent` import assert from 'assert'; - import { expectErrors } from './expect-errors'; + import { expectErrors } from 'expect-errors'; const shouldntAffectFile = \` //# sourceMappingURL=\`; diff --git a/tests/specs/tsconfig.ts b/tests/specs/tsconfig.ts index b72f3ad5..630b7363 100644 --- a/tests/specs/tsconfig.ts +++ b/tests/specs/tsconfig.ts @@ -1,142 +1,152 @@ import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; import type { NodeApis } from '../utils/tsx.js'; -import { expectErrors, jsxCheck } from '../fixtures.js'; +import { + expectErrors, jsxCheck, createPackageJson, createTsconfig, +} from '../fixtures.js'; import { packageTypes } from '../utils/package-types.js'; export default testSuite(async ({ describe }, { tsx }: NodeApis) => { describe('tsconfig', ({ describe }) => { for (const packageType of packageTypes) { - describe(packageType, async ({ test, onFinish }) => { + describe(packageType, async ({ describe, onFinish }) => { const fixture = await createFixture({ ...expectErrors, - 'package.json': JSON.stringify({ type: packageType }), + 'package.json': createPackageJson({ type: packageType }), + + 'tsconfig.json': createTsconfig({ + compilerOptions: { + jsxFactory: 'Array', + jsxFragmentFactory: 'null', + baseUrl: '.', + paths: { + 'paths-exact-match': ['file'], + 'prefix/*': ['*'], + '*/suffix': ['*'], + }, + }, + }), - 'import-typescript-parent.js': ` - import './import-typescript-child.js'; - `, + 'tsconfig-allowJs.json': createTsconfig({ + extends: './tsconfig.json', + compilerOptions: { + allowJs: true, + }, + }), - 'import-typescript-child.ts': ` - console.log('imported'); - `, + 'tsconfig-broken.json': '{ asdf', - tsconfig: { - 'jsx.jsx': ` - // tsconfig not applied to jsx because allowJs is not set - import { expectErrors } from '../expect-errors'; - expectErrors( - [() => ${jsxCheck}, 'React is not defined'], + 'tsconfig-unresolvable.json': createTsconfig({ + extends: 'doesnt-exist', + }), - // These should throw unless allowJs is set - // [() => import ('prefix/file'), "Cannot find package 'prefix'"], - // [() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"], - // [() => import ('file'), "Cannot find package 'file'"], - ); - `, + 'index.tsx': ` + ${jsxCheck}; - 'index.tsx': ` - ${jsxCheck}; + import './jsx'; - import './jsx'; + // Resolves relative to baseUrl + import 'file'; - // Resolves relative to baseUrl - import 'file'; + // Resolves paths - exact match + import 'paths-exact-match'; - // Resolves paths - exact match - import 'paths-exact-match'; + // Resolves paths - prefix match + import 'prefix/file'; - // Resolves paths - prefix match - import 'prefix/file'; + // Resolves paths - suffix match + import 'file/suffix'; - // Resolves paths - suffix match - import 'file/suffix'; + // tsconfig should not apply to dependency + import 'tsconfig-should-not-apply'; + `, - // tsconfig should not apply to dependency - import "tsconfig-should-not-apply"; - `, + 'file.ts': '', - 'file.ts': '', - 'tsconfig-allowJs.json': JSON.stringify({ - extends: './tsconfig.json', - compilerOptions: { - allowJs: true, - }, - }), + 'jsx.jsx': ` + // tsconfig not applied to jsx because allowJs is not set + import { expectErrors } from 'expect-errors'; + expectErrors( + [() => ${jsxCheck}, 'React is not defined'], - 'tsconfig.json': JSON.stringify({ - compilerOptions: { - jsxFactory: 'Array', - jsxFragmentFactory: 'null', - baseUrl: '.', - paths: { - 'paths-exact-match': ['file'], - 'prefix/*': ['*'], - '*/suffix': ['*'], - }, - }, - }), + // These should throw unless allowJs is set + // [() => import ('prefix/file'), "Cannot find package 'prefix'"], + // [() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"], + // [() => import ('file'), "Cannot find package 'file'"], + ); + `, - 'node_modules/tsconfig-should-not-apply': { - 'package.json': JSON.stringify({ - exports: { - import: './index.mjs', - default: './index.cjs', - }, - }), - 'index.mjs': ` - import { expectErrors } from '../../../expect-errors'; - expectErrors( - [() => import ('prefix/file'), "Cannot find package 'prefix'"], - [() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"], - [() => import ('file'), "Cannot find package 'file'"], - ); - `, - 'index.cjs': ` - const { expectErrors } = require('../../../expect-errors'); - expectErrors( - [() => require('prefix/file'), "Cannot find module"], - [() => require('paths-exact-match'), "Cannot find module"], - [() => require('file'), "Cannot find module"], - ); - `, - }, + 'import-typescript-parent.js': ` + import './import-typescript-child.js'; + `, + + 'import-typescript-child.ts': ` + console.log('imported'); + `, + 'node_modules/tsconfig-should-not-apply': { + 'package.json': createPackageJson({ + exports: { + import: './index.mjs', + default: './index.cjs', + }, + }), + 'index.mjs': ` + import { expectErrors } from 'expect-errors'; + expectErrors( + [() => import ('prefix/file'), "Cannot find package 'prefix'"], + [() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"], + [() => import ('file'), "Cannot find package 'file'"], + ); + `, + 'index.cjs': ` + const { expectErrors } = require('expect-errors'); + expectErrors( + [() => require('prefix/file'), "Cannot find module"], + [() => require('paths-exact-match'), "Cannot find module"], + [() => require('file'), "Cannot find module"], + ); + `, }, }); onFinish(async () => await fixture.rm()); - test('tsconfig', async ({ onTestFail }) => { - const pTsconfig = await tsx(['index.tsx'], fixture.getPath('tsconfig')); - onTestFail((error) => { - console.error(error); - console.log(pTsconfig); + describe('detected tsconfig', ({ test }) => { + test('tsconfig', async ({ onTestFail }) => { + const pTsconfig = await tsx(['index.tsx'], fixture.path); + onTestFail((error) => { + console.error(error); + console.log(pTsconfig); + }); + expect(pTsconfig.failed).toBe(false); + expect(pTsconfig.stderr).toBe(''); + expect(pTsconfig.stdout).toBe(''); }); - expect(pTsconfig.failed).toBe(false); - expect(pTsconfig.stderr).toBe(''); - expect(pTsconfig.stdout).toBe(''); }); - test('custom tsconfig', async ({ onTestFail }) => { - const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig-allowJs.json', 'jsx.jsx'], fixture.getPath('tsconfig')); - onTestFail((error) => { - console.error(error); - console.log(pTsconfigAllowJs); + describe('custom tsconfig', ({ test }) => { + test('custom tsconfig', async ({ onTestFail }) => { + const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig-allowJs.json', 'jsx.jsx'], fixture.path); + onTestFail((error) => { + console.error(error); + console.log(pTsconfigAllowJs); + }); + expect(pTsconfigAllowJs.failed).toBe(true); + expect(pTsconfigAllowJs.stderr).toMatch('Error: No error thrown'); + expect(pTsconfigAllowJs.stdout).toBe(''); }); - expect(pTsconfigAllowJs.failed).toBe(true); - expect(pTsconfigAllowJs.stderr).toMatch('Error: No error thrown'); - expect(pTsconfigAllowJs.stdout).toBe(''); - }); - test('allowJs in tsconfig.json', async ({ onTestFail }) => { - const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig/tsconfig-allowJs.json', 'import-typescript-parent.js'], fixture.path); - onTestFail((error) => { - console.error(error); - console.log(pTsconfigAllowJs); + test('allowJs in tsconfig.json', async ({ onTestFail }) => { + const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig-allowJs.json', 'import-typescript-parent.js'], fixture.path); + onTestFail((error) => { + console.error(error); + console.log(pTsconfigAllowJs); + }); + expect(pTsconfigAllowJs.failed).toBe(false); + expect(pTsconfigAllowJs.stderr).toBe(''); + expect(pTsconfigAllowJs.stdout).toBe('imported'); }); - expect(pTsconfigAllowJs.failed).toBe(false); - expect(pTsconfigAllowJs.stderr).toBe(''); - expect(pTsconfigAllowJs.stdout).toBe('imported'); }); }); } diff --git a/tests/specs/watch.ts b/tests/specs/watch.ts index 5b4a2c84..ff68cb8c 100644 --- a/tests/specs/watch.ts +++ b/tests/specs/watch.ts @@ -5,6 +5,7 @@ import { createFixture } from 'fs-fixture'; import stripAnsi from 'strip-ansi'; import type { NodeApis } from '../utils/tsx.js'; import { processInteract } from '../utils/process-interact.js'; +import { createPackageJson } from '../fixtures.js'; export default testSuite(async ({ describe }, { tsx }: NodeApis) => { describe('watch', async ({ test, describe, onFinish }) => { @@ -23,7 +24,7 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { for (const packageType of ['module', 'commonjs'] as const) { test(`watch files for changes in ${packageType} package`, async ({ onTestFinish, onTestFail }) => { const fixtureWatch = await createFixture({ - 'package.json': JSON.stringify({ + 'package.json': createPackageJson({ type: packageType, }), 'index.js': `