Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1072 #1085

Merged
merged 3 commits into from Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 1 addition & 31 deletions dist-raw/node-esm-resolve-implementation.js
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
@@ -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
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