結構前に「React+webpackでHello Worldを表示するまで」という記事を書いたのですが、あれからだいぶ環境が変わったので、改めて投稿します。
もし「ここおかしいよ!」って部分があればご指摘いただけるとありがたいです。
環境
Node.js 15.0.1
npm 7.6.0
下準備
ディレクトリを作成し、npm init
するところまでは一緒です。
mkdir project-name
cd project-name
npm init
インストール
必要なものをインストールします。
以前はwebpack-dev-serverを入れていましたが、webpack v5だとまだ対応していないようで、動かなかったため、今回は入れません。
代わりにwebpack-cli serveを使用します。
※2021/09/29
webpack-cli serveを使用する際もwebpack-dev-serverを入れる必要があるようです。
# webpack
npm install --save-dev webpack webpack-cli webpack-dev-server
# babel
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-react babel-loader
# react
npm install --save-dev react react-dom
TypeScript使いたいのでこれもインストールします。
npm install --save-dev typescript ts-loader
npm install --save-dev @babel/preset-typescript @types/react @types/react-dom
スタイルシート関連です。
mini-css-extract-pluginはCSSのみ別ファイルに書き出すために必要。
npm install --save-dev css-loader sass-loader style-loader node-sass
npm install --save-dev mini-css-extract-plugin
webpackの設定
webpack.config.js を作成し、以下を記述します。
コンポーネントなどのファイルを保存するディレクトリが「src」、ローカルサーバー用のディレクトリが「public」、ビルドしたファイルの保存先が「dist」です。
以前はbabelの設定を別ファイルにしていましたが、こちらにまとめています。
modeは適宜書き換えてください。
watchオプション入れていますが、こちらも特に必要ない場合はfalseで。
※2021/09/29
devServerの設定を修正
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: {
app: './src/index.tsx'
},
output: {
filename: 'js/[name].bundle.js',
path: `${__dirname}/dist`
},
module: {
rules: [
{
test: /\.ts[x]?$/,
exclude: /node_modules/,
use: 'ts-loader'
}, {
test: /\.(sa|sc|c)ss$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { url: false }
},
'sass-loader'
]
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
target: ['web', 'es6'],
plugins: [
new MiniCssExtractPlugin({
filename: 'css/app.css'
})
],
watch: true,
watchOptions: {
ignored: /node_modules/
},
devServer: {
static: {
directory: `${__dirname}/public`
},
compress: true,
port: 8080,
open: true
// open: true,
// contentBase: `${__dirname}/public`
}
};
package.jsonの設定
コマンドでwebpackのどの機能を実行するかを設定します。
npm start
でローカルサーバー起動、npm run build
でビルド出来るようになります。
--mode development
の部分は適宜書き換えてください。
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
// ここを編集
"build": "webpack",
"start": "webpack-cli serve --mode development",
"test": "echo \"Error: no test specified\" && exit 1"
},
...
}
TypeScriptの設定
TypeScriptのための設定ファイルを用意します。
正直オプション多すぎてよくわかっていません...
{
"compilerOptions": {
"sourceMap": true,
"target": "es6",
"module": "es2015",
"jsx": "react",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"lib": [
"es2020",
"dom"
],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
"include": [
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
Hello Worldを表示
表示用のテンプレートを作成します。
JS、CSSは自動で読み込まれないので、webpackで設定した名前のファイルを読み込むよう記述します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- ビルドするCSSファイル -->
<link rel="stylesheet" href="css/app.css">
<!-- 追加で読み込みたい場合は、public内に保存して読み込む -->
<link rel="stylesheet" href="css/plugins.css">
</head>
<body>
<div id="root"></div>
<!-- ビルドするJSファイル -->
<script src="js/app.bundle.js"></script>
</body>
</html>
reactで文字を表示。
import React from "react"
import ReactDOM from "react-dom"
ReactDOM.render(
<h1>Hello World!</h1>,
document.getElementById("root")
)
npm start
でサーバーを起動して、http://localhost:8080 にアクセスします。
「Hello World!」と表示されれば完了です。
最終的な構成
src/components内にコンポーネントを保存して、index.tsxでインポートします。
├─ dist // ビルドしたファイルの保存先
├─ node-modules
├─ public // ローカルサーバー用のファイル
│ ├─ index.html
├─ src
│ ├─ components // 作成したコンポーネントを保存
│ └─ index.tsx
├─ package.json
├─ package-lock.json
├─ tsconfig.json
└─ webpack.config.js
おまけ
ファイルを分割する
よく1つのファイルにまとめて書き出そうとして「重いよ!」って怒られるので、分割します。
ビルドすると、app.bundle.jsとplugins.bundle.jsが作成されます。
module.exports = {
...
entry: {
app: './src/index.tsx',
plugins: './src/plugins.tsx'
},
output: {
filename: 'js/[name].bundle.js',
path: `${__dirname}/dist`
},
...
参考
参考にさせていただきました。ありがとうございます。
tsconfig.jsonの全オプションを理解する(随時追加中)
webpack.config.js の書き方をしっかり理解しよう
webpack v5 npx webpack-dev-server で dev server が動かないにハマる