Repository: node
Issue: `worker_threads` not respecting `--require` in `process.execArgv` or `process.env.NODE_OPTIONS`
Labels: worker

<!--
Thank you for reporting an issue.

This issue tracker is for bugs and issues found within Node.js core.
If you require more general support please file an issue on our help
repo. https://github.com/nodejs/help


Please fill in as much of the template below as you're able.

Version: output of `node -v`
Platform: output of `uname -a` (UNIX), or output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in PowerShell console (Windows)
Subsystem: if known, please specify affected core module name
-->

* **Versions**: 
  * v12.20.2
  * v14.15.5
  * v15.8.0
* **Platforms**:
  * CentOS 7 (`Linux 3.10.0-1127.8.2.el7.x86_64 #1 SMP Tue May 12 16:57:42 UTC 2020 x86_64 GNU/Linux`)
  * Windows 10 (`Microsoft Windows NT 10.0.19041.0 x64`)
* **Subsystem**: worker_threads

### What steps will reproduce the bug?

Mutate either `process.env.NODE_OPTIONS` or `process.execArgv` to include a `--require` flag before spawning a worker thread.

<details>
<summary>Test script</summary>

```js
const { Worker, isMainThread, SHARE_ENV } = require('worker_threads')
const { once } = require('events')

if (module.parent && module.parent.id === 'internal/preload') {
  // Preload
  delete require.cache[__filename]
  console.log('preloaded')
} else if (isMainThread && !process.send) {
  // Main
  const tests = [
    async () => {
      console.log('worker process.execArgv')
      const orig = process.execArgv
      process.execArgv = ['--require', __filename, ...process.execArgv]
      const worker = new Worker(__filename)
      await once(worker, 'exit')
      process.execArgv = orig
    },
    async () => {
      console.log('worker process.env.NO')
      const orig = process.env.NODE_OPTIONS
      process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
      const worker = new Worker(__filename)
      await once(worker, 'exit')
      process.env.NODE_OPTIONS = orig
    },
    async () => {
      console.log('worker SHARE_ENV')
      const orig = process.env.NODE_OPTIONS
      process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
      const worker = new Worker(__filename, { env: SHARE_ENV })
      await once(worker, 'exit')
      process.env.NODE_OPTIONS = orig
    },
  ]
  ;(async () => {
    for (const f of tests) {
      await f()
      console.log()
    }
  })()
}
```

</details>

### What is the expected behavior?

The `--require` flag is respected in each case:

```
worker process.execArgv
preloaded

worker process.env.NO
preloaded

worker SHARE_ENV
preloaded
```

### What do you see instead?

The `--require` flag is not respected:

```
worker process.execArgv

worker process.env.NO

worker SHARE_ENV
```
### Additional information

**tl;dr**: Seems like the default value of `env` and `execArgv` options of the `Worker` constructor is the **initial** value of `process.env` and `process.execArgv` instead of the current value. This behavior is in contrast to `child_process.fork`.

#### Full test script

This is the full test script with all the tests I have done (detailed below).

<details>
<summary>Test script</summary>

