LoginSignup
10
5

More than 5 years have passed since last update.

React.js 開発環境を webpack4 + webpack-serve + babel 7 で作る(Deprecated)

Last updated at Posted at 2018-08-13

追記: webpack-serve は非推奨となり webpack-dev-server が開発再開しました。新しく始める際はスタックに webpack-serve を採用しないほうがよいでしょう。webpack-dev-server で同じような内容を書き残したのがこちら


なんか普段開発しているフロントアプリケーションが依存しているツールスタックがそれぞれ少しずつバージョンあがっているので、手軽に環境用意するための手順を備忘録がてら書いておきます。この記事の流れで React-Router 利用時のフォールバックコンテンツ返す設定は別に書いた

  • webpack 4.x
  • webpack-serve 2
  • babel 7
  • babel-loader 8
  • react 16.4.x
  • node 10.8.0, npm 6.2.0

※ babel 7, babel-loader 8 がそれぞれリリースされました。

プロジェクト初期化とパッケージのインストール

以下、適当なプロジェクトディレクトリを作成してその中で行います。

npm init -y
npm install react react-dom
npm install --save-dev webpack webpack-serve webpack-cli
npm install --save-dev @babel/preset-env @babel/cli @babel/core @babel/preset-react
npm install --save-dev babel-loader style-loader css-loader html-webpack-plugin
npm install --save-dev babel-plugin-transform-class-properties

※ babel は 6系までは babel- って命名なので、スコープ付きパッケージを指定すると自動的に7系最新が入ります。

babel-plugin-transform-class-properties は実質的に必須なのでサンプルコードでは使っていませんが入れています。

ファイルレイアウトを決める

以下のような構成にすることにします。

├── src/
│   └── index.css
│   └── index.js
│   └── index.html
├── dist/
├── package.json
├── babel.config.js
└── webpack.config.js

当初JS以外は public/ 以下に静的ファイルとして置いていましたが、エントリポイントとなるHTMLは html-webpack-plugin で出力し、CSSは style-loader でJSに組み込む形に変えました。全部 webpack 経由でまとめた方が開発サーバでのリロードの挙動などが快適なことに気が付きました。またキャッシュバスター埋め込みなどを考えてもHTMLはwebpack管理下の方が何かと楽です。

webpack.config.js を置く

webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    mode: process.env.WEBPACK_SERVE ? 'development' : 'production',
    entry: {
      main: path.resolve(__dirname, './src/', "index.js")
    },
    output: {
        path: path.resolve(__dirname, './dist/'),
        publicPath: '/',
        filename: '[name]-[hash].js'
    },
    module: {
      rules: [
      {
        test: /\.jsx?$/,
        exclude:[ /node_modules/ ],
        loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        exclude: [/node_modules/],
        use: ["style-loader", { loader: "css-loader", options: { url: false, modules: true } }]
      }]
    },
    devtool: 'source-map',
    serve: {
        open: true,
        port: 8080,
        content: path.resolve(__dirname, 'public'),
    },
    plugins: [new HtmlWebpackPlugin({ template: "src/index.html" })]
}

ここでは serve.config.js をおかず webpack.config.js に webpack-serve の設定も書いています。css-loaderoptions: { modules: true } で CSS Modules サポートです。

babel.config.js を置く

babel.config.js
module.exports = {
  presets: [
    "@babel/preset-env", 
    "@babel/preset-react"
  ],
  plugins: ["transform-class-properties"]
}

src/index.js を作成する

import React from "react";
import { render } from "react-dom";
import "./index.css";

class App extends React.Component {
  render() {
    return (
      <div>
        <h1> Hello React!</h1>
        <p> this is a component.</p>
      </div>
    );
  }
}

render(<App />, document.getElementById("content"));

#content 要素に <App /> をマウントする簡単なコードです。

src/index.css を作成する

懐かしい感じに黒背景に白文字にします。

body {
  color: #fff;
  background-color: #000;
}

src/index.html を作成する

html、header、body などは省略しています。script 要素は webpack-html-plugin が補完してくれるので、Reactの描画ターゲットとなるdiv要素一つだけを置いています。

<div id="content"/>

開発サーバで実行する

$ npx webpack-serve

サーバが 8080 番ポートで立ち上がり、ブラウザが起動すると思います。(http://0.0.0.0:8080

この時、環境変数 WEBPACK_SERVE が設定されるため、webpack の mode には development が設定されます。ブラウザで開いたまま index.js を編集すると、livereload 的に再読込が走っていることがわかります。

スクリーンショット 2018-08-16 9.37.31.png

ビルドする

webpack コマンドでビルドを行います。

development

$ npx webpack --mode development

Hash: f368235ab2e8b186dd35
Version: webpack 4.17.1
Time: 1253ms
Built at: 2018-08-29 06:22:59
                           Asset      Size  Chunks             Chunk Names
    main-f368235ab2e8b186dd35.js   712 KiB    main  [emitted]  main
main-f368235ab2e8b186dd35.js.map   820 KiB    main  [emitted]  main
                      index.html  95 bytes          [emitted]
Entrypoint main = main-f368235ab2e8b186dd35.js main-f368235ab2e8b186dd35.js.map
[./node_modules/css-loader/index.js?!./src/index.css] ./node_modules/css-loader??ref--5-1!./src/index.css 213 bytes {main} [built]
[./src/index.css] 1.08 KiB {main} [built]
[./src/index.js] 2.78 KiB {main} [built]
    + 24 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 215 bytes {0} [built]
    [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 489 bytes {0} [built]
    [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 1 hidden module

production

$ npx webpack --mode production
Hash: 931ddeccf4361df4a522
Version: webpack 4.17.1
Time: 1263ms
Built at: 2018-08-29 06:27:30
                           Asset      Size  Chunks             Chunk Names
    main-931ddeccf4361df4a522.js   107 KiB       0  [emitted]  main
main-931ddeccf4361df4a522.js.map   270 KiB       0  [emitted]  main
                      index.html  95 bytes          [emitted]
Entrypoint main = main-931ddeccf4361df4a522.js main-931ddeccf4361df4a522.js.map
 [6] ./src/index.js 3.11 KiB {0} [built]
[15] ./src/index.css 1.08 KiB {0} [built]
[16] ./node_modules/css-loader??ref--5-1!./src/index.css 213 bytes {0} [built]
    + 17 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html 215 bytes {0} [built]
    [2] (webpack)/buildin/global.js 489 bytes {0} [built]
    [3] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 1 hidden module

約700kbから約100kbと、production ビルドにするとちゃんと minify かかっていますね。(そしてけっこう大きい)

package.json に script を追加する

します。

  "scripts": {
    "start": "npx webpack-serve",
    "build": "npx webpack --mode production",

これで npm start して開発サーバが立ち上がるようになりました。

まとめ

登場人物としては以下だけです。

  • package.json
  • webpack.config.js
  • babel.config.js
  • index.html
  • index.js
  • index.css
10
5
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
10
5