berry: [Bug] SyntaxError when running a "bin" file that isn't authored in JS
- I’d be willing to implement a fix
Describe the bug
Yarn 2.0 fails with a SyntaxError
when running a bin
file that isn’t authored in JS. For example, the bin file may be an executable file with a shebang #!/usr/bin/env sh
.
Example bin
file:
#!/usr/bin/env sh
echo 'Hello world!'
To Reproduce
See sample package (@cameronhunter/berry-bin-bug
) that defines a bin
that is an executable file with a shebang.
const { promises: { writeFile, chmod } } = require('fs');
await writeFile('./hello-world', '#!/usr/bin/env sh\necho "Hello world!"');
await chmod('./hello-world', 0o765);
await packageJsonAndInstall({
bin: { 'hello-world': './hello-world' }
});
await expect(yarn('hello-world')).resolves.toContain('Hello world!');
Example of failure:
$ yarn berry-bin-bug
/Users/chunter/workspace/github/cameronhunter/berry-bin-bug/bin/berry-bin-bug:3
echo "Hello world!"
^^^^^^^^^^^^^^
SyntaxError: Unexpected string
at Module._compile (internal/modules/cjs/loader.js:895:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.module_1.Module._load (/Users/chunter/workspace/github/cameronhunter/berry-bin-bug/.pnp.js:13519:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
at internal/main/run_main_module.js:17:11
Environment if relevant (please complete the following information):
- OS: MacOS Mojave (
10.14.5
) - Node version:
12.14.0
- Yarn version:
2.0.0-rc.28
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 35
- Comments: 23 (4 by maintainers)
Commits related to this issue
- chore: fix tmex call see https://github.com/yarnpkg/berry/issues/882#issuecomment-1209694606 — committed to owid/owid-grapher by marcelgerber 2 years ago
- chore: fix tmex call see https://github.com/yarnpkg/berry/issues/882#issuecomment-1209694606 — committed to owid/owid-grapher by marcelgerber 2 years ago
Thanks for your response, @arcanis. Cross-platform isn’t a goal for many of our (internal) tools so it’s a shame that we have to spin up node to execute a shebang executable. I can certainly work around this using your suggestion though.
Perhaps this ticket could be changed to focus on improving the error message so that other users don’t fall into the same confusion.
Side-question: Is cross-platform portability a goal of berry or is it more the implementation detail of not being able to run them from zip archives?
In my opinion native binaries should be supported, at least on unplugged packages. Someone should step in, implement and maintain this feature - yes, of course. At least it should not be viewed as wont fix.
Some NPM packages (e.g., https://www.npmjs.com/package/elm) are meant to provide a native binary executable for various platforms and expose it so that it can be found via PATH when run from a script specified in package.json (often indirectly, e.g., via a specific loader for webpack). These packages cannot be used with Yarn Berry, even with
yarn unplug
(or even without Plug’n’Play altogether).Can Yarn provide a configuration option to skip the shell script shim for a particular executable?
Hello! This thread has been discussing two separate issues.
bin
entries should be able to point to native binaries; we finally fixed this today in: #5508 🎉bin
entries should be able to point to non-JS shebang scripts; this is still not possible at the moment.It’s a little difficult to follow the thread with those two separate issues kept together, so I think it’s best to keep it archived. However, since the second use case is not resolved yet (a
bin
entry pointing to a non-JS shebang script), if you would still benefit from it, please feel free to open a new thread and reference this one.Another reason why I’d like another thread to be opened is to assess how important is this use case in practice. While supporting native binaries were clearly high value (I’m aware of a couple of packages who had to make workarounds for Yarn), I’m not quite convinced the same is true for non-JS shebang scripts. We had some internal debates, and settling them would benefit from having clear example of semi-popular packages using such patterns - so far, we don’t have any in mind, hence why we’d need your help.
Is there away to run TypeScript
bin
files?I used
as shebang with
in the
package.json
. Withyarn 1.0
workspace setup I could then simply executeyarn my-script
and it worked just fine. I wanted to migrate toyarn 3.0.2
, but there it’s not working anymore…Surely I could compile the script to JS first, but it was a quite nice developer experience to just execute the TS file without having a build step always in between…
btw, this worked in yarn v1 too
Hi, I encountered a similar problem now. I installed the
ngrok
npm package via yarn, and whileyarn ngrok
worked in previous versions, it crashes with PnP:I also tried
yarn run ngrok
oryarn exec ngrok
.However, I found a workaround here: https://github.com/evanw/esbuild/issues/237#issuecomment-655265240
Running
$(yarn bin ngrok)
works. So I created a script inpackage.json
:Now the
yarn ngrok
works correctly 🙂 Hope it helps somebody.I agree with @ti1024. More and more packages are providing native binaries (Rust, Go), and not having these work via Yarn is a huge problem IMO.
What if yarn inspected the
os
,cpus
, etc fields inpackage.json
and inferred compatibility through that? This seems to be top of mind since Yarn 3.2 adds support forlibc
field. https://dev.to/arcanis/yarn-32-libc-yarn-explain-next-major--o22Hi, as indicated in mklement0/ttab#52,
ttab
package is affected as well, as it’s based on a#!/usr/bin/env bash
shebang (https://github.com/mklement0/ttab/blob/master/bin/ttab#L1-L5).@rtrembecky’s workaround
$(yarn bin ttab)
works well on my Mac, thanks!FYI, I even run yarn 4 workspaces command for my mono-repo like this:
I found a workaround though. If I define my script like this, it will execute correctly: