Skip to content

Commit

Permalink
refactor: reuse tsconfig util
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber committed May 21, 2024
1 parent eeaefd6 commit b54131c
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 207 deletions.
5 changes: 1 addition & 4 deletions src/cjs/api/module-extensions.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -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);

Expand Down
15 changes: 4 additions & 11 deletions src/cjs/api/module-resolve-filename.ts
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -33,8 +26,8 @@ const resolveTsFilename = (
if (
parent?.filename
&& (
isTsFilePatten.test(parent.filename)
|| tsconfig?.config.compilerOptions?.allowJs
tsExtensionsPattern.test(parent.filename)
|| allowJs
)
&& tsPath
) {
Expand Down
16 changes: 0 additions & 16 deletions src/cjs/api/utils.ts

This file was deleted.

9 changes: 3 additions & 6 deletions src/esm/hook/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand Down
12 changes: 6 additions & 6 deletions src/esm/hook/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
32 changes: 7 additions & 25 deletions src/esm/hook/utils.ts
Original file line number Diff line number Diff line change
@@ -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';
}
Expand Down
24 changes: 12 additions & 12 deletions src/utils/esm-pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
1 change: 0 additions & 1 deletion src/utils/file-url.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/utils/path-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = /\/(?:$|\?)/;
22 changes: 22 additions & 0 deletions src/utils/tsconfig.ts
Original file line number Diff line number Diff line change
@@ -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;
14 changes: 10 additions & 4 deletions tests/fixtures.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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',
}),
Expand Down
23 changes: 12 additions & 11 deletions tests/specs/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
tsxEsmApiCjsPath,
type NodeApis,
} from '../utils/tsx.js';
import { createPackageJson } from '../fixtures.js';

const tsFiles = {
'file.ts': `
Expand All @@ -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',
Expand Down Expand Up @@ -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,
});
Expand All @@ -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';
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)};
Expand All @@ -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)};
Expand Down Expand Up @@ -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)};
Expand Down Expand Up @@ -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)});
Expand Down Expand Up @@ -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);
Expand All @@ -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)};
Expand Down Expand Up @@ -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)};
Expand Down
5 changes: 3 additions & 2 deletions tests/specs/loaders.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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';
Expand Down
Loading

0 comments on commit b54131c

Please sign in to comment.