Skip to content

Commit

Permalink
implement recommendations in nodejs/node#44859
Browse files Browse the repository at this point in the history
  • Loading branch information
vscheuber committed Feb 16, 2023
1 parent f0024b2 commit c746d18
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -18,7 +18,7 @@
"devops"
],
"engines": {
"node": ">=14"
"node": ">=16"
},
"repository": {
"type": "git",
Expand All @@ -27,7 +27,7 @@
"bugs": {
"url": "https://github.com/rockcarver/frodo-cli/issues"
},
"main": "esm/app.js",
"main": "esm/launch.js",
"scripts": {
"test": "npx tsc && node --experimental-vm-modules node_modules/jest/bin/jest.js",
"test:local": "npm run build && node --experimental-vm-modules node_modules/jest/bin/jest.js",
Expand Down Expand Up @@ -78,7 +78,7 @@
],
"license": "MIT",
"bin": {
"frodo": "./esm/app.js"
"frodo": "./esm/launch.js"
},
"babel": {
"plugins": [
Expand Down
2 changes: 0 additions & 2 deletions src/app.ts
@@ -1,5 +1,3 @@
#!/usr/bin/env -S node --no-warnings --enable-source-maps --experimental-specifier-resolution=node

import { ConnectionProfile } from '@rockcarver/frodo-lib';
import { Command } from 'commander';

Expand Down
19 changes: 19 additions & 0 deletions src/launch.ts
@@ -0,0 +1,19 @@
#!/usr/bin/env node
import { spawn } from 'node:child_process';
import { createRequire } from 'module';

const require = createRequire(import.meta.url);

const launchArgs = [
'--no-warnings',
'--enable-source-maps',
'--experimental-loader',
require.resolve('./loader.js'),
require.resolve('./app.js'),
];
const frodoArgs = process.argv.slice(2);

spawn(process.execPath, [...launchArgs, ...frodoArgs], {
stdio: 'inherit',
shell: false,
});
44 changes: 44 additions & 0 deletions src/loader.ts
@@ -0,0 +1,44 @@
import { builtinModules } from 'node:module';
import { dirname } from 'path';
import { cwd } from 'process';
import { fileURLToPath, pathToFileURL } from 'url';
import { promisify } from 'util';

import resolveCallback from 'resolve/async.js';

const resolveAsync = promisify(resolveCallback);

const baseURL = pathToFileURL(cwd() + '/').href;

export async function resolve(specifier, context, next) {
const { parentURL = baseURL } = context;

if (specifier.startsWith('node:') || builtinModules.includes(specifier)) {
return next(specifier, context);
}

// `resolveAsync` works with paths, not URLs
if (specifier.startsWith('file://')) {
specifier = fileURLToPath(specifier);
}
const parentPath = fileURLToPath(parentURL);

let url;
try {
const resolution = await resolveAsync(specifier, {
basedir: dirname(parentPath),
// For whatever reason, --experimental-specifier-resolution=node doesn't search for .mjs extensions
// but it does search for index.mjs files within directories
extensions: ['.js', '.json', '.node', '.mjs'],
});
url = pathToFileURL(resolution).href;
} catch (error) {
if (error.code === 'MODULE_NOT_FOUND') {
// Match Node's error code
error.code = 'ERR_MODULE_NOT_FOUND';
}
throw error;
}

return next(url, context);
}

0 comments on commit c746d18

Please sign in to comment.