Skip to content
This repository has been archived by the owner on May 12, 2022. It is now read-only.

Commit

Permalink
feat: add support for node >=16.12.0 (#19)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
elianiva and antfu committed Oct 25, 2021
1 parent 71a4d75 commit ccb92a3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
node-version: [12.x, 14.x, 16.x, 16.11, 16.12]
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: false

Expand Down
74 changes: 54 additions & 20 deletions loader.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,37 @@ import { transformSync } from 'esbuild'
const baseURL = pathToFileURL(`${process.cwd()}/`).href
const isWindows = process.platform === 'win32'

const extensionsRegex = /\.(tsx?|json)$/;
const extensionsRegex = /\.(tsx?|json)$/
const excludeRegex = /^\w+:/

function esbuildTransformSync(rawSource, filename, url, format) {
const {
code: js,
warnings,
map: jsSourceMap,
} = transformSync(rawSource.toString(), {
sourcefile: filename,
sourcemap: 'both',
loader: new URL(url).pathname.match(extensionsRegex)[1],
target: `node${process.versions.node}`,
format: format === 'module' ? 'esm' : 'cjs',
})

if (warnings && warnings.length > 0) {
for (const warning of warnings) {
console.warn(warning.location)
console.warn(warning.text)
}
}

return { js, jsSourceMap }
}

export function resolve(specifier, context, defaultResolve) {
const { parentURL = baseURL } = context
const url = new URL(specifier, parentURL)
if (extensionsRegex.test(url.pathname))
return { url: url.href }
return { url: url.href, format: 'module' }

// ignore `data:` and `node:` prefix etc.
if (!excludeRegex.test(specifier)) {
Expand All @@ -22,14 +45,39 @@ export function resolve(specifier, context, defaultResolve) {
url.pathname = `${pathname}.${ext}`
const path = fileURLToPath(url.href)
if (fs.existsSync(path))
return { url: url.href }
return {
url: url.href,
format: extensionsRegex.test(url.pathname) && 'module',
}
}
}

// Let Node.js handle all other specifiers.
return defaultResolve(specifier, context, defaultResolve)
}

// New hook starting from Node v16.12.0
// See: https://github.com/nodejs/node/pull/37468
export function load(url, context, defaultLoad) {
if (extensionsRegex.test(new URL(url).pathname)) {
const { format } = context

let filename = url
if (!isWindows) filename = fileURLToPath(url)

const rawSource = fs.readFileSync(new URL(url), { encoding: 'utf8' })
const { js } = esbuildTransformSync(rawSource, filename, url, format)

return {
format: 'module',
source: js,
}
}

// Let Node.js handle all other format / sources.
return defaultLoad(url, context, defaultLoad)
}

export function getFormat(url, context, defaultGetFormat) {
if (extensionsRegex.test(new URL(url).pathname)) {
return {
Expand All @@ -46,23 +94,9 @@ export function transformSource(source, context, defaultTransformSource) {

if (extensionsRegex.test(new URL(url).pathname)) {
let filename = url
if (!isWindows)
filename = fileURLToPath(url)

const { code: js, warnings, map: jsSourceMap } = transformSync(source.toString(), {
sourcefile: filename,
sourcemap: 'both',
loader: new URL(url).pathname.match(extensionsRegex)[1],
target: `node${process.versions.node}`,
format: format === 'module' ? 'esm' : 'cjs',
})

if (warnings && warnings.length > 0) {
for (const warning of warnings) {
console.warn(warning.location)
console.warn(warning.text)
}
}
if (!isWindows) filename = fileURLToPath(url)

const { js } = esbuildTransformSync(source, filename, url, format)

return {
source: js,
Expand Down

0 comments on commit ccb92a3

Please sign in to comment.