Use NPM packages as the building blocks of your application. Having separate packages is a little bit more of work but:
- Force us to have clear interfaces
- Having packages that can run independently makes them easier to test
- Easier to refactor because of the clear dependencies
Each package is a building block. Each of them works independently of the rest. Each of them can be tested in an isolated environment.
- Simple blocks:
- Composition blocks:
- Functionality blocks:
- Utilities blocks:
- Whole apps:
We have TONS of packages. Is there a way to manage them? Monorepos to the rescue.
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
npm install -g lerna
Lerna is a tool to manage one Git repo with multiple NPM packages. The alternative, using one repository per NPM package…
- Harder to document and maintain: Difficult to know after a few years what packages are in use and which ones are deprecated
- Easier to refactor because you can commit across packages
- Tons of places where to open merge requests, issues etc.
I created a repository that contains scoped
In lerna, the packages are stored on
packages/ folder. This is how it looks:
And each package is an independent NPM module.
❯ cat Loginform/package.json
The packages are written with js ECMA stage-2 and they are transpiled on a build process. The packages can be tested independently with jest+ex
Test Suites: 8 failed, 7 passed, 15 total
Lerna has three different steps:
lerna bootstrap. For each package, installs external dependencies and links sub-packages together. That means that the scoped packages
@grajalpresent in the repo will be symlinked on the
node_modules/@grajal/instead of installed. Ex. import(‘@grajal/ui-text’) -> import(‘../../ui-text’)
- lerna run [command]. Runs npm run [command] on each package. Big lerna users like Babel, Jest, React etc dont really use this command because it is faster to run global build scripts than spawning 30 build scripts in parallel. Example: On the packages I created
lerna run buildwill run
npm run buildon all packages, transpiling the code and exporting it on
lerna run testWill run
npm run teston all packages
lerna publish. Publishes all packages to npm
The lerna managed NPM packages need to be published somewhere so they can be consumed by the applications. On my tests I installed a verdaccio server as a private local NPM repository. In a real environment we will publish our lerna packages directly to the company NPM package repository. By default verdaccio runs on port 4873.
You will need to create a user
npm adduser --registry http://localhost:4873
You will end up with something like
> cat ~/.npmrc
Create a new application with react-create-app.
Add a couple of building blocks:
@grajal/ui-loginformThis one allows the user to login and creates a localStorage key with the sessionID
@grajal/app-pictureratingThis is a React version of BB picture rating.
The app will display the loginform if the user is not logged in, and will display the picturerating app if the user is logged in.
- Initial setup is horrible
- I was not able to make NPM resolve dependencies of the demo app.
yarnwas able to install the packages without trouble