Yalc
Better workflow than npm | yarn link for package authors.
Why
When developing and authoring multiple packages (private or public), you often find yourself in need of using the latest/WIP versions in other projects that you are working on in your local environment without publishing those packages to the remote registry. NPM and Yarn address this issue with a similar approach of symlinked packages (npm/yarn link
). Though this may work in many cases, it often brings nasty constraints and problems with dependency resolution, symlink interoperability between file systems, etc.
What
yalc
acts as very simple local repository for your locally developed packages that you want to share across your local environment.- When you run
yalc publish
in the package directory, it grabs only files that should be published to NPM and puts them in a special global store (located, for example, in~/.yalc
). - When you run
yalc add my-package
in yourproject
it pulls package content into.yalc
in the current folder and injects afile:
/link:
dependency intopackage.json
. Alternatively, you may useyalc link my-package
which will create a symlink to the package content innode_modules
and will not touchpackage.json
(likenpm/yarn link
does), or you even may use it with Pnmp/Yarn/Npm workspaces. yalc
creates a specialyalc.lock
file in your project (similar toyarn.lock
andpackage-lock.json
) that is used to ensure consistency while performingyalc
's routines.yalc
can be used with projects whereyarn
ornpm
package managers are used for managingpackage.json
dependencies.
Installation
Using NPM:
npm i yalc -g
Using Yarn:
yarn global add yalc
Some documented features might not have been published yet, see the change log.
Usage
Publish
- Run
yalc publish
in your dependency packagemy-package
. - It will copy all the files that should be published in remote NPM registry.
- If your package has any of these lifecycle scripts:
prepublish
,prepare
,prepublishOnly
,prepack
,preyalcpublish
, they will run before in this order. If your package has any of these:postyalcpublish
,postpack
,publish
,postpublish
, they will run after in this order. Use--no-scripts
to publish without running scripts. - When publishing,
yalc
can optionally calculate a hash signature from the file contents and use the signature in the resulting packageversion
(like"1.2.3+ffffffff"
). To enable this, pass the--sig
option to theyalc publish
command. - You may also use
.yalcignore
to exclude files from publishing to yalc repo, for example, files like README.md, etc. --content
flag will show included files in the published package- NB! In terms of which files will be included in the package
yalc
fully supposed to emulate behavior ofnpm
client (npm pack
). If you have nested.yalc
folder in your package that you are going to publish withyalc
and you usepackage.json
files
list, it should be included there explicitly. - NB! Windows users should make sure the
LF
new line symbol is used in published sources; it may be needed for some packages to work correctly (for example,bin
scripts).yalc
won't convert line endings for you (becausenpm
andyarn
won't either). - NB! Note that, if you want to include
.yalc
folder in published package content, you should add!.yalc
line to.npmignore
. - Easily propagate package updates everywhere.
- Yalc by default resolve
workspace:
protocol in dependencies, to omit this use-no-workspace-resolve
flag
Add
- Run
yalc add my-package
in your dependent project, which will copy the current version from the store to your project's.yalc
folder and inject afile:.yalc/my-package
dependency intopackage.json
. - You may specify a particular version with
yalc add my-package@version
. This version will be fixed inyalc.lock
and will not affect newly published versions during updates. - Use the
--link
option to add alink:
dependency instead offile:
. - Use the
--dev
option to add yalc package to dev dependencies. - With
--pure
flag it will not touchpackage.json
file, nor it will touch modules folder, this is useful for example when working with Yarn workspaces (read below in Advanced usage section) - With
--workspace
(or-W
) it will add dependency with "workspace:" protocol.
Link
- As an alternative to
add
, you can use thelink
command which is similar tonpm/yarn link
, except that the symlink source will be not the global link directory but the local.yalc
folder of your project. - After
yalc
copies package content to.yalc
folder it will create a symlink:project/.yalc/my-package ==> project/node_modules/my-package
. It will not touchpackage.json
in this case.
Update
- Run
yalc update my-package
to update the latest version from store. - Run
yalc update
to update all the packages found inyalc.lock
. preyalc
andpostyalc
scripts will be executed in target package on add/update operations which are performed whilepush
- if need to perform pre/post
scripts
on update of particular package use(pre|post)yalc.package-name
name for script in yourpackage.json
. - update
--update
(--upgrade
,--up
) to run package managers's update command for packages.
Remove
- Run
yalc remove my-package
, it will remove package info frompackage.json
andyalc.lock
- Run
yalc remove --all
to remove all packages from project.
Installations
- Run
yalc installations clean my-package
to unpublish a package published withyalc publish
- Run
yalc installations show my-package
to show all packages to whichmy-package
has been installed.
Advanced usage
Pushing updates automatically to all installations
- When you run
yalc add|link|update
, the project's package locations are tracked and saved, soyalc
knows where each package in the store is being used in your local environment. yalc publish --push
will publish your package to the store and propagate all changes to existingyalc
package installations (this will actually doupdate
operation on the location).yalc push
- is a use shortcut command for push operation (which will likely become your primarily used command for publication):scripts
options isfalse
by default, so it won't runpre/post
scripts (may change this with passing--scripts
flag).- With
--changed
flag yalc will first check if package content has changed before publishing and pushing, it is a quick operation and may be useful for file watching scenarios with pushing on changes. - Use
--replace
option to force replacement of package content. - Use
preyalc
andpostyalc
(read inupdate
docs) to execute needed script on every push. - Use
--update
to runyarn/npm/pnpm update
command for pushed packages.
Keep it out of git
- If you are using
yalc'ed
modules temporarily during development, first add.yalc
andyalc.lock
to.gitignore
. - Use
yalc link
, that won't touchpackage.json
- If you use
yalc add
it will changepackage.json
, and adsfile:
/link:
dependencies, if you may want to useyalc check
in the precommit hook which will check package.json foryalc'ed
dependencies and exits with an error if you forgot to remove them.
Keep it in git
- You may want to keep shared
yalc'ed
stuff within the projects you are working on and treat it as a part of the project's codebase. This may really simplify management and usage of shared work in progress packages within your projects and help to make things consistent. So, then just do it, keep.yalc
folder andyalc.lock
in git. - Replace it with published versions from remote repository when ready.
- NB! - standard non-code files like
README
,LICENCE
etc. will be included also, so you may want to exclude them in.gitignore
with a line like**/.yalc/**/*.md
or you may use.yalcignore
not to include those files in package content.
Publish/push sub-projects
- Useful for monorepos (projects with multiple sub-projects/packages):
yalc publish some-project
will perform publish operation in the./some-project
directory relative toprocess.cwd()
Retreat and Restore
- Instead of completely removing package you may temporary set it back with
yalc retreat [--all]
for example before package publication to remote registry. - After or later restore it with
yalc restore
.
Use with Yarn/Pnpm workspaces
Use if you will try to add
repo in workspaces
enabled package, --pure
option will be used by default, so package.json
and modules folder will not be touched.
Then you add yalc'ed package folder to workspaces
in package.json
(you may just add .yalc/*
and .yalc/@*/*
patterns). While update
(or push
) operation, packages content will be updated automatically and yarn
will care about everything else.
If you want to override default pure behavior use --no-pure
flag.
Clean up installations file
- While working with yalc for some time on the dev machine you may face the situation when you have locations where you added yalc'ed packages being removed from file system, and this will cause some warning messages when yalc will try to push package to removed location. To get rid of such messages, there is an explicit command for this:
yalc installations clean [package]
.
Override default package store folder
- You may use
--store-folder
flag option to override default location for storing published packages.
Control output
- Use
--quiet
to fully disable output (except of errors). Use--no-colors
to disable colors.
Set default options via .yalcrc
- For example add
workspace-resolve=false
line to the.yalcrc
file to turn offworkspace:
protocol resolution orsig=false
to disable package version hash signature.
Related links
- yarn probably shouldn't cache packages resolved with a file path
- "yarn knit": a better "yarn link"
- npm-link-shared
- yarn link does not install package dependencies
- [npm] RFC: file: specifier changes
Licence
WTF.