Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lerna bootstrap does not link local dependencies?

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.

Expected Behavior

As per the lerna bootstrap documentation:

  1. 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).

Current Behavior

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)

Steps to Reproduce

  1. Create the folder structure below
  2. Copy the files inlined to their corresponding directory
  3. Execute $ 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"
}

Observation

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.

Remark

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.

Environment

  • lerna --version 3.18.4
  • npm --version 6.11.3
  • yarn --version 1.19.1
  • node --version v12.12.0
  • macOS Mojave 10.14.6
like image 655
matsev Avatar asked Nov 18 '19 15:11

matsev


People also ask

What does NPX lerna bootstrap do?

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.

What does lerna link do?

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.


1 Answers

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

like image 121
kitimenpolku Avatar answered Sep 23 '22 22:09

kitimenpolku