Skip to content

Commit 820ffaf

Browse files
authored
Merge pull request #706 from izaera/issue-630
chore: add local-npm tool
2 parents b002f29 + 447d413 commit 820ffaf

File tree

5 files changed

+447
-0
lines changed

5 files changed

+447
-0
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module.exports = {
2323
'/maintenance/projects/js-toolkit/**/__fixtures__',
2424
'/maintenance/projects/senna/build',
2525
'/projects/amd-loader/build',
26+
'/projects/js-themes-toolkit/qa',
2627
'/projects/js-toolkit/qa',
2728
'/projects/js-toolkit/**/generators',
2829
'/projects/js-toolkit/**/lib',
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# @liferay/local-npm
2+
3+
`@liferay/local-npm` is a private package (internal to this monorepo) that
4+
provides a CLI tool for using local npm registries (like
5+
[Verdaccio](https://verdaccio.org/)) to publish local versions of development
6+
packages and be able to test them before the public release is made.
7+
8+
## Installation
9+
10+
Simply run `yarn link` inside the project's folder to make the `local-npm` CLI
11+
executable available in your system.
12+
13+
> 👀 Note that we don't publish versions of this package to the public npm
14+
> registry, so the only way to install it is to `yarn link` it.
15+
16+
## Usage
17+
18+
### How it works
19+
20+
The first thing you need to do to use this tool is to run a local npm registry.
21+
We recommend [Verdaccio](https://verdaccio.org), which can be installed using
22+
`npm`/`yarn` or your operating system's package managers (like `brew`,
23+
`pacman`, `chocolatey`, etc.).
24+
25+
Once that's done, you need to know that `npm` and `yarn` can be configured to
26+
use any registry different from the public ones, which are:
27+
28+
- https://registry.npmjs.org
29+
- https://registry.yarnpkg.com
30+
31+
This lets you (the user) put a proxy between your `npm`/`yarn` and the public
32+
registry. That proxy may contain packages you have published locally, which are
33+
not available to the rest of the world, because you didn't publish them to the
34+
public(https://www.npmjs.com/) registry.
35+
36+
Using a local registry will allow you to prepublish the packages we are
37+
modifying so that we can use them from `liferay-portal` or any other sample
38+
project as if they had been already released to the general public.
39+
40+
The advantages of this are:
41+
42+
1. Because you are using true packages, your sample projects will reproduce
43+
exactly the same configuration they will have when the packages are truly
44+
released to the public. This means, no more `yarn link`s or flaky
45+
`node_modules` folders due to them.
46+
2. Because you are using a local npm registry, you are not polluting the public
47+
registry with bogus or alpha versions.
48+
3. Since you are not publishing to the public registry, you may reuse the same
49+
version number for a given package as many times as you want.
50+
4. Because of 3, there's no need to use prerelease version numbers or anything
51+
like that, i.e., no more `-pre.0`. You can simply use the next version
52+
number you plan to release.
53+
5. Because of 4 it is less likely that you break dependencies in the
54+
`package.json` files, because you don't need to play with prerelease version
55+
numbers that can be updated wrongly when the final release is made.
56+
6. Given that you are using true version numbers, you can keep your range semver
57+
expressions (f.e.: `^1.0.0`) in your `package.json` files because they won't
58+
break as they do when you use prerelease numbers (remember that prerelease
59+
numbers don't match semver expressions in Node).
60+
7. Once you are done, or every time you want to reset the state of your local
61+
registry, you can delete all your prepublished local packages by simply
62+
removing them from Verdaccio's
63+
`storage`([docs](https://verdaccio.org/docs/cli/#default-storage-location))
64+
folder.
65+
66+
Note: The main con of using a local npm registry is the need to republish a new
67+
version each time you modify any package, making development & testing slower
68+
than simply `yarn link`. For cases where speed is needed, you may use `yarn link` but beware that you must know what you are doing because `yarn link` may
69+
completely break node's resolution algorithm as it diverts resolution of
70+
dependencies of linked packages to their own folder locations, which usually
71+
leads to unpredictable results.
72+
73+
You've been warned.
74+
75+
### How to use it
76+
77+
There are three commands:
78+
79+
1. `local-npm install`: this works like `yarn install` but it makes sure that
80+
the package is re-downloaded from the registry and written again to your
81+
`node_modules` folder. On the contrary, `yarn` doesn't do this unless you
82+
change the dependency version number or remove `yarn.lock` and
83+
`node_modules`.
84+
2. `local-npm publish`: this is like `npm publish` but it makes sure you are
85+
publishing to your local registry only and overwrites any published package
86+
with the same name and version.
87+
3. `local-npm registry`: this has two subcommands for querying (`get`) the
88+
active registry, or setting (`set`) it to `local` or `public`.
89+
90+
Usually you will always have `npm`/`yarn` pointing to your local registry. This
91+
is because Verdaccio acts as a proxy of the public registry so, if you request
92+
anything it doesn't have, it will download it, cache it and serve it.
93+
94+
This has the benefit that you don't need to switch between local and public
95+
registries whenever you use third party packages and you will have a local
96+
mirror of the public `npm` registry which will let you develop even when
97+
offline (this is not a wanted feature of the setup, but a nice side effect).
98+
99+
The only moments when you need to switch back to using the public registry are:
100+
101+
1. If you are going to update a `yarn.lock` file that you will commit to
102+
upstream.
103+
2. If you want to make sure that a public release has worked.
104+
105+
#### Case 1
106+
107+
Case 1 will usually happen at the end of a pull request preparation. Whenever
108+
we change dependencies in `liferay-frontend-projects`, we must run `yarn install` so that `yarn.lock` is updated and we can commit the modified version.
109+
110+
However, `yarn.lock` files hold information about the registry from where the
111+
packages are downloaded. If you run `yarn install` when your machine is
112+
pointing to your local registry, the `yarn.lock` files will have references to
113+
`localhost` instead of `registry.npmjs.org`, and those will fail in other
114+
machines.
115+
116+
For that reason, the recommended action to take when you finish preparing your
117+
pull request are:
118+
119+
1. Run `git checkout yarn.lock` to restore it to `master`'s state
120+
2. Run `local-npm registry set public` to point `npm` and `yarn` to the public
121+
registry.
122+
3. Run `yarn install` to update `yarn.lock`
123+
4. Run `local-npm registry set local` to restore your local registry.
124+
125+
In the event that you forget to follow these steps or commit a `yarn.lock` file
126+
with references to `localhost` there's no need for drama (though you can make
127+
drama of it if you like; it's OK) because our CI build will catch the error and
128+
tell you that your commited `yarn.lock` is incorrect.
129+
130+
In that case, simply fix it, force push the `yarn.lock` commit, and continue
131+
with you beautiful life.
132+
133+
#### Case 2
134+
135+
Case 2 would arise after merging the PR and releasing your work to the public.
136+
In that moment, if you want to make sure that everything is correct and people
137+
outside won't have any problem, you may point to the `public` registry and do
138+
whatever tests you need.
139+
140+
This is more of a QA thing than something you do during development but because
141+
sometimes you need to make sure that you've released the correct thing, it is
142+
documented here.
143+
144+
Remember to point to your `local` registry again once you are finished!
145+
146+
## Example
147+
148+
Perico is a developer that is planning to fix something in the
149+
[portal-base](https://github.com/liferay/liferay-frontend-projects/tree/f6a283e2e13123d7cba4384f409ff74b0067d009/projects/js-toolkit/packages/portal-base)
150+
project.
151+
152+
This project is a dependency of
153+
[target-platforms](https://github.com/liferay/liferay-frontend-projects/tree/f6a283e2e13123d7cba4384f409ff74b0067d009/target-platforms/packages)
154+
which are usually a dependency of projects generated with the JS Toolkit.
155+
156+
Perico has two options:
157+
158+
1. Use `yarn link` on every test project he generates to see how `portal-base`
159+
behaves and cross his fingers.
160+
2. Use `local-npm` to publish local version of `portal-base` and forget about
161+
it.
162+
163+
Perico is a smart guy so he chooses 2. The development workflow would go like
164+
this:
165+
166+
1. Fix `portal-base`
167+
2. Run `local-npm publish` inside `portal-base`, which pushes a new version of
168+
that package to the local npm registry.
169+
3. Run `liferay new test-project` to generate a test project that will use
170+
`portal-base` to build.
171+
4. Run `yarn install` in `test-project`, which will download the package
172+
published in step 2 from the local registry (Perico could check this by
173+
looking at the `yarn.lock` file, for example, or by looking for his change
174+
inside `node_modules`).
175+
5. Build `test-project` and see if the issue was fixed.
176+
177+
If it ain't fixed, Perico would just need to:
178+
179+
1. Modify `portal-base`
180+
2. Run `local-npm publish` inside `portal-base`, which pushes a new version of
181+
that package to the local npm registry.
182+
3. Run `local-npm install portal-base` in `test-project`, which will redownload
183+
the package.
184+
4. Build `test-project` and see if the issue was fixed.
185+
186+
And repeat this 4 steps over and over until everything is correct. Note that
187+
Perico could even iterate this cycle to add `console.log` traces or any other
188+
diagnostic code and see it work in the test project.
189+
190+
Once everything is fixed, Perico prepares the PR, and sends it to GH.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
5+
* SPDX-License-Identifier: MIT
6+
*/
7+
8+
const yargs = require('yargs');
9+
10+
const index = require('../lib/index');
11+
12+
const {argv} = yargs
13+
.command(
14+
['install <package name>', 'i'],
15+
'Force reinstallation of given package in current project'
16+
)
17+
.command(
18+
['publish [<projects>...]', 'p'],
19+
'Publish current project or a list of projects to the local registry'
20+
)
21+
.command(
22+
['registry', 'r'],
23+
'Set/get the current npm and yarn configured registries',
24+
(yargs) =>
25+
yargs
26+
.command(['get', 'g'], 'Print current npm/yarn registry')
27+
.command(
28+
['set', 's'],
29+
'Set the npm/yarn repo to use',
30+
(yargs) =>
31+
yargs
32+
.command(
33+
['local', 'l'],
34+
'Use local npm/yarn registry'
35+
)
36+
.command(
37+
['public', 'p'],
38+
'Use public npm/yarn registry'
39+
)
40+
.demandCommand()
41+
)
42+
.demandCommand()
43+
)
44+
.demandCommand()
45+
.help();
46+
47+
index(argv);

0 commit comments

Comments
 (0)