diff --git a/src/bin.ts b/src/bin.ts index 0194f3a3c..13907f39e 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -376,7 +376,7 @@ Options: } // Prepend `ts-node` arguments to CLI for child processes. - process.execArgv.unshift( + process.execArgv.push( __filename, ...process.argv.slice(2, process.argv.length - args._.length) ); diff --git a/src/test/helpers.ts b/src/test/helpers.ts index 2ff36f157..5327459be 100644 --- a/src/test/helpers.ts +++ b/src/test/helpers.ts @@ -29,6 +29,7 @@ export const DIST_DIR = resolve(__dirname, '..'); export const TEST_DIR = join(__dirname, '../../tests'); export const PROJECT = join(TEST_DIR, 'tsconfig.json'); export const BIN_PATH = join(TEST_DIR, 'node_modules/.bin/ts-node'); +export const BIN_PATH_JS = join(TEST_DIR, 'node_modules/ts-node/dist/bin.js'); export const BIN_SCRIPT_PATH = join( TEST_DIR, 'node_modules/.bin/ts-node-script' diff --git a/src/test/index.spec.ts b/src/test/index.spec.ts index a709e4e8a..16c9a666b 100644 --- a/src/test/index.spec.ts +++ b/src/test/index.spec.ts @@ -3,7 +3,7 @@ import * as expect from 'expect'; import { join, resolve, sep as pathSep } from 'path'; import { tmpdir } from 'os'; import semver = require('semver'); -import { nodeSupportsEsmHooks, ts } from './helpers'; +import { BIN_PATH_JS, nodeSupportsEsmHooks, ts } from './helpers'; import { lstatSync, mkdtempSync } from 'fs'; import { npath } from '@yarnpkg/fslib'; import type _createRequire from 'create-require'; @@ -1071,6 +1071,30 @@ test('Falls back to transpileOnly when ts compiler returns emitSkipped', async ( expect(stdout).toBe('foo\n'); }); +test.suite('node environment', (test) => { + test('Sets argv and execArgv correctly in forked processes', async (t) => { + const { err, stderr, stdout } = await exec( + `node --no-warnings ${BIN_PATH} --skipIgnore ./recursive-fork/index.ts argv2` + ); + expect(err).toBeNull(); + expect(stderr).toBe(''); + const generations = stdout.split('\n'); + const expectation = { + execArgv: ['--no-warnings', BIN_PATH_JS, '--skipIgnore'], + argv: [ + // Note: argv[0] is BIN_PATH in parent, BIN_PATH_JS in child & grandchild + BIN_PATH, + resolve(TEST_DIR, 'recursive-fork/index.ts'), + 'argv2', + ], + }; + expect(JSON.parse(generations[0])).toMatchObject(expectation); + expectation.argv[0] = BIN_PATH_JS; + expect(JSON.parse(generations[1])).toMatchObject(expectation); + expect(JSON.parse(generations[2])).toMatchObject(expectation); + }); +}); + test('Detect when typescript adds new ModuleKind values; flag as a failure so we can update our code flagged [MUST_UPDATE_FOR_NEW_MODULEKIND]', async () => { // We have marked a few places in our code with MUST_UPDATE_FOR_NEW_MODULEKIND to make it easier to update them when TS adds new ModuleKinds const foundKeys: string[] = []; diff --git a/tests/recursive-fork/index.ts b/tests/recursive-fork/index.ts new file mode 100644 index 000000000..ed68a2080 --- /dev/null +++ b/tests/recursive-fork/index.ts @@ -0,0 +1,11 @@ +import { fork } from 'child_process'; + +console.log(JSON.stringify({ execArgv: process.execArgv, argv: process.argv })); +if (process.env.generation !== 'grandchild') { + const nextGeneration = + process.env.generation === 'child' ? 'grandchild' : 'child'; + fork(__filename, process.argv.slice(2), { + env: { ...process.env, generation: nextGeneration }, + stdio: 'inherit', + }); +} diff --git a/tests/recursive-fork/package.json b/tests/recursive-fork/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/recursive-fork/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/recursive-fork/tsconfig.json b/tests/recursive-fork/tsconfig.json new file mode 100644 index 000000000..8e881cf9c --- /dev/null +++ b/tests/recursive-fork/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "moduleResolution": "node" + } +}