Help us understand the problem. What is going on with this article?

babelでコンパイルしたnpmモジュールをTravisCIからリリースする

More than 3 years have passed since last update.

初めてnpmパッケージを作ってみて、わりといろいろやることがあったのでメモします。
ES2015のコードで開発して、babelでES5にコンパイルしています。

ここに動いているコードは置いてあります。 https://github.com/mookjp/multi-proxy

前提

babelを使って、以下のようなパッケージ構成でES2015でnpmモジュールを開発しているものとします。

.
├── dist # babelでコンパイルしたコードを配置
├── package.json
└── src # ES2015のコードを配置
    ├── main
    │   ├── lib
    │   ├── main.js
    │   └── middleware
    └── test
        ├── lib
        └── middleware

パッケージの設定

package.json

"scripts"に、babel-cliを使ってES2015のコードをコンパイルする処理を追加します。
また、"main"にはコンパイル後のコードを指定します。

// 省略
"main": "dist/main.js", # babelでコンパイルしたコード
"scripts": {
// 省略
    "build": "babel src/main -d dist" # dist以下に出力
},
"devDependencies": {
    "babel-cli": "^6.3.17",
    // 省略、テスト用パッケージ等
}

.gitignore

ES2015で開発しているモジュールなので、babelでコンパイルした後のコードはバージョン管理は不要だと思います。
.gitignoreにはbabelでコンパイルしたコードは含めないようにします。

// 省略
dist/

.npmignore

npm publishするとき、パッケージのルートディレクトリに

  • .npmignoreがない
  • .gitignoreがある

場合は、.gitignoreで無視されているファイルがnpm publish時にも無視されます。
(参考: developers | npm Documentation

今回は

  • npmモジュールとしてはdist/以下にビルドしたES5のファイルを配布したい
  • 逆にgitリポジトリに含めているES2015のソースコードは無視したい

ので、以下のような.npmignoreを書きます。

// 省略
# dist/
src/ # ES2015のソースコードが配置されているディレクトリ

TravisCIの設定

.travis.yml

deployフェーズの設定をします。
以下の例ではTravisCIが標準で用意している、npmパッケージをデプロイできるproviderをそのまま使っています。

language: node_js
node_js:
    - "4.1"
after_success:
  - npm run-script build
deploy:
  provider: npm
  email: "mookjpy@gmail.com"
  api_key: $NPM_API_KEY
  skip_cleanup: true # `run-script build`で生成したES5のコードを消さないようにする
  on:
    tags: true

TravisCIのプロジェクト設定

TravisCIのプロジェクトごとの環境変数設定項目に、$NPM_API_KEYをあらかじめ設定しておきます。
プロジェクトの設定は https://travis-ci.org/your-username/project/ の、右側にsettingsというリンクがあるのでそこから行うことができます。

Screen Shot 2015-12-24 at 23.32.43.png

$NPM_API_KEYは自分のマシンでnpm loginした後に以下のコマンドから確認することができます。

cat ~/.npmrc
//registry.npmjs.org/:_authToken=<Your key>

babel6からのdefault exportの扱いについて

babel6からはexport defaultでexportしたモジュールにrequireでアクセスする際の挙動が変わっています。
以下のようにES2015のexport defaultを使った時は

mybar.js
export default myVar;

以下のようにrequireで取得したオブジェクトのdefaultを参照する必要があります。

importing.js
// var myVar = require('myVar'); これはbabel6からは使えない

var myVar = require('myVar').default; // defaultオブジェクトを指定する

今回例にしているプロジェクトをbabel6を使ってコンパイルする際は、src/main/main.jsを以下のように書くことができます。
これはES5のコードなので、babelのコンパイラを通してもそのままdist/main.jsに書きだされます。

src/main/main.js
module.exports = require('./lib/my_util').default; // ユーザー側からrequireを使ってアクセスされるであろうモジュール

npmモジュールのユーザーは普段通りの感覚でrequireを使うことができます。

npm install great-package
main-by-user.js
var myUtil = require('great-package');
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away