|
| 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. |
0 commit comments