Skip to content

Commit

Permalink
feat: Allow requiring .ts scripts by their .js extension
Browse files Browse the repository at this point in the history
  • Loading branch information
Septh committed Jul 20, 2024
1 parent 0e21030 commit 68b9bf9
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
2 changes: 2 additions & 0 deletions source/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare global {
type ModuleType = 'commonjs' | 'module'

interface Module {
_resolveFilename(request: string, ...otherArgs: any[]): string
_compile(code: string, filename: string): string
}
}
Expand All @@ -21,6 +22,7 @@ declare global {
}

declare module 'module' {
export function _resolveFilename(request: string, ...otherArgs: any[]): string
export const _extensions: NodeJS.RequireExtensions
}

Expand Down
13 changes: 12 additions & 1 deletion source/cjs-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Module, { createRequire } from 'node:module'
import { readFileSync } from 'node:fs'

const require = createRequire(import.meta.url)
const jsExtRx = /\.([cm])?js$/

function transpile(m: Module, format: NodeJS.ModuleType, filePath: string) {
// Notes:
Expand All @@ -12,7 +13,7 @@ function transpile(m: Module, format: NodeJS.ModuleType, filePath: string) {
// This infers a very small performance penalty when transpile() is called
// for the fist time, but we'll live with it.
const { transform } = require('./transform.cjs') as typeof import('./transform.cjs')
const source = readFileSync(filePath).toString()
const source = readFileSync(filePath.replace(jsExtRx, '.$1ts')).toString()
const code = transform(source, format, path.basename(filePath))
return m._compile(code, filePath)
}
Expand Down Expand Up @@ -53,6 +54,16 @@ function nearestPackageType(file: string, defaultType: NodeJS.ModuleType): NodeJ
}

export function install_cjs_hooks(defaultType: NodeJS.ModuleType) {
const { _resolveFilename } = Module
Module._resolveFilename = function(request, ...otherArgs) {
try {
return _resolveFilename.call(undefined, request, ...otherArgs)
}
catch {
return _resolveFilename.call(undefined, request.replace(jsExtRx, '.$1ts'), ...otherArgs)
}
}

Module._extensions['.ts'] = (m, filename) => transpile(m, nearestPackageType(filename, defaultType), filename)
Module._extensions['.cts'] = (m, filename) => transpile(m, 'commonjs', filename)
Module._extensions['.mts'] = (m, filename) => transpile(m, 'module', filename)
Expand Down

0 comments on commit 68b9bf9

Please sign in to comment.