Go to list of users who liked
More than 1 year has passed since last update.
Webpackを一歩一歩確実に理解してReact + TypeScript環境を作る (2022/10/31 追記)
2022/10/31 追記
2022年時点ではWebpackでReactの環境を構築するより、Viteを用いて環境構築するほうがメジャーになっています。
筆者としても新規開発するならWebpackより、Viteの方で構築することをおすすめします。
ViteではReactのビルド用設定はPluginとしてパッケージされており、Webpackのように設定が必要ではありません。
下記はWebpack v4の話であり、すでに過去の物となっています。
※自分のブログに投稿したのものと同じです。
https://mr-ozin.hatenablog.jp/entry/2020/06/20/043243
動機
毎回npx create-react-app
で React アプリを生成していて Webpack の勉強から逃げていたが、いい加減向き合いたいと思ったため。
昔 Webpack に入門しようとしたら難しいという先入観を抱いたので、できるだけシンプルに、一歩一歩づつ入門する。
最終的に、React + TypeScript の環境を作れるようにする。
リポジトリ
各ステップごとにコミットしているので逐次さかのぼってください。
https://github.com/ryokryok/webpack-step-by-step
前提
- 最低限の
yarn
またはnpm
コマンドの使い方がわかること。 npx create-react-app
で React プロジェクトを作成した事があること。
※VSCode 使用を前提としています。
Config なしで実行する
最低限の構成で Webpack が何をするのか理解する。
準備
# run at project directoryyarn init-y# generate package.jsonyarn add webpack webpack-cli-Dmkdirsrctouchsrc/index.jstouchsrc/a.jstouch .gitignore
node_modules/dist/
importafrom"./a";a();
exportdefault()=>console.log("function called");
実行
2 つの JavaScript ファイルはimport/export
で読み込まれている。
これらを Webpack で Bundle(梱包、まとめる)を行うことで依存関係が解決された 1 つの JavaScript を生成できる。
# mode を指定しない場合は自動的に production モードで実行されるyarn webpack--mode productionHash: 812c3c2bfa797a640163Version: webpack 4.43.0Time: 132msBuilt at: 2020-06-18 23:07:37 Asset Size Chunks Chunk Namesmain.js 982 bytes 0[emitted] mainEntrypoint main= main.js[0] ./src/index.js + 1 modules 79 bytes{0}[built] | ./src/index.js 26 bytes[built] | ./src/a.js 53 bytes[built]✨ Donein1.16s.
!(function(e){// 省略...})([function(e,t,n){"use strict";n.r(t);console.log("function called");},]);
Webpack は Config ファイルなしではdist/main.js
にまとめられる。
https://webpack.js.org/configuration/
Out of the box, webpack won't require you to use a configuration file. However, it will assume the entry point of your project is src/index.js and will output the result in dist/main.js minified and optimized for production.
Config ファイルを設定する
Webpack の最低限の働きが理解できたので、次は Config ファイルを設定する。
まずは Bundle するファイル、Bundle で出力されるファイルを明示的に指定する。
準備
webpack.config.js
を作成して設定する。設定用の JavaScript オブジェクトを書いて、module.exports
すれば良い。
ついでに、npm script を設定して実行を単調なコマンドで実行できるようにする。
touchwebpack.config.js
constpath=require("path");module.exports={// 入力元entry:"./src/index.js",// 出力先output:{path:path.resolve(__dirname,"output"),filename:"bundle.js",},};
- }+ },+ "scripts": {+ "build": "webpack --mode production"+ }
実行
出力先を変更したので実行するとoutput/bundle.js
に出力される。
yarn build$webpack--mode productionHash: c4b26abe6d1df8044083Version: webpack 4.43.0Time: 173msBuilt at: 2020-06-18 23:46:27 Asset Size Chunks Chunk Namesbundle.js 982 bytes 0[emitted] mainEntrypoint main= bundle.js[0] ./src/index.js + 1 modules 79 bytes{0}[built] | ./src/index.js 26 bytes[built] | ./src/a.js 53 bytes[built]✨ Donein1.63s.
自動更新と開発用サーバーを実行する
現段階では変更があるたびに毎回yarn build
する必要がある。これでは面倒なので、ファイルが保存されるたびに自動的に変更を反映させる。
HTML ファイル内で JavaScript を実行したときの環境を作成する。
準備
開発環境用サーバー& build 用にwebpack-dev-server
とhtml-webpack-plugin
を導入する。
導入する Plugin はwebpack.config.js
のplugins
に追加する。
public
ディレクトリーにindex.html
を作成する。JavaScript が HTML 内で動作していることを確認するするため、実行されると<div id='root'>
内の文字が変わるようにした。
html-webpack-plugin
の設定にてtemplate:
に作成した HTML のパスを設定する。これによって開発用サーバーが立ち上がると指定した HTML に自動的に JavaScript を注入し、変更があるたびに更新する。
https://github.com/jantimon/html-webpack-plugin#options
yarn add webpack-dev-server html-webpack-plugin-Dmkdirpublictouchpublic/index.html
<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>Document</title></head><body><divid="root">JavaScript will be injected here.</div></body></html>
constendPoint=document.getElementById("root");exportdefaultfunctiona(){endPoint.innerHTML="JavaScript is injected!";}
constpath=require("path");constHtmlWebpackPlugin=require("html-webpack-plugin");module.exports={entry:"./src/index.js",output:{path:path.resolve(__dirname,"dist"),filename:"bundle.js",},plugins:[newHtmlWebpackPlugin({template:path.resolve(__dirname,"public/index.html"),}),],};
"scripts": { "build": "webpack --mode production",+ "start": "webpack-dev-server"},
実行
yarn start
で開発用サーバーがhttp://localhost:8080/
で立ち上がる。
無事 JavaScript が実行されている場合、JavaScript will be injected here.
の箇所がJavaScript is injected!
に置き換わっている。a.js
の文字列を書き換えて保存すると自動的に反映される。
またhtml-webpack-plugin
を導入したのでyarn build
時にindex.html
も出力してくれる。これを導入しない場合、bundle.js
しか出力されない。
https://webpack.js.org/plugins/html-webpack-plugin/#root
# launch dev sever at http://localhost:8080/`yarn start# build dist/bundle.js and dist/index.htmlyarn build
TypeScript を扱えるようにする
現段階では JavaScript しか扱えない。Webpack では様々なファイルを取り扱えるようにするため、各ファイルごとにloader
が提供されている。
今回は TypeScript の loader、ts-loader
を導入する。
https://webpack.js.org/loaders/#root
準備
typescript
とts-loader
を導入する。
TypeScript を実行するときはtsconfig.json
も必要なので設定する。
今回はyarn tsc --init
で生成したものからコメント行を削除した。
(2020/7/23 追記)tsconfig.json
に"moduleResolution": "node",
追記。
また、tsconfig.json
にて"module": "ESNext"
を指定すること。(標準では"CommonJS" が指定されている)
Webpack の Tree Shaking(未使用の JavaScript を削ってファイルサイズを軽減する機能)を働かせるために必要。
webpack.config.js
にはts-loader
が拡張子.ts
のファイルに対して働くようにする。
また、resolve.extensions
で拡張子を指定しておくと、その拡張子はimport
時に省略できる。
TypeScript ファイルで実行するため JavaScript ファイルの拡張子を.js
から.ts
に変更する。
yarn add typescript ts-loader-D# generate tsconfig.jsonyarn tsc--initmvsrc/index.js src/index.tsmvsrc/a.js src/a.ts
{"compilerOptions":{"target":"es5","module":"ESNext","strict":true,"esModuleInterop":true,"skipLibCheck":true,"moduleResolution":"node","forceConsistentCasingInFileNames":true}}
constpath=require("path");constHtmlWebpackPlugin=require("html-webpack-plugin");module.exports={entry:"./src/index.ts",output:{path:path.resolve(__dirname,"dist"),filename:"bundle.js",},module:{rules:[{test:/\.ts$/,use:"ts-loader",},],},resolve:{extensions:[".ts",".js"],},plugins:[newHtmlWebpackPlugin({template:path.resolve(__dirname,"public/index.html"),}),],};
constendPoint=document.getElementById("root");exportdefaultfunctiona(){// null check for endPointif(endPoint)endPoint.innerHTML="JavaScript is injected, from TypeScript";}
実行
先程と同じ。TypeScript は JavaScript に変換され、Webpack によって 1 つの JavaScript ファイルにまとめられる。
# launch dev sever at http://localhost:8080/`yarn start# build dist/bundle.js and dist/index.htmlyarn build
React + TypeScript を扱えるようにする
最後に、TypeScript 環境で React(TSX)を扱えるようにする。が、実は前項にてほぼ準備は済んでいる。
TypeScript のコンパイラは TSX をサポートしているため、設定を少し加えて React のライブラリと型ファイルを読み込むめば済む。
https://www.typescriptlang.org/docs/handbook/jsx.html
準備
React のライブラリと型ファイルを導入する。
webpack.config.js
には、entry
、loader 用のtest
、resolve.extensions
を変更する。
tsconfig.json
には"jsx": "react"
を追記するだけ。
yarn add react react-dom @types/react @types/react-domtouchsrc/index.tsxtouchsrc/App.tsx
constpath=require("path");constHtmlWebpackPlugin=require("html-webpack-plugin");module.exports={entry:"./src/index.tsx",output:{path:path.resolve(__dirname,"dist"),filename:"bundle.js",},module:{rules:[{test:/\.tsx?$/,use:"ts-loader",},],},resolve:{extensions:[".tsx",".ts",".js"],},plugins:[newHtmlWebpackPlugin({template:path.resolve(__dirname,"public/index.html"),}),],};
{"compilerOptions":{"jsx":"react","target":"es5","module":"ESNext","strict":true,"esModuleInterop":true,"skipLibCheck":true,"moduleResolution":"node","forceConsistentCasingInFileNames":true}}
importReactfrom"react";exportdefaultfunctionApp(){return<div>Hello React with TypeScript</div>;}
importReactfrom"react";importReactDOMfrom"react-dom";importAppfrom"./App";ReactDOM.render(<App/>,document.getElementById("root"));
実行
前項と同じ。yarn start
とyarn build
まとめ
というわけで0から順を追ってちょっとづつ追加した。
説明においては「これはおまじないです」というのをできるだけ避けた。
初見ではWebpackのConfigファイルが複雑に見えるかもしれないが、設定を1つ1つ、意味を確認しながら追加すれば難しくなかった。
あとはCSSを読み込むためにstyle-loader
を入れたりして作りたいものに合わせてカスタマイズする。
参考
https://mizchi.hatenablog.com/entry/2020/05/03/151022
https://ics.media/entry/16329/
https://webpack.js.org/guides/
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme