Lerna Monorepo Mocha Setup (JavaScript)
In this article I show you how to setup a lerna JavaScript monorepo for testing with mocha (MochaJS).
Step 1. Install lerna and mocha globally
Install lerna and mocha globally using npm.
If you don’t have npm installed, click here.
- Open up a terminal window
- Run the following (the $ indicates that you are at a command line prompt – you should only type in what comes after the symbol):
$ npm install -g lerna mocha
Because the packages are installed globally, you won’t need to do this again for new projects.
Step 2. Create a monorepo project
- Change to a parent folder for all of your projects
- Create a new folder for a new lerna monorepo project:
$ mkdir lerna-javascript-example
$ cd lerna-javascript-example
Step 3. Decide how you want to handle versioning
There are two ways to handle package versioning in lerna:
- fixed – (the default) every package is published with the same version
- for fixed versioning you would initialize with
lerna init
- for fixed versioning you would initialize with
- independent – packages are published independently with their own version
- for independent versioning you would initialize with
lerna init --independent
- for independent versioning you would initialize with
The focus of this article is on testing and not publishing. So for this example you can just go with the default (fixed).
- Initialize lerna:
$ lerna init
$ npm install
- Verify that the following files and folders are listed:
lerna.json
node_modules
package-lock.json
package.json
packages
Step 4. Create a .gitignore file
- Create a new file called .gitignore
- On a Mac you can use this command:
$ touch .gitignore
- Open .gitignore in a text editor
- Paste the following into the file and save it:
node_modules/
lerna-debug.log
npm-debug.log
Step 5. Create a package
- Create a new package:
$ lerna create demo-tools
- Fill in the details (replace @mitchallen with your npm scope, if any):
package name: (demo-tools) @mitchallen/demo-tools
version: (0.0.0)
description: Demo tools module
keywords: demo
homepage:
license: (ISC)
entry point: (lib/demo-tools.js)
git repository:
You should see a message about a new packages folder and package.json file.
The path for the json file should be something like this:
- lerna-javascript-example/packages/demo-tools/package.json
The contents should be echoed to the console and look something like this:
{
"name": "@mitchallen/demo-tools",
"version": "0.0.0",
"description": "Demo tools module",
"keywords": [
"demo"
],
"author": "Mitch Allen <...>",
"homepage": "",
"license": "ISC",
"main": "lib/demo-tools.js",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1"
}
}
- Confirm when prompted
This article doesn’t cover publishing. But if you are planning to publish the package at some point, be sure to add a publishConfig section to package.json in the package folder.
For example:
"publishConfig": {
"access": "public"
},
Step 6. Create the library
- Replace the code in packages/demo-tools/lib/demo-tools.js with the following and save it:
"use strict";
module.exports = {
add: (a,b) => a + b,
subtract: (a,b) => a - b
};
It’s a simple module that has two functions:
- add – returns the addition of two arguments
- subtract – returns the subtraction of one argument from another
Step 7. Add a test script to the package
- Add this to the scripts section of the demo-tools package.json file:
"scripts": {
"test": "mocha __tests__/*.test.js"
}
- Remember to add this script whenever you add a new package
Step 8. Write the demo-tools test cases
- Edit packages/demo-tools/__tests__/demo-tools.test.js
- Replace all code in the file with the following and save it:
'use strict';
var assert = require('assert');
const demoTools = require('..');
describe('demo-tools', function () {
context('smoke test', function () {
it('add should add two numbers together', function (done) {
assert.strictEqual(demoTools.add(100,200),300);
done();
});
it('subtract should subtract one number from another', function (done) {
assert.strictEqual(demoTools.subtract(100,200),-100);
done();
});
});
});
Step 9. Run the tests
Run the tests with the following command:
$ lerna run test
You should see the mocha test results for your package.
When you have more than one package, the command will run all test scripts in all packages.
Step 10. Add a second package
Add a second package called demo-main, just like you did for the first package:
$ lerna create demo-main
- Replace the code in packages/demo-main/lib/demo-main.js with the following (replace YOUR-SCOPE in the require statement with your npm scope (in my case that would be
@mitchallen
)):
"use strict";
var tools = require('@YOUR-SCOPE/demo-tools');
module.exports = demoMain;
function demoMain(a,b,c) {
// return a + b - c
return tools.subtract(tools.add(a,b),c);
}
The code uses functions from the demo-tools library to calculate and return a value.
This is to prove that the demo-main package can require (import) the tools package using the lerna framework.
But first you need to add a dependency.
Step 11. Add a dependency
For the code to work, you have to use lerna to add the tools package as a dependency for the main package.
- To create a dependency, you would run a command like this:
lerna add @YOUR-SCOPE/LIBRARY --scope=@YOUR-SCOPE/PACKAGE
- Substitite YOUR-SCOPE with your npm scope
- Substitute LIBRARY with the name of the library that the package needs
- Substitute PACKAGE with the name of the package that needs to use the library
Here is an example:
- Run this command (substitute
mitchallen
with your npm scope):
$ lerna add @mitchallen/demo-tools --scope=@mitchallen/demo-main
- Verify that the dependency was added to the package.json for demo-main:
"dependencies": {
"@mitchallen/demo-tools": "^0.0.0"
}
- Your scope in the dependency should be different from mine
Step 12. Write the demo-main test cases
- Edit packages/demo-main/__tests__/demo-main.test.js
- Replace all code in the file with the following and save the file:
"use strict";
var assert = require('assert');
const demoMain = require('..');
describe('demo-main', function () {
context('smoke test', function () {
it('should add first two numbers and subtract the third', function (done) {
const a = 100, b = 200, c = 50;
const expected = a + b - c;
assert.strictEqual(demoMain( a, b, c ), expected );
done();
});
});
});
- Add a test script to the child packages package.json file and save it:
"scripts": {
"test": "mocha __tests__/*.test.js"
},
Step 13. Run all the tests
Run all the tests like you did before with:
$ lerna run test
You should see results for both packages.
Run tests for just one package
To run the tests for just one package, use the scope command (substitute my scope for your scope):
$ lerna run test --scope @mitchallen/demo-tools
If you are in a packages folder, you can also run the tests like this:
$ npm test
Once everything passes, you have the option to publish to npm or a private repo. But that’s beyond the scope of this article.
Troubleshooting
No rights to install lerna globally
- On a Mac or Linux, try putting
sudo
in front of the command
Get the Error: run tests from root
- This actually might mean that you forgot to add the test script for a package
Conclusion
In this article you learned how to:
- Setup a lerna JavaScript monorepo for testing using mocha (MochaJS)
- Add multiple packages
- Add mocha for testing
- Create dependencies between packages without the need for linking or publishing
Related Articles
References
- Lerna – A tool for managing JavaScript projects with multiple packages [1]