66
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TISAdvent Calendar 2018

Day 13

Reactコンポーネントをnpmで公開する(GitHub Pages付き、Babel7、webpack4)

Last updated at Posted at 2018-12-12

なにこれ

TIS Advent Calendar 2018の13日目の記事です。よろしくお願いします!

最近Reactコンポーネントをnpm公開してみました(参考記事:CSSのclip-pathでSlit Animationを実現する)。そこで今回は簡単なReactコンポーネントを作って、npm公開する方法を紹介します。
「React始めたんだけど...npmアカウント作ったんだけど...」という方でも30分くらいで公開できるので、とりあえず手を動かしたい人向けのチュートリアルです。
下記のような手順でnpm公開するまでの方法を見ていきましょう。

  1. コンポーネントを作成する
  2. デモページを作成する
  3. デモページをGitHub Pagesで公開する
  4. コンポーネントをnpmに公開する

※ 完成品はGitHubに公開しています => Takumon/react-component-sample
※ 完成品は下記のようなプロジェクト構成になります。

プロジェクトルート
├─dist              ・・・ コンポーネントビルド資産出力場所
├─src               ・・・ コンポーネント資産
│   ├─index.js
│   └─styles.css
├─examples          ・・・ デモページ用資産
│  ├─dist           ・・・ デモページビルド資産出力場所
│  └─src
│     ├─index.html
│     └─index.js
├─node_modules
├─.babelrc          ・・・トランスコンパイル用設定ファイル
├─webpack.config.js ・・・ビルド用設定ファイル
├─package.json      ・・・依存ライブラリ・スクリプト定義ファイル
├─.npmignore        ・・・npm登録除外対処定義ファイル
└─.gitignore

1. コンポーネントを作成する

まずはコンポーネントを作ってトランスパイルするところまで完成させましょう。

※ 本手順完了時のソースコードは**こちら**
※ 本手順完了時のプロジェクト構成 ↓

プロジェクトルート
+ ├─dist          ・・・ コンポーネントビルド資産出力場所
+ ├─src           ・・・ コンポーネント資産
+ │   ├─index.js
+ │   └─styles.css
+ ├─node_modules
+ ├─.babelrc      ・・・トランスコンパイル用設定ファイル
+ └─package.json  ・・・依存ライブラリ・スクリプト定義ファイル(追記)
  • 最初にプロジェクトの雛形を作ります。npm initで色々聞かれますが全てデフォルトで構いません。
mkdir react-component-sample
cd react-component-sample
npm init
  • 最低限のReact系ライブラリをインストールします。開発用ライブラリとしてインストールするので-Dオプションを付けてください。
npm i -D react react-dom
  • BabelでReactをトランスコンパイルするためのライブラリをインストールします。こちらも開発用ライブラリなので-Dオプションを付けましょう。
npm i -D @babel/cli @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader
  • .babelrcを作成し、Reactをトランスコンパイルするための定義を記載します。
.babelrc
{
    "presets": [
        "@babel/preset-env",
        "@babel/react"
    ]
}
  • コンポーネントを作ります。
src/index.js
import React from 'react';
import './styles.css';
const MyComponent = () => (
    <h1>Hello from My Component</h1>
);
export default MyComponent;
  • コンポーネントで読み込むCSSを作ります。
src/styles.css
h1 {
    color: red;
}
  • トランスパイル用スクリプトをpackage.jsonに追加します。具体的にはJSファイルをトランスパイルしdistフォルダに出力、それ以外のファイル(CSS)をdistファイルにコピーするスクリプトです。
package.json
    "scripts": {
+     "transpile": "babel src -d dist --copy-files"
    },

確認

  • 準備が整ったので、トランスパイルしてみましょう。
npm run transpile
  • 下記のようにdistフォルダ配下にindex.jsとstyles.cssが生成されればトランスパイル成功です。
トランスパイル後の資産
プロジェクトルート
├─dist           ・・・ コンポーネントビルド資産出力場所
│   ├─index.js
│   └─styles.css

2. デモページを作成する

