TypeScriptで作ったpackageをesbuildを使ってnpmに公開するまで

2022/05/06に公開
1

先日私は、Reactのカスタムフックを作成してnpmに公開しました。

https://chot-inc.com/blog/a358wz0nf/

この記事は、その時の忘備録です。

今回の主な開発環境

  • PC: MacBook Air(M1)
  • OS: Monterey (12.3.1)
  • Node.js: v16.14.2
  • pnpm: v7

依存環境のインストール

pnpm add -D esbuild typescript ts-node npm-run-all

build.tsの作成

requiredimportどちらも対応するようにesmcjsどちらも対応を進めます。

build.ts
const { build } = require('esbuild')
const { dependencies } = require('./package.json')

const entryFile = 'src/index.ts'
const shared = {
  bundle: true,
  entryPoints: [entryFile],
  external: Object.keys(dependencies),
  logLevel: 'info',
  minify: true,
  sourcemap: false,
}

build({
  ...shared,
  format: 'esm',
  outfile: './dist/index.esm.js',
  target: ['ES6'],
})

build({
  ...shared,
  format: 'cjs',
  outfile: './dist/index.cjs.js',
  target: ['ES6'],
})
package.json
{
  "scripts": {
    "build:esbuild": "ts-node build.ts"
  }
}

型ファイルを出力する

esbuildでは型定義ファイルは出力されません。
型定義ファイルはtscコマンドで作成します。
--declaration--emitDeclarationOnlyのオプションを渡すことで型定義ファイルのみを出力することができます。

package.json
  {
    "scripts": {
-     "build:esbuild": "ts-node build.ts"
+     "build:esbuild": "ts-node build.ts",
+     "build:types": "tsc --declaration --emitDeclarationOnly --declarationDir './dist'",
    }
  }

tscのオプションについて詳しくはこちらをご確認ください
https://www.typescriptlang.org/docs/handbook/compiler-options.html

この時私が使ったtsconfig.jsonファイルは下記の通りです。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "declaration": true,
    "strict": true,
    "lib": ["ES2020", "dom"]
  },
  "include": ["./src/**/*"],
  "exclude": ["node_modules"]
}

コマンドをまとめる

npm-run-allを利用して、コマンドを並列実行します。

https://github.com/mysticatea/npm-run-all

package.json
  {
    "scripts": {
+     "build": "run-p build:*",
      "build:esbuild": "ts-node build.ts",
      "build:types": "tsc --declaration --emitDeclarationOnly --declarationDir './dist'",
    }
  }

package.jsonにnpm公開する際の情報を記載する

npmに公開する上で必要な情報をpackage.jsonに記載します。
こちらに詳しく掲載されていますのでご参考ください。

https://docs.npmjs.com/cli/v8/configuring-npm/package-json

今回私が設定した主な情報は下記になります。

package.json
  {
+   "name": "use-microcms-iframe",
+   "version": "0.0.1",
+   "description": "Custom Hooks to create iframe fields for microCMS",
+   "main": "./dist/index.cjs.js",
+   "module": "./dist/index.esm.js",
+   "types": "./dist/index.d.ts",
+   "files": [
+     "/dist"
+   ],
    "scripts": {
      "build": "run-p build:*",
      "build:esbuild": "ts-node build.ts",
      "build:types": "tsc --declaration --emitDeclarationOnly --declarationDir './dist'"
-   }
+   },
+   "repository": {
+     "type": "git",
+     "url": "git+https://github.com/tsuki-lab/use-microcms-iframe.git"
+   },
+   "keywords": [
+     "microcms",
+     "react",
+     "typescript"
+   ],
+   "author": "hanetsuki <me@tsuki-lab.net>",
+   "license": "MIT",
+   "bugs": {
+     "url": "https://github.com/tsuki-lab/use-microcms-iframe/issues"
+   },
+   "homepage": "https://github.com/tsuki-lab/use-microcms-iframe#readme",
  }

あとはpnpm publishポチー

最後に

最近は、これあると便利かも!や自分が使いまわしたい!をnpmに公開して、weeklyDownloadを眺めるのが楽しみになってます。(一種の承認欲求)

今後も、あれやこれやに挑戦開発していきたいなーと思ひます。

参考にした記事

https://javascript.plainenglish.io/develop-and-publish-a-react-component-with-esbuild-and-typescript-3eb756adda6e
https://zenn.dev/drop_table_user/articles/6aa0b4c706e201

Discussion