A microbundle template to create browser/server packages faster and more reliably.
If this is the first time the package is being setup by any team member
ensure that all todo-template-
annotations spread around the code have been
resolved and deleted.
package.json
author
to owner-or-organization
name
to @owner-or-organization/repository-name
repository.url
to git://github.com/owner-or-organization/repository-name.git
publishConfig.registry
https://npm.pkg.github.com/owner-or-organization
https://registry.npmjs.org
publishConfig.access
to according to your needs.module
. Which we recommend..github/workflows/publish.yml
jobs.steps.*.with.scope
to @owner-or-organization
jobs.steps.Publish.env.NODE_AUTH_TOKEN
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
publish.yml
workflow on GitHub if you prefer releasing through the CLI
readme.md
repository-name
as main headingREADME.md
file that will replace this oneREADME.md
filetestpkg.sh
testpkg.sh
app/index.ts
test file (tiny app to manually verifynpm run release
)miscellaneous:
devDependencies
, e.g.: react
and react-dom
peerDependencies
to ensure package consumers have required dependenciesprettier
or eslint
plugins as required.cypress
, playwright
, react-testing-lib
, storybook
.vscode/settings.json
, some libs you might be using may require or benefit additional configs (e.g.: vue
or i18n-ally
).eslintrc.cjs
with rules specific to your tooks, e.g.: react-hooks
or others..lintstagedrc.json
to scan additional file types.tsconfig.json
at the root of the project with rules that make sense for your package.prettierrc.cjs
import order rules to add additional path alias overtime.To update the project's dependencies and package.json
use the script below. Please
review the package changes. If any major version upgrade was made, check on the package
repository if there were breaking changes and how to deal with them.
npm run up:install
Code quality is set up for you with prettier
, eslint
, husky
, and
lint-staged
. Depending on the package goals, you might need to add some
plugins. Adjust package.json
accordingly.
size limit is set up to calculate
the real cost of your library with npm run size
and visualize the bundle
with npm run analyze
.
Take care when adding new dependencies to the project. When you add a new
production dependency (dependencies
in package.json
), these will also
be installed a production
or development
dependencies in the consumer
projects (depending on their usage of --save-dev
). When you add a package to
devDependencies
these are not propagated to consumers. Ideally, if you want
to ensure that consumers have a package installed on their project, that is
needed for your project to work, without risking conflicts with them, you should
declare such packages as peerDependencies
which are installed in case the
consumer does not have them yet. Otherwise peerDependencies
ensures version
the consumer has, is compatible with what is requested.
dependencies
indirectly forces consumers to have your dependencies.devDependencies
do not affect consumers.peerDependencies
ensures consumers install the correct version of a packages youJest tests are set up to run with npm test
or npm test:headless
. If you
are developing a package for React.js
or Next.js
further packages need to be
added.
We use TypeScript path
alias and ts-jest
to ensure the same aliases are available
during test runs. For bundling convinience, our tests are located on an isolated folder
called test
. You should create your unit
and integration
tests here, but you
are free to modify the configuration to your preference.
Add all expected environment variables (see .env.example
) to your .zshrc
or
.bashrc
profile. Alternatively, install direnv
, then, add a .env
file
in the root of the project containing those same environment variables.
Finally, execute the commands below
# Create a PAT (write package permissions) for your GitHub user on the website
# This should be somewhere under Profile > Settings > Developer Settings
# Export the following environment variables or use `direnv` / `dotenv`:
export NPM_USER=<your_lowercased_github_username>
export NPM_PASS=<your_github_pat_with_packages_write_permission>
export NPM_EMAIL=<your_github_email>
export NPM_REGISTRY=https://npm.pkg.github.com/
export NPM_SCOPE=<owner-or-organization>
# Source your profile and execute:
npm-cli-login -u $NPM_USER -p $NPM_PASS -e $NPM_EMAIL -r $NPM_REGISTRY -s $NPM_SCOPE
# Verify the previous process
# Check global .npmrc (ensure you see your auth token (PAT) and the org registry)
# Check also your `whoami` just in case
cat ~/.npmrc
npm whoami --scope=@owner-or-organization --registry=https://npm.pkg.github.com/
# Kickstart the actual publishing process
npm run release -- --first-release
npm run release -- --release-as patch
npm run release -- --release-as minor
npm run release -- --release-as major
You should run a healthy amount of automated tests and ideally, test your
library on a dummy-app, if it is somewhat complex to do so automatically; If it is a
simple utility library you can tweak ./app/index.ts
and use testpkg.sh
to print some
console.log
statements;
When you run npm run release -- args
a handful of precommand, command, and
postcommand scripts are executed. Below is the order in which they resolve!
2. prerelease # checkout to main, updates local codebase and runs static-analysis
3. prebuild # cleans current dist folder
4. build # runs microbundle commands to generate a new dist folder
5. release # executes at this point to generate standard-version and changelogs
6. postrelease # pushes the created tags to remote and starts publishing process
7. prepack # disables postinstall script to avoid conflict on consumers
8. prepare # executes default prepare script (gzip of package.json.files + package.json itself)
9. postpack # reenables postinstall script
10. publish # pushes gzip to remote registry.
We export our configurations in multiple formats on package.json
. We use microbundle
to make bundling a breeze. For a more refined configuration, please refer to their
documentation at @microbundle
Three actions are added by default:
main
which installs deps w/ cache, lints, tests, and builds againstsize
which comments cost comparison of your library on every pullsize-limit
publish
a workflow that is currently under development, which would beCJS, MJS, ESModules, and UMD module formats are supported. The appropriate paths are
configured in package.json
. Read more at microbundle
Per Palmer Group guidelines, you should prefer named exports.. This allows code-splitting inside a consumer application instead of the exported library. E.g.: a react app using this lib will optimize this library better if we export named modules rather than default modules.