lerna: `lerna bootstrap` v3.4.3 no longer sets `process.env.npm_package_engines_*`...

hey there 👋

i have a monorepo that i use to manage a handful of vscode extensions. i have scripts set up like so:

in my top-level package.json file:

"private": true,
"scripts": {
    "postinstall": "npm run bootstrap",
    "bootstrap": "lerna bootstrap",
    ...
},
"devDependencies": {
    "vscode": "^1.1.21",
    ...
}

then each of my packages use a package.json like:

"private": true,
"scripts": {
    "postinstall": "node ../../node_modules/vscode/bin/install",
    ...
},
"engines": {
    "vscode": "^1.23.0",
    ...
}

the vscode/bin/install program expects to find a value for process.env.npm_package_engines_vscode (source) but when i run npm i at the top-level of my monorepo, i get:

Error installing vscode.d.ts: Missing VSCode engine declaration in package.json.

inspecting process.env, i see:

INIT_CWD: '/path/to/my-repo',
PWD: '/path/to/my-repo/packages/myext-vscode-core',
npm_package_name: 'myext-vscode-core',
...

but no trace of anything using the npm_package_engines_ prefix.

when i cd ./packages/myext-vscode-core then run npm i and inspect process.env there, i see:

INIT_CWD: '/path/to/my-repo/packages/myext-vscode-core',
PWD: '/path/to/my-repo/packages/myext-vscode-core',
npm_package_name: 'myext-vscode-core',
npm_package_engines_vscode: '^1.23.0',
...

which is to say: env vars using the npm_package_engines_ prefix are available.

all of this worked fine under lerna v2.11.0 - running npm i at the top-level executed my bootstrap script which in turn ran my packages’ postinstall scripts without issue. i never saw the Missing VSCode engine error.

Executable Version
lerna --version 3.4.3
npm --version 5.10.0
yarn --version N/A
node --version 8.12.0
OS Version
macOS High Sierra 10.13.6

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 17 (7 by maintainers)

Most upvoted comments

Thanks for being patient with me. 😃

On further reflection, I had a hunch it might be related to the use of npm-lifecycle, which we now use instead of allowing the subprocess npm install to run the scripts. (Spoilers: yes, but not where I expected)

At first, I thought it was a bug in the library, but just now I read the source, and npm-lifecycle is indeed creating those env vars (instead of what I dreaded, something leftover in the npm CLI). So it’s an issue with the pkg parameter (data in the makeEnv() function).

Turns out the pkg we are passing in is an internal Package instance, not the actual package.json’s JSON object. And instances of that class have a lot of non-enumerable fields and such.

So you’re totally right, this is our bug, and I’mma fix it. Thanks for your persistence!

Published in v3.9.0

Thanks for being patient with me

likewise 🙏 👍

i can’t say it enough: super-big thanks for all the work you and your fellow maintainers do here ❤️

to be clear, you don’t owe me anything. i’m not entitled to your free labor. i’m thankful that this helpful tool has been made freely available to me and the broader community. further, as even just a casual observer i’ve been impressed by how successful you all have been lately in cleaning up some of the bit rot / legacy weirdness that had built up over the years here. i know how hard that work is so again, thank you 🙏

for my issue, there are likely a number of work-arounds i can explore - including simply sticking w/ v2 for now. i’d be interested in pointers on where i might dive in as well as learning more about the technical hurdles / risks around fixing my issue. naively, it seems since lerna run postinstall does the right thing, getting lerna bootstrap to do the same would be fairly straightforward but what do i know 🤷‍♂️

as to the notion that lerna bootstrap is legacy to be avoided and that my use-case is outside what lerna was designed for, i can’t help but quote from the README

Splitting up large codebases into separate independently versioned packages is extremely useful for code sharing. However, making changes across many repositories is messy and difficult to track, and testing across repositories gets complicated really fast.

this is exactly why i opted to use lerna and to date it has served me well 👍 more specifically, it allows me to share all my dev dependencies and test tooling (e.g. fixtures, linting, etc), as well as providing easy publishing and orchestration (via lerna run and lerna exec) of my packages which are versioned together. if there are specific gotchas / “you might have a bad time if” type things here, i (and i imagine most everyone) would appreciate seeing them called out.

What can Lerna do? The two primary commands in Lerna are lerna bootstrap and lerna publish. bootstrap will link dependencies in the repo together. publish will help publish any updated packages.

🤔🤷‍♂️

🙏 ❤️ 👍

@evocateur without using lerna bootstrap, how do you install package dependencies and link cross-dependencies?