実際にコンポーネントを使用したデモページもあわせて用意しておきましょう。コンポーネントの使い方をユーザーにわかりやすく示すことができます。
ここではローカルでデモページが見れるところまでを作成します。

※ 本手順完了時のソースコードは**こちら**
※ 本手順完了時のプロジェクト構成 ↓

プロジェクトルート
  ├─dist
  ├─src
  │   ├─index.js
  │   └─styles.css
  ├─node_modules
  ├─.babelrc
+ ├─examples          ・・・ デモページ用資産
+ │  ├─dist           ・・・ デモページビルド資産出力場所
+ │  └─src
+ │     ├─index.html
+ │     └─index.js
+ ├─webpack.config.js ・・・ビルド用設定ファイル
+ └─package.json      ・・・依存ライブラリ・スクリプト定義ファイル
  • デモページはwebpackでビルドするので必要なライブラリをインストールします。
npm i -D html-webpack-plugin webpack webpack-cli webpack-dev-server css-loader style-loader
  • デモページのHTMLを作成します。
examples/src/index.html
<html>
<head>
    <title>My Component Demo</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
    <noscript>
        You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
</body>
</html>
examples/src/index.js
import React from 'react';
import { render } from 'react-dom'
import MyComponent from '../../src'

const App = () => <MyComponent/>;
render(<App />, document.getElementById('root'));
  • デモページのビルド設定ファイル(webpack.config.js)を作りましょう。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// HTMLファイルのビルド設定
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    template: path.join(__dirname, 'examples/src/index.html'),
    filename: './index.html'
});
module.exports = {
    // 依存関係解決の起点となる資産を指定します。
    entry: path.join(__dirname, 'examples/src/index.js'),
    // Babelのトランスパイル対象資産を指定します。
    module: {
        rules: [
            {
                test: /\.(js|jsx)/,
                use: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            }
        ]
    },
    plugins: [htmlWebpackPlugin],
    resolve: {
        extensions: ['.js', '.jsx']
    },
    // 開発用Webサーバのポートを指定します。
    devServer: {
        port: 3001
    }
}
  • デモページ起動用スクリプトをpackage.jsonに追記します。
package.jsonの一部
    "scripts": {
+     "start": "webpack-dev-server --mode development"
    },

確認

  • 準備が整ったのでデモページを起動しましょう。
npm start
  • ブラウザでhttp://localhost:3001にアクセスしてコンポーネントが表示されればOKです。

図1.png

3. デモページをGitHub Pagesで公開する

デモページをローカルで見れるようになったら、次はGitHubに資産を登録し、GitHub Pagesで公開しましょう。プラグインで簡単に公開できます。

※ 本手順完了時のソースコードは**こちら**
※ 本手順完了時のプロジェクト構成 ↓

プロジェクトルート
  ├─dist              ・・・ コンポーネントビルド資産出力場所
  ├─src               ・・・ コンポーネント資産
  │   ├─index.js
  │   └─styles.css
  ├─examples          ・・・ デモページ用資産
  │  ├─dist           ・・・ デモページビルド資産出力場所
  │  └─src
  │     ├─index.html
  │     └─index.js
  ├─node_modules
  ├─.babelrc          ・・・トランスコンパイル用設定ファイル
+ ├─webpack.config.js ・・・ビルド用設定ファイル(追記)
+ ├─package.json      ・・・依存ライブラリ・スクリプト定義ファイル(追記)
+ └─.gitignore
  • github-pagesというGitHub公開用プラグインをインストールします。
npm i -D gh-pages
  • package.jsonにGitHubPages公開用スクリプトを3個追加します。
    • publish-demoはビルドとデプロイをいっぺんにやるスクリプトです。デプロイ前に大抵の場合ビルドするので、1つにまとめておくと便利です。
package.json
    "scripts": {
+     "build": "webpack --mode production",
+     "deploy": "gh-pages -d examples/dist",
+     "publish-demo": "npm run build && npm run deploy"
    },
  • webpack.config.jsに出力先を指定します。
webpack.config.jsの一部
  module.exports = {
+     output: {
+        path: path.join(__dirname, "examples/dist"),
+        filename: "bundle.js"
+    },
  }
  • ではビルドしてみましょう。
