Skip to content
This repository has been archived by the owner on Jul 6, 2019. It is now read-only.

Add return promise to the Module.runMain() branch. #172

Merged
merged 1 commit into from
Apr 12, 2018
Merged

Add return promise to the Module.runMain() branch. #172

merged 1 commit into from
Apr 12, 2018

Conversation

jdalton
Copy link
Contributor

@jdalton jdalton commented Apr 12, 2018

This PR adds an in-process opt-in to avoid defaulting to running in the same process as npx. Running in process causes the promise to resolve quicker and creates problems with packages that tie-in to process.on('exit') or call process.exit(). Related to npm/npm#20303.

Update:

I can also flip this so instead of opting-in to in-process the user could opt-in to child process.

Update:

Flipped to adding a --always-spawn option.

@jdalton
Copy link
Contributor Author

jdalton commented Apr 12, 2018

Any guidance on unit tests would be appreciated.

index.js Outdated
}
})
})
})
} else if (!existing && argv.nodeArg && argv.nodeArg.length) {
Copy link
Contributor Author

@jdalton jdalton Apr 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setImmediate use here is just to get it off the synchronous beforeExit event loop.
It could be a setTimeout of 0 or process.nextTick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I shifted to opting-in to running in the same process since that is prickly.

test/index.js Outdated
return child.spawn('node', [
NPX_ESC, '--quiet', 'echo-cli', 'hewwo'
], {stdio: 'pipe'}).then(res => {
t.equal(res.stdout.trim(), 'hewwo')
t.equal(res.stdout.trim(), isWindows ? '' : 'hewwo')
t.end()
Copy link
Contributor Author

@jdalton jdalton Apr 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any ideas on why the res.stdout is empty on Windows?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it shouldn't have been? /cc @noahleigh

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the switch to running in a child process in the current PR state has smth to do with it.

parse-args.js Outdated
@@ -208,6 +208,10 @@ function yargsParser (argv, defaultNpm) {
describe: Y()`Ignores existing binaries in $PATH, or in the local project. This forces npx to do a temporary install and use the latest version.`,
type: 'boolean'
})
.option('in-process', {
describe: Y()`Allow the command to be executed in the same process as npx instead of a child process.`,
type: 'boolean'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in re opt-in, I think this should default to true -- that way, it won't be a breaking change, and this has been part of npx for a while, so I'd rather not start spawning processes here.

Copy link
Contributor Author

@jdalton jdalton Apr 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about flipping the new option to being child which enforces the child process branch? I kind of dig that approach since the in-process option is more of a suggestion if it's doable (no nodeArg or shell or other stuff) where the child --always-spawn option is explicit and can happen 💯of the time.

test/index.js Outdated
return child.spawn('node', [
NPX_ESC, '--quiet', 'echo-cli', 'hewwo'
], {stdio: 'pipe'}).then(res => {
t.equal(res.stdout.trim(), 'hewwo')
t.equal(res.stdout.trim(), isWindows ? '' : 'hewwo')
t.end()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it shouldn't have been? /cc @noahleigh

Copy link
Owner

@zkat zkat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 nice. This will be useful, specially for libnpx users. This feature was definitely optimized for plain npx usage.

@zkat zkat merged commit c0d6abc into zkat:latest Apr 12, 2018
@jdalton
Copy link
Contributor Author

jdalton commented Apr 12, 2018

Thanks @zkat! Would you like a follow-up PR for a unit test?

@jdalton jdalton deleted the run-main branch April 12, 2018 17:57
@zkat
Copy link
Owner

zkat commented Apr 12, 2018

@jdalton If you want, give it a shot! -- but if it's too tricky to write a test for, don't worry about it. I mainly want to unblock you right now though :)

@noelleleigh
Copy link
Contributor

After pulling down these changes to my local repo on my Windows 10 machine, I tested it with:

node .\test\util\npx-bin.js --always-spawn echo-cli hewwo

After the packages were installed, it launched my text editor with the index.js file for echo-cli in the npx cache folder. hewwo was not echoed to my console.

npx/index.js

Line 291 in 13fea31

return child.runCommand(cmd, opts).catch(err => {

The cmd here is just a .js file with no mention of the node binary that lives in process.argv[0] to actually run it.

I assume this isn't the intended behavior?

@zkat
Copy link
Owner

zkat commented Apr 12, 2018

No that's not intended. Ohno. I'll try and fix it once I've got my laptop out again.

@zkat
Copy link
Owner

zkat commented Apr 12, 2018

actually I've no idea why this is happening, right now lol

@noelleleigh
Copy link
Contributor

@zkat
With my example, this condition doesn't get met:

npx/index.js

Line 273 in 13fea31

if (existing && argv.nodeArg && argv.nodeArg.length) {

Which means when it comes time to run a command in a new process:

npx/index.js

Line 291 in 13fea31

return child.runCommand(cmd, opts).catch(err => {

cmd and opts look like:

> cmd
"C:\Users\nleigh\AppData\Roaming\npm-cache\_npx\14100\node_modules\echo-cli\dist\index.js"

> opts
{
    ....
    "cmdOpts": ["hewwo"],
    ....
}

I think they should look like this:

> cmd
"C:\Program Files\nodejs\node.exe"

> opts
{
    ...
    "cmdOpts": [
        "C:\Users\nleigh\AppData\Roaming\npm-cache\_npx\14100\node_modules\echo-cli\dist\index.js",
        "hewwo"
    ],
    ....
}    

Which is what the code within that first condition block does (more or less)

@jdalton
Copy link
Contributor Author

jdalton commented Apr 12, 2018

@noahleigh Does #174 resolve the problem?

@noelleleigh
Copy link
Contributor

@jdalton After I apply the change I made in #173 , that PR works for me.

C:\Users\nleigh\dev\npx [pr/174 +1 ~1 -0 !]> node .\test\util\npx-bin.js --always-spawn echo-cli hewwo
npx: installed 47 in 3.353s
hewwo

iarna added a commit to npm/npm that referenced this pull request Apr 12, 2018
add --always-spawn to opt out of process takeover optimization feature

Credit: @jdalton
PR-URL: zkat/npx#172
iarna added a commit to npm/npm that referenced this pull request Apr 12, 2018
add --always-spawn to opt out of process takeover optimization feature

Credit: @jdalton
PR-URL: zkat/npx#172
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants