What is the proper way of working with lerna and local dependencies?
I have configured two modules in a mono repo to use lerna with a local dependency. I expected that
$ lerna bootstrap
$ lerna run test
would be sufficient to download all external dependencies, link a local dependency and execute and pass all tests in all modules.
As per the lerna bootstrap documentation:
- Symlink together all Lerna packages that are dependencies of each other.
Thus, I expected that lerna bootstrap
would create a symlink in module-b/node_modules
below that points to module-a
(which then would allow the tests to be executed and pass).
No linking occurs, which cause the tests to fail:
lerna ERR! yarn run test exited 1 in 'module-b' lerna ERR! yarn run test stdout: yarn run v1.19.1 $ jest info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
lerna ERR! yarn run test stderr: FAIL ./import.test.js ● Test suite failed to run
Cannot find module 'module-a' from 'import.test.js' > 1 | const moduleA = require('module-a'); | ^ 2 | 3 | test('should import module-a', () => { 4 | moduleA(); at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:259:17) at Object.<anonymous> (import.test.js:1:1)
$ lerna bootstrap
followed by $ lerna run test
project-root
+ packages
| + module-a
| | + package.json
| | + index.js
| |
| + module-b
| | + package.json
| | + import.test.js
|
+ lerna.json
packages/module-a/package.json
{
"name": "module-a",
"version": "1.0.0",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Test passed in module-a\""
}
}
packages/module-a/index.js
module.exports = () => console.log('Log in module-a');
packages/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"private": true,
"main": "index.js",
"scripts": {
"test": "jest"
},
"dependencies": {
"module-a": "file:../module-a"
},
"devDependencies": {
"jest": "^24.9.0"
}
}
packages/module-b/import.test.js
const moduleA = require('module-a');
test('should import module-a', () => {
moduleA();
});
lerna.json
{
"npmClient": "yarn",
"packages": [
"packages/*"
],
"version": "independent"
}
Executing lerna link --force-local does not change status quo, the test still fails because the module-b/node_modules/
still does not contain a reference to module-a
.
I cannot use yarn workspaces together with lerna because module-b
is an Electron app and the electron builder expects its dependencies to be installed in the packages/module-b/node_modules/
folder.
Lerna's bootstrap command installs package dependencies and links the packages together. Without bootstrapping your packages, the package dependencies will not satisfy, and you won't be able to run any npm scripts across the project.
Lerna allows for installing and linking all the external/shared dependencies, also called bootstrapping, in the mono repo and creating symlinks to the shared dependency locations in the repo. Since it's symlink any update done in the shared dependency will immediately take effect in your code which is using it.
I have tried your implementation.
Using file:../module-a
in packages/module-b/package.json
does not work for me.
You can go around it easily by using writing a version number for module-a
(it does not matter which since we will force-local
)
{
"name": "module-b",
"version": "1.0.0",
"private": true,
"main": "index.js",
"scripts": {
"test": "jest"
},
"dependencies": {
"module-a": "1.0.0"
},
"devDependencies": {
"jest": "^24.9.0"
}
}
At the root of your project:
Bootstrap and link for local version:
npx lerna bootstrap --force-local
Run tests:
npx lerna run test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With