developing and publishing multiple packages

{
"name": "currency-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x"
}
}{
"name": "currency-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x"
}
}{
"name": "address-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x"
}
}{
"name": "awesome-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"material-ui": "1.x"
}
}npm publish awesome-input
npm install awesome-input
{
"name": "currency-input",
"version": "1.1.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x",
"awesome-input": "1.0.0"
}
}{
"name": "address-input",
"version": "1.1.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x",
"awesome-input": "1.0.0"
}
}npm publish currency-input address-input
{
"name": "currency-input",
"version": "1.1.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x",
"awesome-input": "1.0.0"
}
}{
"name": "address-input",
"version": "1.1.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"meow": "2.x",
"awesome-input": "1.0.0"
}
}{
"name": "awesome-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"material-ui": "1.x"
}
}
awesome-input not awesome anymore

awesome-input
1. Fix Bug
2. Unit Test
3. npm publish awesome-input@1.0.1
address-input
1. npm install awesome-input@1.0.1
2. Verify Fix
3. npm publish address-input@1.1.1
currency-input
1. npm install awesome-input@1.0.1
2. Verify Fix
3. npm publish currency-input@1.1.1

{
"name": "email-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"email-validator": "4.x",
"awesome-input": "1.1.0"
}
}{
"name": "awesome-input",
"version": "1.1.0",
"dependencies": {
"react": "16.x",
"material-ui": "1.x"
}
}awesome-input
1. Add new feature
2. Unit Test
3. npm publish awesome-input@1.1.0
email-input
1. npm install awesome-input@1.1.0
2. Integrate awesome-input
3. Unit Test
4. npm publish email-input@1.0.0
address-input
1. npm install awesome-input@1.1.0
2. Integrate awesome-input
3. Unit Test
4. npm publish address-input@1.2.0
currency-input
1. npm install awesome-input@1.0.1
2. Integrate awesome-input
3. Unit Test AND FOUND A BUG, SHIT!
awesome-input
1. Fix Bug
2. Unit Test
3. npm publish awesome-input@1.1.1
email-input
1. npm install awesome-input@1.1.1
2. Unit Test
3. npm publish email-input@1.0.1
address-input
1. npm install awesome-input@1.1.1
2. Unit Test
3. npm publish address-input@1.2.1
currency-input
1. npm install awesome-input@1.1.1
2. Integrate awesome-input
3. Unit Test AND GREAT, NO BUG!
4. npm publish currency-input@1.2.1

npm link

node_modules

email-input
awesome-input


node_modules

address-input
awesome-input


node_modules

currency-input
awesome-input


awesome-input
symlink
{
"name": "awesome-design",
"version": "1.0.0",
"dependencies": {
"email-input": "1.0.1",
"address-input": "1.2.1",
"currency-input": "1.2.1"
}
}import EmailInput from 'email-input';
import AddressInput from 'address-input';
import CurrencyInput from 'currency-input';
export { EmailInput, AddressInput, CurrencyInput };import { EmailInput } from 'awesome-design';
awesome-design/index.js
user-feature/index.js

MANAGING MULTIPLE PACKAGES IS HARD
FIXING 1 PACKAGE HAS CHAIN EFFECT ON MULTIPLE PACKAGES
{
"name": "email-input",
"version": "1.0.0",
"dependencies": {
"react": "16.x",
"lodash": "3.x",
"email-validator": "4.x",
"awesome-input": "^1.1.0"
}
}SEQUENCE IS IMPORTANT
GIT

MORE GIT REPOS MAKE YOUR GITHUB PROFILE LOOK MORE IMPRESSIVE

shawn / awesome-input




git submodule

email-input

address-input

currency-input

awesome-design

email-input

address-input

currency-input

awesome-design
import EmailInput from './email-input/src/index.js';
import AddressInput from './address-input/src/index.js';
import CurrencyInput from './currency-input/src/index.js';
class AwesomeDesignDemo extends React.Component {
render() {
return (
<Demo>
<EmailInput />
<AddressInput />
<CurrencyInput />
</Demo>
);
}
}
awesome-design/demo.js


monorepo


QUESTIONS?


101
lerna.json
{
"packages": [
"widgets/*",
"utils/*"
],
"npmClient": "yarn"
}
https://en.wikipedia.org/wiki/Glob_(programming)

email-input

widgets
lerna.json

address-input

awesome-design

package.json

package.json


currency-util

utils

test
package.json


docs

__mocks__

email-input

widgets
lerna.json

address-input

awesome-design

package.json

package.json


currency-util

utils

test
package.json


docs

__mocks__
@shawn/email-input
@shawn/address-input
@shawn/currency-util
...
lerna list

