fabrique
v2.0.6
Published
CLI to build a library
Downloads
1,113
Readme
Fabrique
fabrique is a cli to create, build and publish libraries,
letting the user focus on the functionalities of its library, instead of the build/publish process.
With fabrique you'll be able to:
- create rapidly a library with all the tools and scripts to:
- build and publish your library
- write tests for it
- format your code
- and debug it
- upgrade any Fabrique project to get the last functionalities in one command line.
fabriqueis the French word for "made/factory"
Motivation
When we develop javascript/typescript libraries, we frequently create new repositories
and maintain the scripts to build, test, and debug them.
This tends to become rapidly cumbersome, especially when their number grows.
We may choose to opt in for a monorepo, and I'll tell you: yes, in many cases, this is the optimal solution.
However, in many other cases, one library per-repo makes sense, and this is where fabrique comes in.
Another goal is to focus on simplicity: for new incomers in javascript,
learning all the tools and build processes is complicated.
You want to write your library, but you have to learn vite, jest, how to build and publish a lib,
install prettier, etc. With fabrique all comes in pre-configured.
📝 Documentation
Requirements
The library requires Node.js 24+ and yarn 4+.
Installation
We recommend using npx:
npx fabrique [cmd]But you may prefer to install globally fabrique:
npm install -g fabriqueAnd run a command with:
fabrique [cmd]List of commands
[cmd]: create
npx fabrique create [type] [name][type]: lib
example
npx fabrique create lib @my-organization/my-libraryaction
This command creates a new library with the name [name] inside the folder ./[name] (in our example: ./@my-organization/my-library).
You'll be prompted for a description, author and git url.
INFO: run the command where you want to create your project.
options
[name]: the library name
NOTE: currently only the
libtype is supported. More architectures may be developed in the future.
[cmd]: upgrade
# from the root of a "fabrique" project
npx fabrique upgradeaction
This command updates an existing fabrique project: it updates the build files, the scripts, etc.
It tries to be non-destructive.
INFO: run the command inside the
fabriqueproject.
options
--force: forces an upgrade even if the lib is not afabriqueproject or if the version is identical. Use with caution.
[cmd]: build
# from the root of a "fabrique" project
npx fabrique buildaction
This command builds an existing fabrique project.
INFO: run the command inside the
fabriqueproject.
lib project
Summary:
- TypeScript files are transpiled into JavaScript files.
- You can exclude some files or directories by adding the suffix
.privateto the file or directory name (ex:src/**/*.private/**/.ts,src/**/*.private.ts). - You can exclude
protectedfiles or directories by adding the suffix.protectedto the file or directory name. These files are exported into a separatesrc/index.protected.tsfile, that can be imported byimport * from '@my-organization/my-library/protected'. - A ready to publish package is generated in the
distfolder.
- All
src/**/*.tsfiles are transpiled intodist/src/**/*.js,dist/src/**/*.js.map, anddist/src/**/*.d.tsfiles. - All
src/**/*.tsfiles exceptsrc/**/*.{test,spec,bench,protected,private}.tsandsrc/**/*.{test,spec,bench,protected,private}/**/*.tsare exported into a temporatrysrc/index.tsfile (and transpiled intodist/src/index.js). - All
src/**/*.protected.tsfiles exceptsrc/**/*.{test,spec,bench,private}.tsandsrc/**/*.{test,spec,bench,private}/**/*.tsare exported into a temporatrysrc/index.protected.tsfile (and transpiled intodist/src/index.protected.js).
- NOTE: if no
protectedfiles are found, theindex.protected.tsfile is not generated
- The
package.jsonis copied intodist/package.jsonwith the foloowing modifications:
- The
mainfield is set todist/src/index.js - The
typesfield is set todist/src/index.d.ts - The
exportsfield is set to:.:dist/src/index.js./protected:dist/src/index.protected.js
- Other fields pointing to
.tsfiles are updated to point on the corresponing.jsfiles - Unnecessary fields for publication are removed (ex:
scripts,packageManager, etc.)
options
--mode <mode>(one ofdev,rc,prod, defaultprod): build the project using a specific mode:dev: appends-dev.{prereleaseId}into the package's versionrc: appends-rc.{prereleaseId}into the package's versionprod: ready for production
[cmd]: release
# from the root of a "fabrique" project
npx fabrique releaseaction
This command releases an existing fabrique project. In order:
- runs
fb:testcommand to ensure that tests fulfill.- if
fb:testdoes not exists, runstestas a replacement.
- if
- runs
fb:buildcommand to build the project.- if
fb:builddoes not exists, runsbuildas a replacement. - if
builddoes not exists, runsfabrique buildas a replacement.
- if
- checks that the resulting build artifact can be published on npm.
- publishes the package on npm.
INFO: run the command inside the
fabriqueproject.
options
--mode <mode>(one ofdev,rc,prod, defaultprod): seefabrique build --mode <mode>--dry(default: false): runs without publishing the package. This is useful to check if the output is correct or not.
[cmd]: ci
npx fabrique ci [type][type]: release
example
npx fabrique ci releaseaction
Starts the CI release workflow.
INFO: this command is automatically run from the github action
release.yml.
[cmd]: refactor
# from the directory we want to refactor
npx fabrique refactor [from] [to]example
npx fabrique refactor my-component my-new-componentRefactors all files and directories having
my-componentas name intomy-new-component(recursively). AND all text-based files (ex: html, js, ts, css, etc...) containingmy-component(or derived cases) intomy-new-component(keeping the same case).
If we run this command with the following files structure:
- some-component
- my-component
- my-component.ts
- my-component-abc
- my-component-abc.ts
We get:
- some-component
- my-new-component
- my-new-component.ts
- my-new-component-abc
- my-new-component-abc.ts
If my-component.ts has this content:
class MyComponent {}
// my-component
const MY_COMPONENT = null;
function my_component(myComponent: MyComponent) {}We get:
class MyNewComponent {}
// my-new-component
const MY_NEW_COMPONENT = null;
function my_new_component(myNewComponent: MyNewComponent) {}action
This command refactors files and directories recursively from the cwd (by default, the current directory in which the script is executed).
It preserves the case of the names (ex: dash-case, or cameCase).
INFO: run the command inside the folder you want to refactor.
options
[from]: the "source" text to refactor. Must bedash-case.[to]: the "destination" text to refactor. Must bedash-case.--dry(default: false): runs without modifying the files. This is useful to check if your refactoring is safe or not.--cwd(default: current folder): specifies the directory to start from.
--version
npx fabrique --version
# or
npx fabrique -vReturns the current fabrique version.
--help
npx fabrique --help
# or
npx fabrique -hYou may get help on individual commands:
npx fabrique create -hRelease Workflow
1. Pull Request to main or develop
- The
release.ymlworkflow runs onpull_request - The
yarn fb:ci:releasestep runs only if the PR has thedevlabel - Impacted packages are published as:
x.y.z-dev.<timestamp>- npm dist-tag:
dev
2. Push to develop
- Impacted packages are published as:
x.y.z-rc.<timestamp>- npm dist-tag:
rc
3. Push to main
- Stable publication:
x.y.z- npm dist-tag:
latest - Only if
[email protected]does not already exist on npm
Graph
flowchart LR
EVENT("EVENT")
HAS_DEV_TAG{"has "dev" tag ?"}
SKIP_BUILD(["skip build"])
BUILD_DEV_PACKAGES["build "dev" package"]
PUBLISH_DEV_PACKAGES["publish "dev" package"]
BUILD_RC_PACKAGES["build "rc" package"]
PUBLISH_RC_PACKAGES["publish "rc" package"]
BUILD_PROD_PACKAGES["build "prod" package"]
PUBLISH_PROD_PACKAGES["publish "prod" package"]
TARGET_BRANCH{"branch"}
EVENT -- "pull_request" --> HAS_DEV_TAG
HAS_DEV_TAG -- "no" --> SKIP_BUILD
HAS_DEV_TAG -- "yes" --> BUILD_DEV_PACKAGES
BUILD_DEV_PACKAGES --> PUBLISH_DEV_PACKAGES
EVENT -- "push" --> TARGET_BRANCH
TARGET_BRANCH -- "develop" --> BUILD_RC_PACKAGES
BUILD_RC_PACKAGES --> PUBLISH_RC_PACKAGES
TARGET_BRANCH -- "main" --> BUILD_PROD_PACKAGES
BUILD_PROD_PACKAGES --> PUBLISH_PROD_PACKAGESImportant Rules
- if the version already exists on npm: the release is skipped
- the
package.jsonfile in the repo must keep stable versions (x.y.z) -dev/-rcsuffixes are generated in CI
