Skip to content

Commit

Permalink
Add support for Node 17
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Oct 23, 2021
1 parent a574477 commit e72b930
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 10 deletions.
4 changes: 2 additions & 2 deletions esm-loader.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createLoader} from './lib/integration/node.js'

const {getFormat, transformSource} = createLoader()
const {load, getFormat, transformSource} = createLoader()

export {getFormat, transformSource, createLoader}
export {load, getFormat, transformSource, createLoader}
34 changes: 33 additions & 1 deletion lib/integration/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
* @typedef {import('../compile.js').CompileOptions} CompileOptions
*/

import {promises as fs} from 'node:fs'
import path from 'node:path'
import {URL, fileURLToPath} from 'node:url'
import {VFile} from 'vfile'
import {createFormatAwareProcessors} from '../util/create-format-aware-processors.js'

Expand All @@ -14,12 +16,39 @@ import {createFormatAwareProcessors} from '../util/create-format-aware-processor
export function createLoader(options) {
const {extnames, process} = createFormatAwareProcessors(options)

return {getFormat, transformSource}
return {load, getFormat, transformSource}

/* c8 ignore start */
// Node version 17.
/**
* @param {string} url
* @param {unknown} context
* @param {Function} defaultLoad
*/
async function load(url, context, defaultLoad) {
if (!extnames.includes(path.extname(url))) {
return defaultLoad(url, context, defaultLoad)
}

const fp = fileURLToPath(new URL(url))
const value = await fs.readFile(fp)
const file = await process(new VFile({value, path: new URL(url)}))

// V8 on Erbium.
/* c8 ignore next 2 */
return {
format: 'module',
source: String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')
}
}

// Pre version 17.
/**
* @param {string} url
* @param {unknown} context
* @param {Function} defaultGetFormat
* @deprecated
* This is an obsolete legacy function that no longer works in Node 17.
*/
function getFormat(url, context, defaultGetFormat) {
return extnames.includes(path.extname(url))
Expand All @@ -31,6 +60,8 @@ export function createLoader(options) {
* @param {string} value
* @param {{url: string, [x: string]: unknown}} context
* @param {Function} defaultTransformSource
* @deprecated
* This is an obsolete legacy function that no longer works in Node 17.
*/
async function transformSource(value, context, defaultTransformSource) {
if (!extnames.includes(path.extname(context.url))) {
Expand All @@ -42,4 +73,5 @@ export function createLoader(options) {
/* c8 ignore next 2 */
return {source: String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')}
}
/* c8 ignore end */
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@
"prepack": "npm run build && npm run format",
"build": "rimraf \"{lib/**/**,test/**/**,script/**}*.d.ts\" \"{esbuild,esm-loader,index,rollup}.d.ts\" && tsc && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node --no-warnings --experimental-loader=./esm-loader.js test/index.js && node test/register.cjs",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --no-warnings --experimental-loader=./esm-loader.js test/index.js",
"test-api": "node --experimental-loader=./esm-loader.js test/index.js && node test/register.cjs",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --experimental-loader=./esm-loader.js test/index.js",
"test": "npm run build && npm run format && npm run test-coverage"
},
"prettier": {
Expand Down
5 changes: 3 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,10 @@ To pass options, you can make your own loader, such as this `my-loader.js`:
```js
import {createLoader} from 'xdm/esm-loader.js'

const {getFormat, transformSource} = createLoader(/* Options… */)
// Load is for Node 17+, the rest for 12, 14, 16.
const {load, getFormat, transformSource} = createLoader(/* Options… */)

export {getFormat, transformSource}
export {load, getFormat, transformSource}
```

Which can then be used with `node --experimental-loader=./my-loader.js`.
Expand Down
10 changes: 8 additions & 2 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,14 @@ test('xdm', async (t) => {

t.equal(
render(
// @ts-expect-error: Preact types do not accept `JSX.Element`.
h(await run(compileSync('?', {jsxImportSource: 'preact/compat'})), {}, [])
h(
// @ts-expect-error: React and Preact interferring.
await run(compileSync('?', {jsxImportSource: 'preact'}), {
keepImport: true
}),
{},
[]
)
),
'<p>?</p>',
'should support an import source (`@jsxImportSource`)'
Expand Down
4 changes: 3 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ import './evaluate.js'
import './rollup.js'
import './source-map.js'
import './vue.js'
import './webpack.js'
// Can’t test webpack on Node 17 for now:
// <https://github.com/webpack/webpack/issues/14532>
// import './webpack.js'

0 comments on commit e72b930

Please sign in to comment.