lerna bootstrap
if dependency not in lerna project:
npm install
else if dependency version satisfy the local version in lerna project:
symlink local copy to node_modules
else:
npm install
lerna bootstrap

email-input

widgets
lerna.json

awesome-input

awesome-design

package.json

package.json


email-util

utils
package.json

node_modules

{
"name": "@shawn/email-input",
"dependencies": {
"awesome-input": "^0.5.0",
"email-util": "^0.6.0",
"react": "16.3.0"
}
}
widgets/email-input/package.json
{
"name": "@shawn/awesome-input",
"version": "0.5.5"
}
widgets/awesome-input/package.json
{
"name": "@shawn/email-input",
"version": "0.9.1"
}
widgets/email-util/package.json

awesome-input

email-input

react

email-input

widgets
lerna.json

awesome-input

awesome-design

package.json

package.json


email-util

utils
package.json

node_modules

{
"name": "@shawn/email-input",
"dependencies": {
"awesome-input": "^0.5.0",
"email-util": "^0.6.0",
"react": "16.3.0"
}
}
widgets/email-input/package.json
{
"name": "@shawn/awesome-input",
"version": "0.5.5"
}
widgets/awesome-input/package.json
{
"name": "@shawn/email-input",
"version": "0.9.1"
}
widgets/email-util/package.json

awesome-input

email-input (from npm)

react (from npm)
lerna link
if dependency not in lerna project:
npm install
else:
symlink local copy to node_modules
lerna link

email-input

widgets
lerna.json

awesome-input

awesome-design

package.json

package.json


email-util

utils
package.json

node_modules

{
"name": "@shawn/email-input",
"dependencies": {
"awesome-input": "^0.5.0",
"email-util": "^0.6.0",
"react": "16.3.0"
}
}
widgets/email-input/package.json
{
"name": "@shawn/awesome-input",
"version": "0.5.5"
}
widgets/awesome-input/package.json
{
"name": "@shawn/email-input",
"version": "0.9.1"
}
widgets/email-util/package.json

awesome-input

email-input

react (from npm)
scope
--scope=email-autocomplete

--scope=email-*

--ignore=email-autocomplete

--scope=email-autocomplete
--include-filtered-dependencies

--scope=email-autocomplete
--include-filtered-dependents

--since=[git-ref]


QUESTIONS?

102
lerna publish
lerna diff
lerna changed
lerna version
lerna publish
git tag



lerna diff
= git diff v1.0.0

lerna diff @shawn/email-input
git diff v1.0.0 ./widgets/email-input

lerna changed
lerna version
lerna publish
lerna
changed
show changes since last git tag
lerna
version
lerna
publish
update version,
git commit, git tag,
git push
npm publish








lerna info Looking for changed packages since v1.0.0
@shawn/awesome-input
@shawn/currency-input
@shawn/email-input
@shawn/address-input
@shawn/awesome-design
lerna success found 5 package ready to publish
lerna changed
lerna info Looking for changed packages since v1.0.0
...
? Select a new version for @shawn/awesome-input (currently 1.0.0) Minor (1.1.0)
...
Changes:
- @shawn/awesome-input: 1.0.0 => 1.1.0
- @shawn/currency-input: 1.0.0 => 1.1.0
- @shawn/email-input: 1.0.0 => 1.1.0
- @shawn/address-input: 1.0.0 => 1.1.0
- @shawn/awesome-design: 1.0.0 => 1.1.0
? Are you sure you want to create these versions? (ynH)
lerna version

...
- @shawn/awesome-design: 1.0.0 => 1.1.0
? Are you sure you want to create these versions? Yes
lerna info publish Publishing packages to npm...
Successfully published:
- @shawn/awesome-input@1.1.0
- @shawn/currency-input@1.1.0
- @shawn/email-input@1.1.0
- @shawn/address-input@1.1.0
- @shawn/awesome-design@1.1.0
lerna publish


103




lerna run
lerna exec
lerna run test
npm run test
in every package that has "test" npm script
lerna exec -- rm -rf src/
rm -rf src/
in every package
lerna run --stream
@shawn/awesome-input: yarn run v1.0.2
@shawn/awesomeness: yarn run v1.0.2
@shawn/happiness: yarn run v1.0.2
@shawn/debounce-utils: yarn run v1.0.2
@shawn/debounce-utils: jest
@shawn/happiness: jest
@shawn/awesomeness: yarn run v1.0.2
lerna run --parallel
lerna run --no-bail
lerna add
lerna-extras
https://confluence.garenanow.com/display/SPCFE/Lerna+Extras
lerna-extras bootstrap-here
lerna-extras
add-here
lerna-extras
diff-package-since <git-ref>
lerna-extras search
lerna-extras bootstrap-changed

lerna
By Li Hau Tan
lerna
- 961