@node-loaders/esbuild
Advanced tools
Comparing version 0.5.1 to 0.6.0
import Module from 'node:module'; | ||
import process from 'node:process'; | ||
import { pathToFileURL } from 'node:url'; | ||
import { specifierToFilePath } from '@node-loaders/core'; | ||
import { isBuiltinModule, isPackageSpecifier, specifierToFilePath } from '@node-loaders/core'; | ||
import { lookForDefaultModuleSync } from '@node-loaders/resolve'; | ||
@@ -22,6 +21,10 @@ import { EsbuildSources } from './esbuild-sources.js'; | ||
catch (error) { | ||
const filePath = specifierToFilePath(request, parent?.filename ?? undefined); | ||
const resolvedFilePath = lookForEsbuildReplacementFileSync(filePath) ?? lookForDefaultModuleSync(filePath, 'ts'); | ||
if (resolvedFilePath) { | ||
return resolvedFilePath; | ||
if (!isBuiltinModule(request) && !isPackageSpecifier(request)) { | ||
const parentFilename = parent?.filename ?? undefined; | ||
const parentUrl = parentFilename ? pathToFileURL(parentFilename).href : undefined; | ||
const possibleFilePath = specifierToFilePath(request, parentUrl); | ||
const resolvedFilePath = lookForEsbuildReplacementFileSync(possibleFilePath) ?? lookForDefaultModuleSync(possibleFilePath, 'ts'); | ||
if (resolvedFilePath) { | ||
return resolvedFilePath; | ||
} | ||
} | ||
@@ -32,6 +35,2 @@ throw error; | ||
register() { | ||
if ('setSourceMapsEnabled' in process && typeof Error.prepareStackTrace !== 'function') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
process.setSourceMapsEnabled(true); | ||
} | ||
for (const ext of this.extensions) { | ||
@@ -38,0 +37,0 @@ Module._extensions[ext] = this.extensionHandler; |
import { type Format } from '@node-loaders/core'; | ||
import { LoaderCache } from '@node-loaders/resolve'; | ||
import { type TransformOptions } from 'esbuild'; | ||
@@ -7,10 +8,17 @@ type EsbuildSource = { | ||
}; | ||
type TsconfigCache = { | ||
config: any; | ||
hash: string; | ||
}; | ||
export declare class EsbuildSources { | ||
private sourcesCache; | ||
private tsconfigCache; | ||
readonly sourcesCache: Record<string, EsbuildSource>; | ||
readonly tsconfigCache: Record<string, TsconfigCache>; | ||
readonly cache: LoaderCache; | ||
private sourceMapSet; | ||
setupSourceMap(): void; | ||
getSource(fileUrl: string, maybeFormat?: string): Promise<EsbuildSource>; | ||
getSourceSync(fileUrl: string, format?: Format): EsbuildSource; | ||
getOptions(options: TransformOptions & Required<Pick<TransformOptions, 'sourcefile'>>): TransformOptions; | ||
findTsConfig(sourceFile: string): any; | ||
getOptions(tsconfig: any, options: TransformOptions & Required<Pick<TransformOptions, 'sourcefile'>>): TransformOptions; | ||
findTsConfig(sourceFile: string): TsconfigCache; | ||
} | ||
export {}; |
import { readFile } from 'node:fs/promises'; | ||
import { readFileSync } from 'node:fs'; | ||
import { dirname, join, relative, resolve } from 'node:path'; | ||
import { dirname, join, relative } from 'node:path'; | ||
import process from 'node:process'; | ||
import { fileURLToPath } from 'node:url'; | ||
import { getTsconfig } from 'get-tsconfig'; | ||
import { detectPackageJsonType } from '@node-loaders/resolve'; | ||
import { detectPackageJsonType, LoaderCache } from '@node-loaders/resolve'; | ||
import { transform, transformSync } from 'esbuild'; | ||
const cacheExtension = 'mjs'; | ||
export class EsbuildSources { | ||
sourcesCache = {}; | ||
tsconfigCache = {}; | ||
cache = new LoaderCache('esbuild'); | ||
sourceMapSet = false; | ||
setupSourceMap() { | ||
if (this.sourceMapSet) { | ||
return; | ||
} | ||
if ('setSourceMapsEnabled' in process && typeof Error.prepareStackTrace !== 'function') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
process.setSourceMapsEnabled(true); | ||
} | ||
this.sourceMapSet = true; | ||
} | ||
/* c8 ignore next */ | ||
async getSource(fileUrl, maybeFormat) { | ||
@@ -15,13 +30,24 @@ if (this.sourcesCache[fileUrl]) { | ||
} | ||
this.setupSourceMap(); | ||
const filePath = fileURLToPath(fileUrl); | ||
const sourceFile = await readFile(filePath); | ||
const fileContent = sourceFile.toString(); | ||
const tsconfigCache = this.findTsConfig(filePath); | ||
const cacheOptions = { modifier: tsconfigCache?.hash, extension: cacheExtension }; | ||
let transformed = await this.cache.get(fileContent, cacheOptions); | ||
/* c8 ignore next 2 */ | ||
const format = (maybeFormat ?? (await detectPackageJsonType(filePath)) ?? 'module'); | ||
const sourceFile = await readFile(filePath); | ||
const esbuildFormat = format === 'module' ? 'esm' : 'cjs'; | ||
const { code: transformed } = await transform(sourceFile.toString(), this.getOptions({ | ||
sourcefile: filePath, | ||
format: esbuildFormat, | ||
})); | ||
if (!transformed) { | ||
const result = await transform(fileContent, this.getOptions(tsconfigCache?.config, { | ||
sourcefile: filePath, | ||
format: esbuildFormat, | ||
})); | ||
transformed = result.code; | ||
await this.cache.save(transformed, cacheOptions); | ||
} | ||
this.sourcesCache[fileUrl] = { source: transformed, format }; | ||
return this.sourcesCache[fileUrl]; | ||
} | ||
/* c8 ignore next */ | ||
getSourceSync(fileUrl, format = 'commonjs') { | ||
@@ -31,14 +57,20 @@ if (this.sourcesCache[fileUrl]) { | ||
} | ||
this.setupSourceMap(); | ||
const filePath = fileURLToPath(fileUrl); | ||
const code = readFileSync(filePath, 'utf8'); | ||
const { code: transformed } = transformSync(code, this.getOptions({ | ||
sourcefile: filePath, | ||
format: 'cjs', | ||
})); | ||
const fileContent = readFileSync(filePath, 'utf8').toString(); | ||
const tsconfigCache = this.findTsConfig(filePath); | ||
const cacheOptions = { file: this.cache.createHash(fileContent), modifier: tsconfigCache?.hash, extension: cacheExtension }; | ||
let transformed = this.cache.getSync(cacheOptions); | ||
if (!transformed) { | ||
const result = transformSync(fileContent, this.getOptions(tsconfigCache?.config, { | ||
sourcefile: filePath, | ||
format: 'cjs', | ||
})); | ||
transformed = result.code; | ||
this.cache.saveSync(transformed, cacheOptions); | ||
} | ||
this.sourcesCache[fileUrl] = { source: transformed, format }; | ||
return this.sourcesCache[fileUrl]; | ||
} | ||
getOptions(options) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const tsconfig = this.findTsConfig(options.sourcefile); | ||
getOptions(tsconfig, options) { | ||
return { | ||
@@ -55,10 +87,12 @@ loader: 'default', | ||
findTsConfig(sourceFile) { | ||
const sourceDirname = resolve(dirname(sourceFile)); | ||
const sourceDirname = dirname(sourceFile); | ||
if (this.tsconfigCache[sourceDirname]) { | ||
return this.sourcesCache[sourceDirname]; | ||
return this.tsconfigCache[sourceDirname]; | ||
} | ||
const result = getTsconfig(sourceDirname); | ||
if (result) { | ||
const tsconfigDirname = resolve(dirname(result.path)); | ||
this.tsconfigCache[sourceDirname] = result.config; | ||
const tsconfigDirname = dirname(result.path); | ||
const hash = this.cache.createHash(JSON.stringify(result.config)); | ||
const cache = { config: result.config, hash }; | ||
this.tsconfigCache[sourceDirname] = cache; | ||
if (/^[./\\]*$/.test(relative(sourceDirname, tsconfigDirname))) { | ||
@@ -68,3 +102,3 @@ let subDir = sourceDirname; | ||
subDir = join(subDir, '..'); | ||
this.tsconfigCache[subDir] = result.config; | ||
this.tsconfigCache[subDir] = cache; | ||
} | ||
@@ -71,0 +105,0 @@ } |
{ | ||
"name": "@node-loaders/esbuild", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"private": false, | ||
@@ -45,3 +45,3 @@ "keywords": [ | ||
"@node-loaders/core": "^0.5.0", | ||
"@node-loaders/resolve": "^0.4.0", | ||
"@node-loaders/resolve": "^0.5.0", | ||
"esbuild": "^0.15.16", | ||
@@ -56,3 +56,3 @@ "get-tsconfig": "^4.2.0" | ||
}, | ||
"gitHead": "1d3e5a5efdcc6e5d96453c5b6e64d9a20f83b05d" | ||
"gitHead": "31b52b61f102cef50d6cd451f66bb5d622d2a548" | ||
} |
@@ -11,2 +11,9 @@ # @node-loaders/esbuild | ||
### Loaders | ||
- `@node-loaders/esbuild` for esm with loose extension support. | ||
- `@node-loaders/esbuild/strict` for esm with strict extension imports with loose require support. | ||
- `@node-loaders/esbuild/esm` for esm with strict extension imports without require support. | ||
- `@node-loaders/esbuild/node14` for esm with loose extension support with Node v14 support. | ||
## ESM/strict mode | ||
@@ -13,0 +20,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40009
503
44
+ Added@node-loaders/resolve@0.5.0(transitive)
- Removed@node-loaders/resolve@0.4.0(transitive)
Updated@node-loaders/resolve@^0.5.0