Skip to content

Commit

Permalink
Port to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
kherock committed May 31, 2022
1 parent 981e74c commit 1751868
Show file tree
Hide file tree
Showing 55 changed files with 304 additions and 320 deletions.
13 changes: 3 additions & 10 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,13 @@
"extends": ["eslint:recommended", "plugin:import/errors", "plugin:import/warnings"],
"plugins": ["import"],
"parserOptions": {
"ecmaVersion": 11
"ecmaVersion": 13,
"sourceType": "module"
},
"rules": {
"eqeqeq": "error",
"no-trailing-spaces": "error",
"prefer-arrow-callback": "error",
"semi": "error"
},
"overrides": [
{
"files": ["./**/*.mjs"],
"parserOptions": {
"sourceType": "module"
}
}
]
}
}
13 changes: 0 additions & 13 deletions bin/node-dev

This file was deleted.

8 changes: 8 additions & 0 deletions bin/node-dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env node

import dev from '../lib/index.js';
import cli from '../lib/cli.js';

const { script, scriptArgs, nodeArgs, opts } = cli(process.argv);

dev(script, scriptArgs, nodeArgs, opts);
File renamed without changes.
6 changes: 2 additions & 4 deletions lib/clear.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
const control = '\u001bc';
const clearFactory = clear => (clear ? () => process.stdout.write(control) : () => {});

module.exports = { clearFactory, control };
export const control = '\u001bc';
export const clearFactory = clear => (clear ? () => process.stdout.write(control) : () => {});
10 changes: 5 additions & 5 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const assert = require('assert');
const minimist = require('minimist');
const { resolve } = require('path');
import assert from 'assert';
import minimist from 'minimist';
import { resolve } from 'path';

const { getConfig } = require('./cfg');
import { getConfig } from './cfg.cjs';

const arrayify = v => (Array.isArray(v) ? [...v] : [v]);
const argify = key => ({ arg: `--${key}`, key });
Expand Down Expand Up @@ -55,7 +55,7 @@ const unknownFactory = args => arg => {
key && !nodeDevNumber.includes(key) && args.push({ arg, key });
};

module.exports = argv => {
export default argv => {
const nodeCustomArgs = [];
const args = argv.slice(2).filter(nodeCustomFactory(nodeCustomArgs));

Expand Down
60 changes: 0 additions & 60 deletions lib/hook.js

This file was deleted.

6 changes: 2 additions & 4 deletions lib/ignore.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,5 @@ const getPrefix = mod => {

const isPrefixOf = value => prefix => value.startsWith(prefix);

const configureDeps = deps => required => deps !== -1 && getLevel(required) > deps;
const configureIgnore = ignore => required => ignore.some(isPrefixOf(required));

module.exports = { configureDeps, configureIgnore };
export const configureDeps = deps => required => deps !== -1 && getLevel(required) > deps;
export const configureIgnore = ignore => required => ignore.some(isPrefixOf(required));
52 changes: 29 additions & 23 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
const { fork } = require('child_process');
const filewatcher = require('filewatcher');
const semver = require('semver');
const { pathToFileURL } = require('url');

const { clearFactory } = require('./clear');
const { configureDeps, configureIgnore } = require('./ignore');
const ipc = require('./ipc');
const logFactory = require('./log');
const notifyFactory = require('./notify');

module.exports = function (
import { fork } from 'child_process';
import filewatcher from 'filewatcher';
import { createRequire } from 'module';
import semver from 'semver';

import { clearFactory } from './clear.js';
import { configureDeps, configureIgnore } from './ignore.js';
import ipc from './ipc.cjs';
import logFactory from './log.js';
import notifyFactory from './notify.js';

const require = createRequire(import.meta.url);
const resolveHook = hook => require.resolve('./require/' + hook);

export default function (
script,
scriptArgs,
nodeArgs,
Expand All @@ -18,13 +21,15 @@ module.exports = function (
debounce,
dedupe,
deps,
fork: patchFork,
graceful_ipc: gracefulIPC,
ignore,
interval,
notify: notifyEnabled,
poll: forcePolling,
respawn,
timestamp
timestamp,
vm: patchVm
}
) {
if (!script) {
Expand Down Expand Up @@ -52,9 +57,6 @@ module.exports = function (
const isIgnored = configureIgnore(ignore);
const isTooDeep = configureDeps(deps);

// Run ./dedupe.js as preload script
if (dedupe) process.env.NODE_DEV_PRELOAD = require.resolve('./dedupe');

const watcher = filewatcher({ debounce, forcePolling, interval });
let isPaused = false;

Expand Down Expand Up @@ -89,12 +91,16 @@ module.exports = function (
function start() {
isPaused = false;

const args = nodeArgs.slice();
const execArgv = nodeArgs.slice();

args.push(`--require=${require.resolve('./wrap')}`);
execArgv.push(`--require=${resolveHook('suppress-experimental-warnings')}`);
if (dedupe) execArgv.push(`--require=${resolveHook('dedupe')}`);
execArgv.push(`--require=${resolveHook('patch')}`);
if (patchFork) execArgv.push(`--require=${resolveHook('patch-fork')}`);
if (patchVm) execArgv.push(`--require=${resolveHook('patch-vm')}`);

if (semver.satisfies(process.version, '<12.17.0')) {
args.push('--experimental-modules');
execArgv.push('--experimental-modules');
}

const loaderName = semver.satisfies(process.version, '>=16.12.0')
Expand All @@ -103,18 +109,18 @@ module.exports = function (
? 'get-format'
: 'resolve';

const loaderURL = pathToFileURL(require.resolve(`./loaders/${loaderName}.mjs`));
const loaderURL = new URL(`./loaders/${loaderName}.mjs`, import.meta.url);

const experimentalPrefix = semver.satisfies(process.version, '>=12.11.1')
? 'experimental-'
: '';

args.push(`--${experimentalPrefix}loader=${loaderURL.href}`);
execArgv.push(`--${experimentalPrefix}loader=${loaderURL.href}`);

child = fork(script, scriptArgs, {
cwd: process.cwd(),
env: process.env,
execArgv: args
execArgv
});

if (respawn) {
Expand Down Expand Up @@ -167,4 +173,4 @@ module.exports = function (

clearOutput();
start();
};
}
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/loaders/get-format.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createRequire } from 'module';
import { fileURLToPath } from 'url';
import { send } from './ipc.mjs';
import { send } from '../ipc.cjs';

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

Expand Down
5 changes: 0 additions & 5 deletions lib/loaders/ipc.mjs

This file was deleted.

2 changes: 1 addition & 1 deletion lib/loaders/load.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createRequire } from 'module';
import { fileURLToPath } from 'url';
import { send } from './ipc.mjs';
import { send } from '../ipc.cjs';

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

Expand Down
2 changes: 1 addition & 1 deletion lib/loaders/resolve.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fileURLToPath } from 'url';
import { send } from './ipc.mjs';
import { send } from '../ipc.cjs';

export function resolve(specifier, parentModule, defaultResolve) {
const resolved = defaultResolve(specifier, parentModule);
Expand Down
6 changes: 3 additions & 3 deletions lib/log.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { format } = require('util');
const dateformat = require('dateformat');
import { format } from 'util';
import dateformat from 'dateformat';

const colors = {
error: '31;1',
Expand All @@ -16,7 +16,7 @@ const colorOutput = (s, c) => '\x1B[' + c + 'm' + s + '\x1B[0m';
* Logs a message to the console. The level is displayed in ANSI colors:
* errors are bright red, warnings are yellow, and info is cyan.
*/
module.exports = ({ noColor, timestamp }) => {
export default ({ noColor, timestamp }) => {
const enableColor = !(noColor || !process.stdout.isTTY);
const color = enableColor ? colorOutput : noop;

Expand Down
8 changes: 5 additions & 3 deletions lib/notify.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const notifier = require('node-notifier');
import notifier from 'node-notifier';
import { fileURLToPath } from 'url';

const iconLevelPath = level => require.resolve(`../icons/node_${level}.png`);
const iconLevelPath = level =>
fileURLToPath(new URL(`../icons/node_${level}.png`, import.meta.url));

// Writes a message to the console and optionally displays a desktop notification.
module.exports = (notifyEnabled, log) => {
export default (notifyEnabled, log) => {
return (title = 'node-dev', message, level = 'info') => {
log[level](`${title}: ${message}`);

Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions lib/require/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
11 changes: 11 additions & 0 deletions lib/require/patch-fork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const childProcess = require('child_process');
const { relay } = require('../ipc.cjs');

// Overwrite child_process.fork() so that we can hook into forked processes
// too. We also need to relay messages about required files to the parent.
const { fork } = childProcess;
childProcess.fork = (modulePath, args, options) => {
const child = fork(modulePath, args, options);
relay(child);
return child;
};
25 changes: 25 additions & 0 deletions lib/require/patch-vm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const vm = require('vm');
const { send } = require('../ipc.cjs');

patch(vm, 'createScript', 1);
patch(vm, 'runInThisContext', 1);
patch(vm, 'runInNewContext', 2);
patch(vm, 'runInContext', 2);

/**
* Patch the specified method to watch the file at the given argument
* index.
*/
function patch(obj, method, optionsArgIndex) {
const orig = obj[method];
if (!orig) return;
obj[method] = function () {
const opts = arguments[optionsArgIndex];
let file = null;
if (opts) {
file = typeof opts === 'string' ? opts : opts.filename;
}
if (file) send({ required: file });
return orig.apply(this, arguments);
};
}
Loading

0 comments on commit 1751868

Please sign in to comment.