@omnidev/knit v0.1.2
🧶 Knit
⚠️ WARNING: This project was recently forked, and I have plans to significantly diverge from and improve upon the original project. Please bear with me while I familiarize myself with the codebase and upgrade the dependencies and engineering processes (CI, etc.). There is no published package yet. Please use the original project, yalc, in the meantime.
Streamline your local Node.js package dependency workflow.
Knit is a fork of yalc, which was created by @wclr. The name is inspired by this GitHub thread.
Overview
knit is a CLI with a local repository designed to mirror a remote package repository, such as npm. It allows you to publish packages from a local project folder to a local store, and install them in other local projects. It also allows you to easily propagate package updates.
knit can be used with projects where package managers, such as npm, yarn, or pnpm, are used
for managing package.json dependencies. knit creates a knit.lock file in your project (similar to yarn.lock and package-lock.json) that is used to ensure consistency while performing knit routines.
Quick Start
Install locally in a project (replace yarn with your preferred package manager):
yarn add -D @omnidev/knitOr execute it directly and ephemerally with yarn dlx:
yarn dlx @omnidev/knit [...]Key Commands
knit publish: publish a package to a local store (~/.knitby default)- Only publishes files that would be published to a remote repository
knit add $PACKAGE_NAME: add a package from the store to a project- Pulls package content into
$PROJECT_DIR/.knit/and injects a relative local (file:/link:depending on usage) dependency intopackage.json - Alternatively, use
knit link $PACKAGE_NAMEwhich creates a symlink innode_modulesto the package content, and will not modifypackage.json(likenpm/yarn linkdoes), or you even may use it withnpm/yarn/pnpmworkspaces
- Pulls package content into
knit helpfor help
Usage
Publish (knit publish)
Run in a project to publish it to the store.
- Copies all the files that should be published to a remote registry
If your package has any of these lifecycle scripts, then will run before publishing, in the following order:
prepublishprepareprepublishOnlyprepackpreknitpublish
If your package has any of these lifecycle scripts, they will run after publishing, in the following order:
postknitpublishpostpackpublishpostpublish
Use
--no-scriptsto publish without running scriptsWhen publishing,
knitcan optionally calculate a hash signature from the file contents and use the signature in the resulting packageversion(e.g."1.2.3+ffffffff"). To enable this, pass--sigto theknit publishcommand- Use
.knitignoreto exclude files from publishing to knit repo, such asREADME.md---contentwill show included files in the published package - Considering publishing,
knitemulates the behavior of thenpmclient (npm pack). If you have a nested.knitfolder in your package that you are going to publish withknitand you use thepackage.jsonfileskey, it should be included there explicitly. See wclr/yalc#95 - If you want to include the
.knitfolder in published package content, add the!.knitpattern to.npmignore - By default, Knit resolves the
workspace:protocol in dependencies. This can be bypassed with--no-workspace-resolve - For convenience, you can automatically propagate package updates to dependent projects
- Note for Windows users: make sure the
LF(line feed) symbol is used in published sources; it may be needed for some packages to work correctly (for example,binscripts).knitwon't convert line endings for you (becausenpmandyarnwon't either)
Add (knit add)
Run in a project to pull a package from the store and install it as a dependency.
- Copies the current version from the store to your project's
.knitfolder and injects afile:.knit/$PACKAGE_NAMEdependency intopackage.json - Specify a particular version with
knit add $PACKAGE_NAME@version. This version will be fixed inknit.lockand will not affect newly published versions during updates - Use
--linkto add alink:protocol dependency instead of thefile:protocol - Use
--devto add the package as a development dependency (devDependencies) - Use
--pureto avoid modifyingpackage.jsonandnode_modules- This is useful when working with workspaces (see workspaces section)
- Use
--workspace(or-W) to add a dependency withworkspace:protocol
Link (knit link)
As an alternative to add, you can use the link command. This is similar to npm link/yarn link, except the symlink source will be the local .knit folder of your project instead of the global link directory.
After knit copies package content to the .knit folder, it will create a symlink (and not modify package.json): $PROJECT_DIR/.knit/$PACKAGE_NAME ⟹ $PROJECT_DIR/node_modules/$PACKAGE_NAME.
Update (knit update)
Run knit update $PACKAGE_NAME to update to the latest version of $PACKAGE_NAME from the store, or just knit update to update all the packages found in knit.lock.
preknitandpostknitscripts will be executed in the target package as part of add and update operations (which are performed duringknit push, see push section)- If you need to perform pre- or post- lifecycle scripts upon the update operation of a particular package, use a
(pre|post)knit.package-namescript in yourpackage.json - Use
--update(or--upgrade/--up) to run your package managers's update command for packages
Remove (knit remove)
- Run
knit remove $PACKAGE_NAMEto remove the package's dependency information frompackage.jsonandknit.lock - Run
knit remove --allto remove all packages from a project
Installations (knit installations)
- Run
knit installations clean $PACKAGE_NAMEto unpublish a package previously published withknit publish - Run
knit installations show $PACKAGE_NAMEto show all packages where$PACKAGE_NAMEhas been installed
Advanced Usage
Pushing Updates Automatically to All Installations
knit publish --push (or knit push) will publish your package to the store and propagate all changes to existing knit package installations (this performs the update operation on the target location).
When you run knit add|link|update, the project's package locations are tracked and saved, so knit knows where each package in the store is being used in your local environment.
The scripts option is false by default, so it won't run pre/post scripts (change this behavior by passing --scripts).
Flags:
--changed: causesknitto first check if the package content has changed before publishing and pushing- This is a quick operation, and may be useful for file-watching scenarios when pushing
--replace: causesknitto force replacement of the package contentpreknitandpostknit(detailed in Update section): execute lifecycle script(s) on every push--update: run thenpm|yarn|pnpm updatecommand for pushed packages
Committing knit files
It is up to you whether you would like to commit the files generated by knit (.knit/ and knit.lock) to your repository.
Reasons not to commit:
- You are using
knitmodules temporarily during development - You strictly use
knit link(which does not modifypackage.json) - You are using
knit addand don't want to worry about changing thefile:/link:dependencies- This can be circumvented by using
knit checkin a precommit hook, e.g. with Husky, which checkspackage.jsonfor Knit dependencies and exits with an error if it finds any
- This can be circumvented by using
Reasons to commit:
- You want to maintain deterministic builds as they relate to Knit dependencies
- You want to keep shared
knitfiles within the projects you are working on and treat it as a part of the project's codebase- This may simplify management and usage of shared packages within your projects and maintain consistency
If you decide to commit, consider that standard non-code files like README.md and LICENSE.md will also be included, so you may want to exclude them in .gitignore with a pattern such as **/.knit/**/*.md. Alternatively, use .knitignore to avoid including those files in package content.
Publish/Push Subprojects
Useful for monorepos, knit publish $PROJECT_NAME will perform the publish operation in the ./$PROJECT_NAME directory relative to process.cwd().
Retreat and Restore
Instead of completely removing a package, it can be temporary set back with knit retreat [--all] (e.g. before package publication to a remote registry).
Later, it can be restored with knit restore.
Use with npm/yarn/pnpm Workspaces
--pure will be used by default if you try to add a project in a workspaces-enabled package, so package.json and node_modules will not be modified. Then, you can add the Knit-enabled package folder to workspaces in package.json (e.g. add .knit/* and .knit/@*/* patterns). During the update (or push) operation, package content will be updated automatically and your package manager will handle the rest.
If you want to override the default pure behavior, use --no-pure.
Clean up Installations File
While working with knit, you might face a situation when you have locations where Knit-enabled projects have been removed from the filesystem, which will cause warnings when knit tries to push a package to the missing location. To get rid of these warnings, use knit installations clean $PACKAGE_NAME.
Override Default Package Store Folder
Use --store-folder to override the default location for storing published packages.
Control Output
Use --quiet to fully disable output, except for errors. Use --no-colors to disable colors.
Set Default Options via .knitrc
A .knitrc file can be created to declaratively set default options for Knit.
Valid options:
sig: control hash signatures for package versionsworkspace-resolve: controlworkspace:protocol resolutiondev-mod: control removal ofdevDependenciesfrom package contentscripts: control lifecycle scriptsquiet: control console outputfiles: control display of included files in published packages
Example:
workspace-resolve=false
sig=falseLicense
The code in this repository is licensed under MIT, © Brian Cooper. The original yalc work is licensed under MIT © Alex Osh. See LICENSE.md for more information.