# ⚪️ Webpack 深い理解と実践
# 🔶 Webpack とは?
Webpack は複数の JavaScript ファイルを一つのファイルにまとめて出力するツールです。この「一つのファイルにまとめる」ことをバンドル(bundle)と言い、また「モジュールを一つのファイルにまとめて出力するツール」のことをモジュールバンドラー(module bundler)と呼びます。
公式 Document で Webpack は、👇 のように静的モジュールバンドラーと紹介されています。
webpack is a static module bundler for modern JavaScript applications
公式には 👇 のような図が記載されています。バンドルの雰囲気がわかりやすいですね。 Concepts | webpack (opens new window)
# 🔶 なぜ Webpack を使うのか?
複数の JavaScript ファイルを一つにまとめることで、ブラウザからのリクエスト数を減らし、ファイル転送の最適化が可能です。これが Webpack などのモジュールバンドラーを使う大きな理由です。
JavaScript ファイルが複数存在することでリクエスト回数が増えて転送効率が落ちるのであれは、最初から一つのファイルに記載することも可能ですが、可読性や保守性などの観点から現実的でありません。また、機能を複数ファイルに分割したままだと、ブラウザからのリクエスト回数が増えてファイル転送効率が落ちます。こういったつらみに対して、Webpack を利用することで機能をファイルごとに分割しながら開発し、実行時は一つのファイルとしてブラウザに提供することが可能となります。
👇 の記事では、dev ツールで実際のファイルサイズを細かく見ながら、Webpack のメリットについて言及されていますので、参考までに。 Why am'I using the webpack tool? (opens new window)
- Learn more about the CLI! (opens new window)
- Learn more about modules! (opens new window)
- Learn more about the Node API! (opens new window)
- Learn more about loaders! (opens new window)
- Learn more about plugins! (opens new window)
# 🔶 Webpack の詳細?
# ▫️ Loader for Different Resource Types
Webpack uses loaders for different resource types, such as:
- CSS:
css-loader
,style-loader
- Less:
less-loader
- Sass:
sass-loader
- JavaScript:
ts-loader
,babel-loader
- Vue:
vue-loader
- Static Resources:
url-loader
(images, audio, video),file-loader
(files),json-loader
(JSON)
# ▫️ Basic Functions of Webpack (Using Loaders)
- Code Transformation: TypeScript to JavaScript, ES6 to ES5, SCSS to CSS, etc.
- Code Syntax Checking: Automatic code syntax checking using
eslint-loader
. - Code Splitting: Splitting code into chunks for on-demand loading, reducing initialization time, and improving first-screen rendering efficiency.
- Automatic Compilation and Page Refresh: Automatically compile and refresh the page on local source code changes.
- Automatic Deployment (Not commonly used): Automatically build and deploy code to the production system.
- File Compression: Compress JavaScript, CSS, and HTML files to reduce file size.
- Module Concatenation: Merge modules into a single file during compilation.
# ▫️ Two Key Features of Webpack
- Code Splitting: Breaks down code into chunks for on-demand loading, reducing initialization time.
- Loader: Handles various types of static files and supports chaining operations.
# ▫️ Webpack Configuration
Webpack runs in the Node.js environment, and its configuration file (webpack.config.js
) follows the CommonJS pattern. It exports a JSON object with the following basic configuration options:
entry
: Specifies the entry point of the modules.output
: Configures output file locations, names, and base paths.module
: Configures rules for different file types.resolve
: Configures aliases or module resolution rules.plugins
: Configures additional plugins to extend Webpack's functionality.devServer
: Implements local HTTP server features.
# ▫️ Webpack Build Process
- Start from the entry point and recursively transform dependent modules.
- For each module found, use the corresponding loader to transform it.
- Continue transforming the dependencies of the current module until there are no more dependencies.
- Group modules by entry point, creating chunks.
- Convert all chunks into output files.
# ▫️ Common Plugins
- html-webpack-plugin: Generates HTML pages based on a template.
- clean-webpack-plugin: Cleans specified directories.
- copy-webpack-plugin: Copies files.
- uglifyjs-webpack-plugin: Minifies JavaScript code.
- mini-css-extract-plugin: Extracts CSS into separate files.
# ▫️ Difference Between Loader and Plugin
- Loader: Acts as a translator, transforming non-JavaScript resources during the build process.
- Plugin: Extends Webpack's functionality by listening to events and altering the output.
# ▫️ Webpack Hot Module Replacement (HMR) Principle
HMR allows modules to be replaced without refreshing the entire page. The key steps include establishing a WebSocket connection, monitoring file changes, and notifying the client about the changes.
# ▫️ Webpack Build Speed Optimization
Use the latest Webpack and Node.js versions.
Minify code using plugins like
uglifyjs-webpack-plugin
.Utilize multiple threads or processes for building (e.g.,
thread-loader
orHappyPack
).Narrow down the scope of file resolution.
Leverage caching for faster secondary builds.
Implement Tree Shaking to eliminate unused code.
Optimize module dependencies using Scope Hoisting.
Use CDN for basic packages to reduce bundle size.
Separate CSS from JavaScript using
mini-css-extract-plugin
.
# ▫️ webpack-bundle-analyzer
webpack を可視化するツールを紹介 (opens new window)
# Basic Steps for Configuring and Using webpack-bundle-analyzer:
Install the webpack-bundle-analyzer plugin using the following command in your project directory:
npm install --save-dev webpack-bundle-analyzer
In your webpack configuration file (e.g., webpack.config.js), import the webpack-bundle-analyzer plugin:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
Add a new instance of BundleAnalyzerPlugin to the
plugins
property in your webpack configuration file:module.exports = { // ... plugins: [new BundleAnalyzerPlugin()], // ... };
Save your webpack configuration file and run your webpack build command. After the build is complete, webpack-bundle-analyzer will open a page on a server where you can view detailed analysis results.
# ▫️ Conditional Usage in Development Environment:
const BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
let plugins = [];
if (process.env.NODE_ENV === "development") {
plugins.push(new BundleAnalyzerPlugin());
}
module.exports = {
//...
plugins: plugins,
//...
};
In this code, the BundleAnalyzerPlugin
is added to the plugins
array only when the NODE_ENV
is set to 'development'. This helps in avoiding the generation of additional data in the production environment.
# ▫️ Detailed Configuration Options for BundleAnalyzerPlugin:
new BundleAnalyzerPlugin({
// Accepts a string to specify the format and channel of the generated report. It can be 'server', 'static', or 'disabled'.
// 'server' starts an HTTP server to provide an interactive report view, defaulting to localhost:8888.
// 'static' generates a single HTML file to describe the report.
// 'disabled' can be useful in some scenarios to temporarily disable the plugin while keeping the configuration code.
analyzerMode: "server",
// In 'server' mode, defines the hostname for the HTTP server.
analyzerHost: "127.0.0.1",
// In 'server' mode, defines the port number for the HTTP server.
analyzerPort: 8888,
// In 'static' mode, defines the filename for the generated report.
reportFilename: "report.html",
// Defines the method for calculating module sizes. Can be 'stat', 'parsed', or 'gzip'.
// 'stat' describes the size before any code is parsed (size between modules).
// 'parsed' describes the size of all parsed code (code that has been processed and parsed by loaders).
// 'gzip' describes the gzip size of all parsed code (if this value is defined).
defaultSizes: "parsed",
// Specifies whether a module should be shown. You can use this option to hide unnecessary modules.
// You can pass a function that takes a module as a parameter and returns a boolean value.
filterModules: false,
// If you want the content of the generated report file to be a custom data structure, you can pass a function.
// This function receives stats data as a parameter and should return a serialized JSON object or a Promise.
generateStatsFile: false,
// If you want to customize the filename of the generated stats file, you can modify this option.
statsFilename: "stats.json",
// Defines whether to generate a report when generating stats files.
statsOptions: null,
// Defines a logging function.
logLevel: "info",
});
analyzerMode
: Specifies the format and channel for report generation ('server', 'static', or 'disabled').analyzerHost
andanalyzerPort
: Define the hostname and port for the HTTP server in 'server' mode.reportFilename
: Specifies the filename for the generated report in 'static' mode.defaultSizes
: Defines how module sizes should be calculated ('stat', 'parsed', or 'gzip').filterModules
: A function to determine whether a module should be displayed in the report.generateStatsFile
: Allows customization of the generated stats file content using a function.statsFilename
: Specifies the filename for the generated stats file.statsOptions
: Defines options for generating stats files.logLevel
: Defines the log level for the plugin.