Scala Advent Calendar 2022 - Qiita 1日目の記事です
scala.js でビルドした成果物を npm にアップロードすることありますか? 私はある。
普通に scala.js でビルドした js を npm にアップロードしようとするとこういう感じの流れになります。
sbt fullOptJS
とかで js にビルド- ビルド成果物(
.../target/scala-2.13/foo-opt.js
とか) を適当なディレクトリにコピー - そのディレクトリに
package.json
と、npmにアップロードするREADME.md
を設置 npm login
してnpm publish
まあ、これでも別にいいっちゃいいのですが、いくつか気に入らないところがあり
build.sbt
の設定と、package.json
の設定を別々に管理することになる (version
とか)- sbt によるビルド成果物のパスをリリーススクリプト側にハードコードしないといけない。
- 別にいいけど、なんとなくビルド成果物の居場所はsbtが知ってる状態であってほしい。
なんか sbt 側で npm publish をラップしたいな〜と思って適当に github 眺めてると良さげな sbt plugin を見つけました。
全然ドキュメントない!けどコード読んだらなんか良さそうだったので使ってみた
sbt-npm-package ざっくり
sbt-npm-package
がやってくれるのは
npm-package
ディレクトリをtarget
以下に作る (target/scala-2.13/npm-package
とか)、ここにjsとかpackage.jsonとかを集めてくれる。npmPackageNpmrc
でnpm-package/.npmrc
の生成- 中身はデフォルトで
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
- 中身はデフォルトで
npmPackagePublish
で js 成果物を npm にアップロードnpm-package/package.json
を build.sbt での設定を元に生成- ビルド成果物のJSを
npm-package/main.js
にコピー - (デフォルトではプロジェクトルートの)
README.md
をnpm-package
にコピー npm-package
ディレクトリ上でnpm publish
を実行
なので基本的にはこの記事の最初に述べたリリース手順をsbt側に寄せて自動化してくれるというシンプルなもの。
設定しそうな settingKey
settingKey | 説明 | デフォルト |
---|---|---|
npmPackageName |
package.json の name |
sbt の project name からいい感じに作られる |
npmPackageDescription |
description |
|
npmPackageVersion |
version |
sbt の version が利用される |
npmPackageRepository |
repository |
git ls-remote --get-url origin |
npmPackageREADME |
アップロードする README.md へのパス | README.md |
npmPackageStage |
fullOptJS とか fastOptJS とか指定する | FastOptJS |
設定にない項目は npmPackageAdditionalNpmConfig
で書き加えられる。
npmPackageAdditionalNpmConfig := Map( "homepage" -> _root_.io.circe.Json.fromString("https://scalameta.org/")
使用例
例えば
npmPackageName := "scalameta-parsers", npmPackageDescription := "Library to parse Scala programs", npmPackageRepository := Some("https://github.com/scalameta/scalameta"), npmPackageAuthor := "scalameta", npmPackageLicense := Some("BSD-3-Clause"), npmPackageKeywords := Seq("scala", "parser"), npmPackageVersion := "4.6.0", npmPackageAdditionalNpmConfig := Map( "homepage" -> _root_.io.circe.Json.fromString("https://scalameta.org/") ),
こんな感じの設定で npmPackagePublish
すると以下のような pakcage.json
が作られます。
{ "name" : "scalameta-parsers", "description" : "Library to parse Scala programs", "version" : "4.6.0", "type" : "commonjs", "repository" : { "type" : "git", "url" : "https://github.com/scalameta/scalameta" }, "author" : "scalameta", "license" : "BSD-3-Clause", "main" : "main.js", "dependencies" : {}, "devDependencies" : {}, "keywords" : ["scala", "parser"], "homepage" : "https://scalameta.org/" }
良さそうですね。
あとは repository secret に npm からとってきた access token を NPM_TOKEN
として登録して、以下のように npm と sbt のある環境で npmPackageNpmrc
-> npmPackagePublish
すれば出来上がり
name: Release JS on: push: tags: ["*"] jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3 with: node-version: "18" - uses: actions/checkout@v3 - uses: olafurpg/setup-scala@v13 - run: git fetch --unshallow - name: Publish run: sbt "parsersJS/npmPackageNpmrc; parsersJS/npmPackagePublish" env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
詳しくはこちら
ブログに使い方書かないで sbt-npm-package にPRでもすれば良かった気もしてきた。