Nx + shipjs で npm package を複数管理する
Nx では oss 向けの workspace を作成できるが、ドキュメントが分かりづらかったので自分なりにまとめる。本記事の内容はこのプロジェクトを作成するときに分かったことをまとめたもの。
GitHub - tyankatsu0105/css-houdini: CSS Houdini
現在の Nx は 11.0.20。
なお、
- sample-org という organization の scoped package な node ライブラリを管理する
- npm package は全て同じバージョニング
を前提とする。
workspace の作成
npx create-nx-workspace@latestで workspace を作成する。
? Workspace name (e.g., org name) sample-org
? What to create in the new workspace oss [an empty workspace with a layout that works best for open-source projects]
? Use Nx Cloud? (It's free and doesn't require registration.) No
これでpackagesが root にある workspace が作成される。各パッケージはここに配置されていく。
nx.json の
workspaceLayoutはlibsDirしか使わないので、それ以外は消していい
続けて、@nrwl/nodeを入れて node library を generate できるようにする。
npm i -D @nrwl/node --save-exact
そして generate する。
npx nx g @nrwl/node:library sample-package1 --publishable --importPath="@sample-org/sample-package1"
publishable オプションで npm publish する前提の library を generate できる。 このとき、importPath をつけることが必須になるので、@<orgName>/<packageName>とする。
これでpackages/sample-package1/package.jsonの name に importPath で指定した library が作成される。
shipjs を導入する
shipjs は
- CHANGELOG.md の生成
- package.json の version のカウントアップ
- release タグの生成
- release PR の自動生成
- build と npm publish の実行
などができる、npm publish に関するあれこれをサポートしてくれるパッケージ
Introduction | Ship.js
shipjs は monorepo のサポートもしているので、Nx の workspace も大丈夫。しかし、パッケージごとのバージョニングはサポートされておらず、全て統一バージョンになってしまうので注意。
npx shipjs setup
質問に答えていくと設定が完了するので、.env をローカルに作成して、shipjs prepareが実行できるようにする。
GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
shipjs の config ファイルを作る必要があるので、root に置く。
const getPackagePath = (dir) => {
const splittedDir = dir.split('/');
const packagePath = [
splittedDir[splittedDir.length - 2],
splittedDir[splittedDir.length - 1],
].join('/');
return { packagePath };
};
const getDistPackagePath = (packagePath) => {
const distPackagePath = `../../dist/${packagePath}`;
return { distPackagePath };
};
module.exports = {
monorepo: {
mainVersionFile: 'package.json',
packagesToBump: ['packages/*'],
packagesToPublish: ['packages/*'],
updateDependencies: false,
},
buildCommand: () => 'nx run-many --target=build --all --maxParallel=3',
publishCommand: ({ defaultCommand, tag, dir }) => {
const { packagePath } = getPackagePath(dir);
const { distPackagePath } = getDistPackagePath(packagePath);
return `cd ${distPackagePath} && ${defaultCommand} --access public --tag ${tag}`
}
};
これで、準備が完了。
publish する
諸々ライブラリの作成が進んでリリースするタイミングがきたら、
npm run release
でshipjs prepareを実行する。
質問に答えると PR が作成されるので、諸々確認して merge する。
PR はこんなかんじ。
chore: release v0.2.0 by tyankatsu0105 · Pull Request #24 · tyankatsu0105/css-houdini · GitHub
これで packages 配下全てを build して、publish する。
Tips
srcRootForCompilationRoot で build するときの directory を変更する
workspace.jsonのtarget.build.options.srcRootForCompilationRootを指定すると、そこの中身をビルドして root に配置してくれる。package.jsonのmainをsrc/index.jsからindex.jsにしたいみたいなときに便利。
workspace.jsonのtarget.build.options.mainも変更しておくのを忘れずに。