Search code examples
npmyarnpkgyarn-workspaces

How to install an executable in yarn workspace that is specified in a package inside of it?


Following folder structure and files are given:

.
├── package.json
└── scripts
    ├── hello-word.js
    └── package.json
// package.json
{
  "name": "yarn-bin",
  "version": "1.0.0",
  "private": true,
  "license": "ISC",
  "workspaces": [
    "scripts"
  ]
}
// scripts/package.json
{
  "name": "@yarn-bin/scripts",
  "version": "1.0.0",
  "license": "ISC",
  "bin": {
    "hello-world": "./hello-world.js"
  }
}
// scripts/hello-world.js
#!/usr/bin/env -S npx node

console.log("Hello World")

This is a very simple yarn workspace setup where an executable is specified in a workspace package ("bin" in scripts/package.json). Executing ./hello-world.js works just fine (with prior chmod +x hello-world.js).

Question

Is it possible to install this executable in the workspace itself?

(To break it down: I would like to execute the script from anywhere in the workspace e.g. with npx hello-world)


Solution

  • Like I said in the comments what you got here is almost complete. You did have a typo in your file name but I assume that's a typo that happened while you copied this over to SO. I did change the hash bang to make sure you run this via node.

    You cannot run this via npx as npx will go online and look through the registry.

    .
    ├── package.json
    └── scripts
        ├── hello-world.js # not "hello-word.js"
        └── package.json
    

    Root package.json:

    {
      "name": "yarn-bin",
      "version": "1.0.0",
      "private": true,
      "license": "ISC",
      "scripts": {
        "hello": "yarn hello-world"
      },
      "workspaces": [
        "scripts"
      ]
    }
    

    scripts/package.json

    {
      "name": "@yarn-bin/scripts",
      "version": "1.0.0",
      "license": "ISC",
      "bin": {
        "hello-world": "./hello-world.js"
      }
    }
    

    And script/hello-world.js

    #!/usr/bin/env node
    
    console.log("Hello World")
    

    With that setup running yarn hello in the root folder will yield:

    $ yarn hello
    yarn run v1.22.10
    $ yarn hello-world
    $ /path/to/folder/node_modules/.bin/hello-world
    Hello World
    ✨  Done in 0.25s.
    

    While I added an npm script into the root package.json you can also execute bins via just running yarn hello-world anywhere from within your project.