Skip to content

Commit

Permalink
Fix #1072 (#1085)
Browse files Browse the repository at this point in the history
* Fix #1072

* add tests
  • Loading branch information
cspotcode committed Aug 4, 2020
1 parent 8dfb75c commit 490ed8a
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 31 deletions.
32 changes: 1 addition & 31 deletions dist-raw/node-esm-resolve-implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,7 @@ const {
Stats,
} = require('fs');
// const { getOptionValue } = require('internal/options');
const { getOptionValue } = (() => {
let options;
function parseOptions() {
if (!options) {
options = {
'--preserve-symlinks': false,
'--preserve-symlinks-main': false,
'--input-type': undefined,
'--experimental-specifier-resolution': 'explicit',
...parseExecArgv()
}
}
};
function parseExecArgv () {
return require('arg')({
'--preserve-symlinks': Boolean,
'--preserve-symlinks-main': Boolean,
'--input-type': String,
'--experimental-specifier-resolution': String
}, {
argv: process.execArgv,
permissive: true
});
}
return {
getOptionValue: (opt) => {
parseOptions();
return options[opt];
}
};
})();
const { getOptionValue } = require('./node-options');
const { sep } = require('path');

const preserveSymlinks = getOptionValue('--preserve-symlinks');
Expand Down
83 changes: 83 additions & 0 deletions dist-raw/node-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Replacement for node's internal 'internal/options' module

exports.getOptionValue = getOptionValue;
function getOptionValue(opt) {
parseOptions();
return options[opt];
}

let options;
function parseOptions() {
if (!options) {
options = {
'--preserve-symlinks': false,
'--preserve-symlinks-main': false,
'--input-type': undefined,
'--experimental-specifier-resolution': 'explicit',
...parseArgv(getNodeOptionsEnvArgv()),
...parseArgv(process.execArgv)
}
}
}

function parseArgv(argv) {
return require('arg')({
'--preserve-symlinks': Boolean,
'--preserve-symlinks-main': Boolean,
'--input-type': String,
'--experimental-specifier-resolution': String
}, {
argv,
permissive: true
});
}

function getNodeOptionsEnvArgv() {
const errors = [];
const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || '', errors);
if (errors.length !== 0) {
// TODO: handle errors somehow
}
return envArgv;
}

// Direct JS port of C implementation: https://github.com/nodejs/node/blob/67ba825037b4082d5d16f922fb9ce54516b4a869/src/node_options.cc#L1024-L1063
function ParseNodeOptionsEnvVar(node_options, errors) {
const env_argv = [];

let is_in_string = false;
let will_start_new_arg = true;
for (let index = 0; index < node_options.length; ++index) {
let c = node_options[index];

// Backslashes escape the following character
if (c === '\\' && is_in_string) {
if (index + 1 === node_options.length) {
errors.push("invalid value for NODE_OPTIONS " +
"(invalid escape)\n");
return env_argv;
} else {
c = node_options[++index];
}
} else if (c === ' ' && !is_in_string) {
will_start_new_arg = true;
continue;
} else if (c === '"') {
is_in_string = !is_in_string;
continue;
}

if (will_start_new_arg) {
env_argv.push(c);
will_start_new_arg = false;
} else {
env_argv[env_argv.length - 1] += c;
}
}

if (is_in_string) {
errors.push("invalid value for NODE_OPTIONS " +
"(unterminated string)\n");
}
return env_argv;
}
25 changes: 25 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -767,8 +767,33 @@ describe('ts-node', function () {

return done()
})
})

describe('supports experimental-specifier-resolution=node', () => {
it('via --experimental-specifier-resolution', (done) => {
exec(`${cmd} --experimental-specifier-resolution=node index.ts`, { cwd: join(__dirname, '../tests/esm-node-resolver') }, function (err, stdout) {
expect(err).to.equal(null)
expect(stdout).to.equal('foo bar baz biff\n')

return done()
})
})
it('via NODE_OPTIONS', (done) => {
exec(`${cmd} index.ts`, {
cwd: join(__dirname, '../tests/esm-node-resolver'),
env: {
...process.env,
NODE_OPTIONS: '--experimental-specifier-resolution=node'
}
}, function (err, stdout) {
expect(err).to.equal(null)
expect(stdout).to.equal('foo bar baz biff\n')

return done()
})
})
})

it('throws ERR_REQUIRE_ESM when attempting to require() an ESM script while ESM loader is enabled', function (done) {
exec(`${cmd} ./index.js`, { cwd: join(__dirname, '../tests/esm-err-require-esm') }, function (err, stdout, stderr) {
expect(err).to.not.equal(null)
Expand Down

0 comments on commit 490ed8a

Please sign in to comment.