方針
- デモページのコードはexamplesディレクトリで管理。
examples/srcには開発用のコードをまとめ、examples/publicは本番用のコードを格納する。 - デモページにはGithub Pagesを使用。examples/public/index.htmlを読み込ませる。
// Reactプロジェクトの例。React以外でも構造は同じ。
...
├─examples // デモページ用ディレクトリ
│ ├─public
│ │ ├─index.html
│ │ └─bundle.js
│ └─src
│ ├─App.tsx
│ ├─index.css
│ └─index.tsx
├─.babelrc
├─package.json
...
Github pagesの準備
Github pagesのライブラリをインストール
yarn add -D gh-pages
# or
npm install --save-dev gh-pages
Github pages公開用コマンドを追加
package.jsonにGithub pages公開用コマンドを追加します。
ここに追加しておけば、npm run deploy:demo
または yarn deploy:demo
を実行すれば公開できます。
今回は、-d examples/public
をオプションにつけているので、examples/publicディレクトリのindex.htmlを読み込む形になります。
{
...
"scripts": {
"deploy:demo": "gh-pages -d examples/public",
},
...
}
Babelの設定
トランスパイルするための設定。使用技術に合わせてプラグインを追加してください。
今回はReactとTypeScriptを使用していたので、その分のプラグインは記載してます。
※JavaScriptを使用しないデモページには必要ありません。
yarn add -D @babel/cli @babel/core @babel/preset-env
#or
npm install --save-dev @babel/cli @babel/core @babel/preset-env
#React使用時は下記追加
yarn add -D @babel/preset-react @babel/plugin-transform-react-jsx
#or
npm install --save-dev @babel/preset-react @babel/plugin-transform-react-jsx
#TypeScript使用時は下記追加
yarn add -D @babel/plugin-transform-typescript @babel/preset-typescript
#or
npm install --save-dev @babel/plugin-transform-typescript @babel/preset-typescript
なぜトランスパイルするのか?
・JavaScriptのコードを新しい書き方から古い書き方に変換し、新しい書き方・機能をサポートしないブラウザでも動くコードに変換するため。
・JSX(React)やVueファイルをJavaScriptファイルに変換するため。JSXやVueファイルはそのままではブラウザで動かない。
バンドルツールを使う
バンドルする(複数のファイルをまとめる)ことで、ファイルのリクエスト数が減少し、ページ読み込み速度が速くなります。
webpackを使用する場合
必要パッケージインストール
yarn add -D webpack webpack-cli webpack-dev-server babel-loader css-loader html-webpack-plugin postcss-loader postcss-preset-env style-loader ts-loader fork-ts-checker-webpack-plugin
#or
npm install --save-dev webpack webpack-cli webpack-dev-server babel-loader css-loader html-webpack-plugin postcss-loader postcss-preset-env style-loader ts-loader fork-ts-checker-webpack-plugin
TypeScriptを使用していない場合は、最後の2つはインストールする必要はない(ts-loader, fork-ts-checker-webpack-plugin)。
htmlファイルを追加
webpackの場合は、srcファイルにindex.htmlを用意します。
...
├─examples // デモページ用ディレクトリ
│ ├─public // バンドルファイルを出力するディレクトリ。.gitignore指定。
│ │ ├─index.html
│ │ └─bundle.js
│ └─src
│ ├─App.tsx
│ ├─index.css
│ ├─index.html // コレ。
│ └─index.tsx
├─.babelrc
├─package.json
├─webpack.config.js
...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="description" content="Demo for new library" />
<title>Page Title</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
webpack.config.jsを追加
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
module.exports = {
entry: "./examples/src/index.tsx",
module: {
rules: [
{
test: /\.(t|j)sx?$/,
loader: "ts-loader",
options: {
transpileOnly: true,
},
},
{
test: /\.(t|j)sx?$/,
exclude: path.resolve(__dirname, 'node_modules'),
loader: 'babel-loader', // .babelrcの設定が読み込まれる
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
["postcss-preset-env"],
],
},
},
},
],
},
],
},
output: {
path: path.join(__dirname, "examples/public"),
filename: "bundle.js",
},
resolve: {
extensions: ["*", ".js", ".jsx", ".ts", ".tsx"],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "examples/src/index.html"),
filename: "./index.html",
}),
new ForkTsCheckerWebpackPlugin({
typescript: true,
eslint: {
files: "./src/**/*.{ts,tsx}",
},
}),
],
devServer: {
port: 3010,
},
};
package.jsonにスクリプト追加
npm run dev:demo / yarn dev:demo
=> ローカルでページ起動npm run build:demo / yarn build:demo
=> ビルド
...,
"scripts": {
...,
"dev:demo": "webpack-dev-server --config webpack.config.js --mode development",
"build:demo": "rm -rf examples/public && webpack --config webpack.config.js --mode production"
},
...,
rollupを使用する場合
必要パッケージインストール
yarn add -D rollup @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-replace rollup-plugin-postcss rollup-plugin-serve rollup-plugin-terser @rollup/plugin-typescript
#or
npm install --save rollup @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-replace rollup-plugin-postcss rollup-plugin-serve rollup-plugin-terser @rollup/plugin-typescript
TypeScriptを使用していない場合は、最後の1つ(@rollup/plugin-typescript)をインストールする必要はない。
htmlファイルを追加
rollupの場合は、バンドル後のディレクトリにindex.htmlを用意します。また、バンドルしたJSファイルを読み込ませます。
...
├─examples // デモページ用ディレクトリ
│ ├─public
│ │ ├─index.html // コレ。
│ │ └─bundle.js // バンドルファイル。.gitignore指定。
│ └─src
│ ├─App.tsx
│ ├─index.css
│ └─index.tsx
├─.babelrc
├─package.json
├─rollup.config.js
...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="description" content="Demo for new library" />
<script defer="defer" src="bundle.js"></script> // バンドルしたJSファイルを読み込ませる
</head>
<body>
<div id="root"></div>
</body>
</html>
rollup.config.jsを追加
import resolve from "@rollup/plugin-node-resolve";
import { babel } from "@rollup/plugin-babel";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import { terser } from "rollup-plugin-terser";
import postcss from "rollup-plugin-postcss";
import serve from "rollup-plugin-serve";
import replace from "@rollup/plugin-replace";
// rollupコマンドがwatchかどうかで、開発状態かビルド状態か判断する
// rollup -c -w -> watch
// rollup -c -> not watch
const watch = process.env.ROLLUP_WATCH;
const config = [
{
input: "examples/src/index.tsx",
output: {
file: `examples/public/bundle.js`,
format: "iife", // <script>タグで読み込むのに適したフォーマット
},
plugins: [
resolve(),
replace({
preventAssignment: true,
"process.env.NODE_ENV": JSON.stringify("development"), // スクリプト内で指定した文字列を置換する。
}),
commonjs(),
postcss(),
typescript({ tsconfig: "tsconfig.demo.json" }), // TypeScript使用時のみ追加。tsconfigが複数ある場合はconfigファイルを指定。
babel({
exclude: "node_modules/**",
babelHelpers: "bundled",
}),
!watch && terser(), // ビルド時はバンドルファイルをminifyする。
watch &&
// ローカルでページを自動的に開く。今回はexamples/public/index.htmlが読み込まれる。
serve({
open: true,
verbose: true,
contentBase: ["", "examples/public"],
host: "localhost",
port: 3000,
}),
],
},
];
export default config;
package.jsonにスクリプト追加
npm run dev:demo / yarn dev:demo
=> ローカルでページ起動npm run build:demo / yarn build:demo
=> ビルド
...,
"scripts": {
...,
"dev:demo": "rollup --config rollup.config.js --watch",
"build:demo": "rollup --config rollup.config.js",
},
...,
これで準備はOK!
- 開発時は、
npm run dev:demo / yarn dev:demo
で開発環境を立ち上げる。 - デプロイ前には、
npm run build:demo / yarn build:demo
でビルド用ファイルを準備する。 - デプロイ時は、
npm run deploy:demo / yarn deploy:demo
でGithub Pageにデプロイ。
スクリプトは好みに応じて名前を変えたり、まとめたりしてもOKです。