やったこと
reactの環境構築についての勉強
webpackについて
複数のファイルを1つにまとめて出力してくれるツール
(複数ファイルをまとめることを「バンドル」と呼ぶ)
メリット
- コードが読みやすくなる
- 保守性が高くなる
- コードを他プロジェクトに転用しやすくなる
- JSだけでなく、CSSや画像もバンドルできる
- 包括的な開発環境が整う(開発作業の分担やテストがしやすくなる)
現代フロントエンドに欠かせないwebpackとBabelを理解しよう! builderscon tokyo 2019
JSにはECMAScriptという言語仕様がある
この仕様を決めているのがTC39委員会
Babelとは?
JSのコンパイラ
元々は6to5という名前だった
- ES6からES5へのコードを変換する機能しか持ってなかった
- しかし、それ以外の機能も必要なため名前が合わない -> Babelに
使用できるJSはブラウザによって異なるためBabelが必要になる
これによって新しいJSを各ブラウザで使用できる
Babelの機能
- 構文変換
- ソースコードの変換(codemods)
- ターゲットブラウザにない環境のPolyfillの提供
コードをどのように変換するのか?
- Parsing: @babel/parser
- ソースコードをAbstract Syntax Tree(AST)に変換する
- Transformation
- ASTを変換するBabelのプラグインがこの役割を担っている
- Code Generat: @babel/generator
- ASTをソースコードに変換する
webpackとは?
JSだけでなく、img, cssなどもモジュール化する
依存関係も解決する
webpackの誕生
CommonJSをブラウザ用に変換する「modules-webmake」があった
これに対してCode Splitting機能を追加する提案をしたが受け入れられなかったので、勝手にforkして開発したのがwebpack
webpackのコンセプト
- Entry
- 起点となるファイルを指定
- Output
- 処理が完了したファイルを出力する
- Loaders
- 指定ファイルに任意の処理を加える、1つのタスク
- Plugins
- webpackのさまざまなイベントをhookし、データを操作したり処理を実行する
- Mode
- none, development, productionを指定してmodeに応じてパフォーマンス最適化や圧縮などを行う
- Browser Compatibility
- ブラウザの後方互換性
実行
- ./bin/webpack.jsを実行
- その中で./bin/webpack-cliを実行
- webpack.comfig.jsを読み込む
参考動画 現代フロントエンドに欠かせないwebpackとBabelを理解しよう! (sakito) - builderscon tokyo 2019
さぁ何はともあれwebpackの公式を読もう
Concepts
- Entry
- Output
- Loaders
- Plugins
- Mode
- Browser Compatibility
Entry Points
Single Entry (Shorthand) Syntax:
Usage: entry: string | [string]
module.exports = {
entry: './path/to/my/entry/file.js',
};
entryを設定していない場合、webpackは
./src/index.jsを./dist/main.jsに出力する
という挙動になる
細かく書くと、
- ./src/index.jsをエントリーポイントとし
- index.js内でimport、requireされ使われているファイルをバンドルして
- ./dist/main.jsに出力する という動き
webpackの基本だけどハマりやすいentryの設定と[name]
Output
module.exports = {
output: {
filename: 'bundle.js',
},
};
複数のEntrypointの場合
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js',
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
};
// writes to disk: ./dist/app.js, ./dist/search.js
mode
mode プロパティのパラメーターを development、production、または none に設定することにより各環境に対応する最適化を有効にする
- development:開発時向けのオプション(ソースコードが読みやすい状態で出力)
- production:本番環境(公開時)向けのオプション(ソースコードを圧縮及び最適化)
- none: 最適化を行わない
Loaders
説明をdeepLにかけてみた
ローダーとは、モジュールのソースコードに適用される変換のことです。これを使うと、ファイルをインポートしたり「ロード」したりするときに、前処理をすることができます。このように、ローダーは他のビルドツールにおける「タスク」のようなもので、フロントエンドのビルドステップを処理するための強力な方法を提供します。ローダーは、異なる言語(TypeScriptなど)のファイルをJavaScriptに変換したり、インライン画像をデータURLとして読み込んだりすることができます。ローダーは、JavaScriptモジュールからCSSファイルを直接インポートするようなことも可能です!
Loadersとは
webpackはJavaScriptファイルのみそのままの状態で取り扱うことができる。
しかしJavaScriptファイル以外の他の言語で書かれたプログラムをwebpackで扱うことができない。
JavaScript以外のファイルでもwebpackでも扱えるようにする場合にはLoader(ローダー)を利用する必要がある。
Loaderは一つではなくそれぞれの言語や行いたい処理に対応するLoaderが存在する。
typescriptとts-loader
module: {
rules: [
{
test: /\.ts$/, // 拡張子 .ts のファイルを
use: 'ts-loader', // ts-loaderでトランスパイルする
exclude: /node_modules/, // ただし外部ライブラリは除く
},
],
},
ローダーの設定は module プロパティの rules
プロパティで test
と use
の2つのプロパティを使って設定する
入門者/初心者にもわかるwebpack5の基礎(Loader編)
css-loader
webpack で CSS を扱うには、CSS を変換するローダー(css-loader)が必要
更に、変換した CSS を DOM に挿入するローダー(style-loader)または CSS を別ファイルとして出力するプラグイン(MiniCssExtractPlugin)も必要
開発モード(webpack-dev-server を含む)の場合、style-loader を使用すれば CSS を DOM に挿入することで、より高速に動作する
Plugins
webpackでESLintが使える環境を構築してみる
$ npm install --save-dev eslint eslint-webpack-plugin
「eslint-webpack-plugin」のパッケージをインストール
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin(options)],
// ...
};
そしてwebpackの設定に追加する
context
タイプ: String
Default: compiler.context
ファイルのルートを示す文字列。
devtool ソースマップ
devtool オプションを使うと出力されるソースマップを設定することができる
devtool オプションにソースマップのタイプを指定してビルドすると、出力ファイルと同じディレクトリに出力ファイルと同じ名前で拡張子が「.js.map」のソースマップファイルが作成される
ビルドするとdistフォルダにmain.js.mapが作成される
dist
├── index.html
├── main.js
└── main.js.map //ソースマップファイル
resolve
webpack には import を使ってモジュールをインポートする際に、指定されたモジュールを検索して該当するファイルを探す仕組みがある
resolve オプションはモジュール解決(モジュールの import を解決する仕組み)の設定を変更する
resolve.modules
モジュールを解決するときに検索するディレクトリを webpack に指示する
module.exports = {
//...
resolve: {
modules: ['node_modules']
}
};
resolve.extentions
このオプションで指定されている拡張子のファイルは import の際に拡張子を省略することができる
extensions: [".ts", ".tsx", ".js"],
この設定をするとこれらのimport時に拡張子を省略できる