From 6aded827afd68e3f6903c8717ace36ddec142661 Mon Sep 17 00:00:00 2001 From: Kyle Herock Date: Sat, 26 Mar 2022 00:32:19 -0400 Subject: [PATCH] [ESM] Support wrapping a custom loader --- .eslintrc | 1 + lib/cli.js | 2 +- lib/index.js | 10 ++++++++++ lib/loader-legacy.mjs | 13 ++++++++++++- lib/loader.mjs | 10 +++++++++- 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index 230d696..e72ffb9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -18,6 +18,7 @@ { "files": ["./**/*.mjs"], "parserOptions": { + "ecmaVersion": 13, "sourceType": "module" } } diff --git a/lib/cli.js b/lib/cli.js index 4edc038..17c3aa3 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -16,7 +16,7 @@ const nodeString = ['require']; const nodeDevBoolean = ['clear', 'dedupe', 'fork', 'notify', 'poll', 'respawn', 'vm']; const nodeDevNumber = ['debounce', 'deps', 'interval']; -const nodeDevString = ['graceful_ipc', 'ignore', 'timestamp']; +const nodeDevString = ['graceful_ipc', 'ignore', 'timestamp', 'experimental-loader']; const alias = Object.assign({}, nodeAlias); const boolean = [...nodeBoolean, ...nodeDevBoolean]; diff --git a/lib/index.js b/lib/index.js index 10794ed..0b9917b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,6 @@ const { fork } = require('child_process'); const filewatcher = require('filewatcher'); +const path = require('path'); const semver = require('semver'); const { pathToFileURL } = require('url'); @@ -20,6 +21,7 @@ module.exports = function ( debounce, dedupe, deps, + 'experimental-loader': wrapLoader, graceful_ipc: gracefulIPC, ignore, interval, @@ -98,6 +100,14 @@ module.exports = function ( ? 'loader-legacy.mjs' : 'loader.mjs'; const loader = pathToFileURL(resolveMain(localPath(loaderPath))); + if (wrapLoader) { + if (wrapLoader.startsWith('.')) { + const customLoaderAbsPath = path.resolve(process.cwd(), wrapLoader); + loader.searchParams.append('wrap', pathToFileURL(customLoaderAbsPath)); + } else { + loader.searchParams.append('wrap', wrapLoader); + } + } if (semver.satisfies(process.version, '<12.17.0')) { args.push('--experimental-modules'); } diff --git a/lib/loader-legacy.mjs b/lib/loader-legacy.mjs index 0026437..d028be2 100644 --- a/lib/loader-legacy.mjs +++ b/lib/loader-legacy.mjs @@ -4,13 +4,19 @@ import { send } from './ipc.mjs'; const require = createRequire(import.meta.url); +const customLoaderUrl = new URL(import.meta.url).searchParams.get('wrap'); +const customLoader = customLoaderUrl ? await import(customLoaderUrl) : {}; + +export const resolve = customLoader.resolve; + export async function getFormat(url, context, defaultGetFormat) { const getPackageType = require('get-package-type'); const filePath = fileURLToPath(url); send({ required: filePath }); + const customGetFormat = customLoader.load || defaultGetFormat; try { - return await defaultGetFormat(url, context, defaultGetFormat); + return await customGetFormat(url, context, defaultGetFormat); } catch (err) { if (err.code === 'ERR_UNKNOWN_FILE_EXTENSION') { return { format: await getPackageType(filePath) }; @@ -18,3 +24,8 @@ export async function getFormat(url, context, defaultGetFormat) { throw err; } } + +export const getSource = customLoader.getSource; + +export const transformSource = customLoader.transformSource; +export const getGlobalPreloadCode = customLoader.getGlobalPreloadCode; diff --git a/lib/loader.mjs b/lib/loader.mjs index 302001e..e46cdc8 100644 --- a/lib/loader.mjs +++ b/lib/loader.mjs @@ -4,13 +4,19 @@ import { send } from './ipc.mjs'; const require = createRequire(import.meta.url); +const customLoaderUrl = new URL(import.meta.url).searchParams.get('wrap'); +const customLoader = customLoaderUrl ? await import(customLoaderUrl) : {}; + +export const resolve = customLoader.resolve; + export async function load(url, context, defaultLoad) { const getPackageType = require('get-package-type'); const filePath = fileURLToPath(url); send({ required: filePath }); + const customLoad = customLoader.load || defaultLoad; try { - return await defaultLoad(url, context, defaultLoad); + return await customLoad(url, context, defaultLoad); } catch (err) { if (err.code === 'ERR_UNKNOWN_FILE_EXTENSION') { return { format: await getPackageType(filePath), source: null }; @@ -18,3 +24,5 @@ export async function load(url, context, defaultLoad) { throw err; } } + +export const globalPreload = customLoader.globalPreload;