npm run build
  • ビルドされて最小化された資産がexamples/dist配下に出力されたのが確認できればOKです。

  • Gitにあげる準備として.gitignoreを作りましょう。

.gitignore
node_modules
dist
  • GitHubでリポジトリを新規作成して資産を登録しましょう。新規作成後の「...or create a new respository on the command line」の説明に従ってください。

確認

  • 下記を実行してGitHub Pagesに登録しましょう。
npm run publish-demo

(補足)画像ファイルを扱う場合

もしデモページで画像を読み込む場合はfile-loaderurl-loaderを開発用依存ライブラリに追加してください。ビルド設定も下記のように修正が必要です。

npm i -D file-loader url-loader
webpack.config.jsの一部
  module.exports = {
    module: {
+     {
+       test: /\.(jpg|png|ico)$/,
+       use: 'url-loader'
+     },
    },
  }

これであとは最終手順のnpm公開を残すのみです!

4. コンポーネントをnpmに公開する

デモページも準備できたので、いよいよコンポーネントをnpmに公開しましょう。

※ 本手順完了時のソースコードは**こちら**
※ 本手順完了時のプロジェクト構成 ↓

プロジェクトルート
  ├─dist              ・・・ コンポーネントビルド資産出力場所
  ├─src               ・・・ コンポーネント資産
  │   ├─index.js
  │   └─styles.css
  ├─examples          ・・・ デモページ用資産
  │  ├─dist           ・・・ デモページビルド資産出力場所
  │  └─src
  │     ├─index.html
  │     └─index.js
  ├─node_modules
  ├─.babelrc          ・・・トランスコンパイル用設定ファイル
  ├─webpack.config.js ・・・ビルド用設定ファイル
+ ├─package.json      ・・・依存ライブラリ・スクリプト定義ファイル(追記)
+ ├─.npmignore        ・・・npm登録除外対処定義ファイル
  └─.gitignore
  • トランスパイル後に生成されるdist/index.jsを、npm公開資産のメインファイルに指定します。
package.json
+   "main": "dist/index.js",
  • 次にnpm公開時に自動で走るスクリプトprepublishOnlyを追加します。これによりnpm公開時にビルドし忘れるということを防ぎます。
package.jsonの一部
    "scripts": {
+     "prepublishOnly": "npm run transpile"
    }
  • このコンポーネントを使う側には、Reactがインストール済という想定ですのでpeerDependenciesを指定します。
package.jsonの一部
+   "peerDependencies": {
+     "react": "^16.3.0",
+     "react-dom": "^16.3.0"
+   },
  • .npmignoreを作成して、npm公開資産として不用な資産(トランスパイル前のjsファイルなど)は公開対象外としましょう。
.npmignore
src
examples
.babelrc
.gitignore
webpack.config.js
  • 最後にパッケージ名(package.jsonのname)を決めます。現段階ではreact-component-sampleとなっていて、お試しで作るコンポーネントとしては少し汎用的すぎる名前なので、@自分のnpmアカウント名/raect-component-sampleのようにしましょう。例えば下記のように修正します。
package.json修正例
-   "name": "react-component-sample",
+   "name": "@takumon/react-component-sample",

確認

  • ではnpm公開してみましょう。
    • @takumon/react-component-sampleのようなパッケージ名は、Scoped Packag(npmのプライベートなパッケージの命名規約)に沿っているのでデフォルトでプライベート公開になってしまいます。npmで有料契約をせずにプライベート公開しようとすると402エラーになります。そのため、ここでは--access=publicをつけて一般公開するようにしています。(参考:stachoverflow)
    • Failed PUT 403になる場合は、npmの認証エラーです。npm loginしましょう。
      それかpackage.jsonversionが古いのが原因です。いったん公開したバージョンで再公開はできません。バージョンをインクリメントしましょう。
npm publish --access=public
  • これで、npm公式サイトを確認しパッケージが追加されていれば、公開完了です!

図4.png

おわりに

今回紹介したように、わりと簡単にnpm公開できるので、普段使いまわしているようなコンポーネントがあれば公開してみるのもいいかもしれません。

参考

66
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
66
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?