```js
const { Worker, isMainThread, SHARE_ENV, parentPort } = require('worker_threads')
const { fork } = require('child_process')
const { once } = require('events')

if (module.parent && module.parent.id === 'internal/preload') {
  // Preload
  delete require.cache[__filename]
  console.log('preloaded')
} else if (isMainThread && !process.send) {
  // Main
  const tests = [
    async () => {
      console.log('worker control')
      const worker = new Worker(__filename)
      await once(worker, 'exit')
    },
    async () => {
      console.log('worker process.execArgv')
      const orig = process.execArgv
      process.execArgv = ['--require', __filename, ...process.execArgv]
      const worker = new Worker(__filename)
      await once(worker, 'exit')
      process.execArgv = orig
    },
    async () => {
      console.log('worker execArgv option')
      const worker = new Worker(__filename, { execArgv: ['--require', __filename, ...process.execArgv] })
      await once(worker, 'exit')
    },
    async () => {
      console.log('worker process.env.NO')
      const orig = process.env.NODE_OPTIONS
      process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
      const worker = new Worker(__filename)
      await once(worker, 'exit')
      process.env.NODE_OPTIONS = orig
    },
    async () => {
      console.log('worker SHARE_ENV')
      const orig = process.env.NODE_OPTIONS
      process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
      const worker = new Worker(__filename, { env: SHARE_ENV })
      await once(worker, 'exit')
      process.env.NODE_OPTIONS = orig
    },
    async () => {
      console.log('worker env option')
      const worker = new Worker(__filename, { env: { NODE_OPTIONS: `--require ${__filename} ${process.env.NODE_OPTIONS}` } })
      await once(worker, 'exit')
    },

    async () => {
      console.log('fork control')
      const cp = fork(__filename)
      await once(cp, 'exit')
    },
    async () => {
      console.log('fork process.execArgv')
      const orig = process.execArgv
      process.execArgv = ['--require', __filename, ...process.execArgv]
      const cp = fork(__filename)
      await once(cp, 'exit')
      process.execArgv = orig
    },
    async () => {
      console.log('fork execArgv option')
      const cp = fork(__filename, { execArgv: ['--require', __filename, ...process.execArgv] })
      await once(cp, 'exit')
    },
    async () => {
      console.log('fork process.env.NO')
      const orig = process.env.NODE_OPTIONS
      process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
      const cp = fork(__filename)
      await once(cp, 'exit')
      process.env.NODE_OPTIONS = orig
    },
    async () => {
      console.log('fork env option')
      const cp = fork(__filename, { env: { NODE_OPTIONS: `--require ${__filename} ${process.env.NODE_OPTIONS}` } })
      await once(cp, 'exit')
    },
  ]
  ;(async () => {
    for (const f of tests) {
      await f()
      console.log()
    }
  })()
}
```
</details>
<details>
<summary>Expected output</summary>

```
worker control

worker process.execArgv
preloaded

worker execArgv option
preloaded

worker process.env.NO
preloaded

worker SHARE_ENV
preloaded

worker env option
preloaded

fork control

fork process.execArgv
preloaded

fork execArgv option
preloaded

fork process.env.NO
preloaded

fork env option
preloaded
```
</details>

<details>
<summary>Actual output</summary>

```
worker control

worker process.execArgv

worker execArgv option
preloaded

worker process.env.NO

worker SHARE_ENV

worker env option
preloaded

fork control

fork process.execArgv
preloaded

fork execArgv option
preloaded

fork process.env.NO
preloaded

fork env option
preloaded
```
</details>

#### Running `node` with `--require` affects worker threads

Modify the test script to use the following test case

```js
async () => {
  console.log('worker control')
  const worker = new Worker(__filename)
  await once(worker, 'exit')
}
```

Then run the script with `node --require ./main.js main.js` outputs:
```
preloaded
worker control
preloaded
```

which shows the `--require` flag is respected in both the main thread and the worker thread

#### `--require` in `Worker` options is respected
When explicitly passing `execArgv` or `env.NODE_OPTIONS` to the `Worker` constructor options, the `--require` flag is respected:

```js
async () => {
  console.log('worker execArgv option')
  const worker = new Worker(__filename, { execArgv: ['--require', __filename, ...process.execArgv] })
  await once(worker, 'exit')
},
async () => {
  console.log('worker env option')
  const worker = new Worker(__filename, { env: { NODE_OPTIONS: `--require ${__filename} ${process.env.NODE_OPTIONS}` } })
  await once(worker, 'exit')
},
```
The above logs:
```
worker execArgv option
preloaded

worker env option
preloaded
```

#### `child_process.fork` respects `--require` in `process.execArgv` or `process.env.NODE_OPTIONS`

```js
const { fork } = require('child_process')

async () => {
  console.log('fork process.execArgv')
  const orig = process.execArgv
  process.execArgv = ['--require', __filename, ...process.execArgv]
  const cp = fork(__filename)
  await once(cp, 'exit')
  process.execArgv = orig
},
async () => {
  console.log('fork process.env.NO')
  const orig = process.env.NODE_OPTIONS
  process.env.NODE_OPTIONS = `--require ${__filename} ${process.env.NODE_OPTIONS}`
  const cp = fork(__filename)
  await once(cp, 'exit')
  process.env.NODE_OPTIONS = orig
},
```
The above logs:
```
fork process.execArgv
preloaded

fork process.env.NO
preloaded
```