本授業の重点内容#
- フロントエンドの「エンジニアリング」概念、ツール、目標を理解する
- チームには必ず Webpack に精通した人が数人必要であり、ある意味で個人のコア競争力となる
- 高階フロントエンドへの道
コース目標:
- Webpack の基本的な使い方を理解する
- Webpack の機能、Loader と Plugin コンポーネントの設計を紹介し、知識体系を構築する
- すべてを詳細に紹介するわけではなく、Webpack の全てを紹介するわけでもない
- また、ソースコードを深く掘り下げて底層の実装原理を解説するわけでもない
Webpack とは何か#
フロントエンドプロジェクトは何で構成されているのか? —— リソース
旧時代は手動でこれらのリソースを管理していましたが、以下のような開発効率に大きな影響を与える欠点がありました:
- 手作業に依存しているため、例えば 50 個の JS ファイルがある場合……操作が煩雑
- コードファイル間に依存関係がある場合、依存順序に厳密に従って記述しなければならない
- 開発環境と本番環境が一致せず、TS や JS の新機能を取り入れるのが難しい
- Less、Sass などのツールを取り入れるのが難しい
- JS、画像、CSS リソース管理モデルが一致しない
その後、多くのフロントエンドエンジニアリングツールが登場し、特に Webpack が登場しました。
Web は本質的にフロントエンドリソースのコンパイル、バンドルツールです。
- 複数のリソースファイルを 1 つのバンドルにパッケージ化
- サポート
- Babel、Eslint、TS、CoffeScript、Less、Sass
- CSS、画像などのリソースファイルのモジュール化処理をサポート
- HMR + 開発サーバーをサポート
- 継続的監視、継続的ビルドをサポート
- コード分離をサポート
- Tree-shaking をサポート
- Sourcemap をサポート
- ...
Webpack バンドルの核心プロセス#
例#
-
インストール(管理者権限でコマンドラインを開くことに注意)
npm i -D webpack webpack-cli
-
設定ファイル webpack.config.js を編集
module.exports = { entry: 'main.js', // 現在のプロジェクトのエントリーファイルを定義 output: { // 現在のプロジェクトの出力ファイルを定義 filename: "[name].js", path: path.join(__dirname, "./dist"), }, module: {// 一部のloader関連の内容を定義、以下で見ることができる rules: [{ test: /\.less$/i, use: ['style-loader', 'css-loader', 'less-loader'] }] } }
-
コンパイルコマンドを実行
npx webpack
ステップ#
エントリー => 依存関係の検索 => 変換 => バンドル => 出力
極度に簡略化された版:
- entry のエントリーファイルからコンパイルを開始
- 依存関係の解析:
require
やimport
などの文に基づいて依存リソースを見つける module
設定に基づいて、リソーストランスフォーマーを呼び出し、非 JS リソースを JS コンテンツにコンパイルし、すべてのリソースが処理されるまで続ける- リソースの統合バンドル:トランスパイルされたリソースコンテンツを統合して、ブラウザで直接実行できる JS ファイルにパッケージ化
モジュール化 + 一貫性
- 複数のファイルリソースを 1 つに統合し、HTTP リクエスト数を削減
- モジュール化開発をサポート
- 高度な JS 機能をサポート
- Typescript、CoffeScript 方言をサポート
- 画像、CSS、フォントなどの他のリソースの処理モデルを統一
- その他...
主要な設定項目(どのように使用するか?)#
Webpack の使用方法は基本的に設定に基づいて展開され、これらの設定は大きく 2 つのカテゴリに分けられます:
- プロセスタイプ:プロセスの特定のまたはいくつかの段階に作用し、バンドル効果に直接影響を与える設定項目
- ツールタイプ:主プロセスの外で、より多くのエンジニアリング能力を提供する設定項目
ps:公式ドキュメントは確かに、あまり理解できない()
設定の概要:
使用頻度に応じて、主に以下の主要な設定項目があります
-
entry/output—— プログラムの入力と出力、必須
-
module/plugins
-
例えば、このプロジェクトでは less ファイルを読み込む必要があり、以下の loader をインポートする必要があります
-
-
mode
-
watch/devServer/devtool
Webpack を使用して CSS/less などを処理する#
-
Loader をインストール
npm add -D css-loader style-loader
-
module に CSS ファイルを処理するための設定を追加
思考問題#
- Loader はどのような役割を果たしますか?なぜここで css-loader、style-loader を使用する必要がありますか?
- 旧時代に HTML ファイルで CSS を維持するのと比較して、この方法にはどのような利点と欠点がありますか?
- Less、Sass、Stylus のような CSS プリプロセッサフレームワークに接触したことがありますか?Webpack でこれらのツールをどのように取り入れますか?
- 答:less に接触したことがあります
参考資料:
Webpack を使用して Babel を取り入れる#
-
依存関係をインストール
npm -D @babel/core @babel/preset-env babel-loader
-
エントリー
entry
と出力output
を宣言 -
module に CSS ファイルを処理するための設定を追加
module:{ rules:[ { test:/\.js?$/, use:[{ loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env' ] ] } }] } ] }
-
npx webpack
を実行
思考問題#
- Babel には具体的にどのような機能がありますか?
- Babel と Webpack はそれぞれどのような問題を解決しましたか?なぜ両者は協力できるのでしょうか?
参考資料:
Webpack を使用して HTML を生成する#
-
依存関係をインストール
npm i -D html-webpack-plugin
-
設定
const path = require( "path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: "./src/index",
output: {
filename:" [name]. js",
path: path.join(__dirname, "./dist"),
},
plugins: [new HtmlWebpackPlugin()]
};
npx webpack
を実行
思考問題#
- 手動で HTML コンテンツを維持するのと比較して、この自動生成の方法にはどのような利点と欠点がありますか?
参考資料:
Webpack を使用して HMR を取り入れる#
Hot Module Replacement—— モジュールのホットリプレースメント(書いたコードが即座にブラウザに更新される~)
-
HMR を有効にする
module.exports={ // ... devServer: { hot:true; // 必須 } };
-
webpack を起動
原理については、Webpack 原理シリーズ十:HMR 原理全解析 (qq.com)を参照してください。
Webpack を使用して Tree-Shaking を取り入れる#
Tree-Shaking - ツリーシェイキング、デッドコードを削除するために使用されます。
デッドコード
- コードが使用されていない、到達不可能
- コードの実行結果が使用されない
- コードは読み取り専用で書き込み不可
Tree-Shaking
- モジュールがエクスポートされているが、他のモジュールで使用されていない
有効化手順?
- mode: "production"
- optimization: {usedExports: true}
module.exports = {
entry: "./src/ index",
mode: "production",
devtool: false,
optimization: {
usedExports: true,
},
};
ps:Lodash のようなツールライブラリに対して非常に効果的で、生成物のサイズを大幅に削減できます。
その他のツール#
- キャッシュ
- Sourcemap (前のコースで触れたことがあります)
- パフォーマンス監視
- ログ
- コード圧縮
- 分割パッケージ
- ...
思考問題#
- 上記に挙げた内容以外に、どのような設定が「プロセスタイプ」に分類されますか?
- ツールタイプの設定には具体的にどのような役割がありますか?devtool/cache/stat などを含む
Loader の理解#
Loader の核心機能:非 JS リソースを JS リソースに変換する
-
Loader をインストール
npm add -D css-loader style-loader less-loader
-
module に less ファイルを処理するための設定を追加
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use:[
"style-loader",
"css-loader",
"less-loader",
],
},
],
},
};
Loader の理解:チェーン呼び出し#
- less-loader: less => css の変換を実現
- css-loader: css => js の変換を実現し、CSS を module.exports = "${css}" のような内容にラップし、ラップされた内容は JavaScript の構文に適合します
- style-loader:CSS モジュールを require 文に包み込み、実行時にinjectStyleなどの関数を呼び出して内容をページの style タグに注入します
Loader の理解:その他の特性#
特徴
- チェーン実行
- 非同期実行をサポート
- normal、pitch の 2 つのモードをサポート
- 参考:Webpack 原理シリーズ七:Loader の書き方 (qq.com)
module.exports = function(source, sourceMap?, data?) {
// sourceはloaderの入力
// それはファイルの内容であるか、前のloaderの処理結果である可能性があります
return source;
};
よく使われる Loader#
使用の観点から、これらの一般的な Loader の機能、設定方法を習得することをお勧めします。
思考問題#
- Loader の入力は何ですか?要求される出力は何ですか?
- Loader のチェーン呼び出しとは何ですか?複数の Loader をどのように連結しますか?
- Loader 内で非同期シーンをどのように処理しますか?例外をスローする必要がある場合、どのようにスローしますか?
プラグイン Plugin の理解#
プラグインとは何か#
- 多くの有名なツール、例えば:
- VS Code、Web Storm、Chrome、Firefox
- Babel、Webpack、Rollup、Eslint
- Vue、Redux、Quill、Axios
- などは、いわゆる「プラグイン」アーキテクチャを設計しています。なぜでしょうか?
プラグインはアプリケーション全体の拡張性を向上させることができます
仮にアプリケーションにプラグインが全くない場合、全体が特に複雑なプロセスになります。そうなると:
- 新人は全プロセスの詳細を理解する必要があり、習得コストが高い
- 機能の反復コストが高く、一つを動かすと全てに影響が出る
- 機能が硬直化し、オープンソースプロジェクトとして成長性が欠ける
心的コストが高い => メンテナンス性が低い => 生命力が弱い
プラグインアーキテクチャの精髄:拡張に対してオープン、変更に対してクローズ、実際にはオープン・クローズド原則です。
さらには、Webpack 自体の多くの機能もプラグインに基づいて実現されています。
プラグインの書き方#
まず:プラグインはフックを中心に展開されます。
class SomePlugin {
apply(compile) {
compiler.hooks.thisCompilation.tap('SomePlugin', (compilation) => {
})
}
}
フック#
-
タイミング:コンパイルプロセスの特定のノードで、Webpack はフック形式でプラグインに現在何が起こっているかを通知します;
-
コンテキスト:tapable が提供するコールバックメカニズムを通じて、パラメータとしてコンテキスト情報を渡します;
-
インタラクション:コンテキストパラメータオブジェクトには、多くの副作用のあるインタラクションインターフェースが含まれており、プラグインはこれらのインターフェースを通じて変更できます。
タイミング:compier.hooks.compilation
パラメータ:compilation など
インタラクション:dependencyFactories.set
思考問題#
- Loader とプラグインにはどのような違いがありますか?
- 「フック」はどのような役割を果たしますか?フック関数をどのようにリスンしますか?
参考資料:
Webpack の学び方#
初級:柔軟に応用できるようになる#
- バンドルプロセスを理解する
- よく使われる設定項目、Loader、プラグインの使用方法を習得し、Vue、React、Babel、Eslint、Less、Sass、画像処理などのツールを統合した Webpack 環境を柔軟に構築できるようになる
- 一般的なスキャフォールディングツールの使い方を習得する、例えば:Vue-cli、create-react-app、@angular/cli
中級:Webpack を拡張できるようになる#
- Loader、Plugin メカニズムを理解し、自分で Webpack コンポーネントを開発できる
- 一般的なパフォーマンス最適化手段を理解し、実際の問題を解決するために使用できる
- フロントエンドエンジニアリングの概念とエコシステムの現状を理解する
マスター:ソースコードレベルで Webpack のバンドルコンパイル原理を理解する#
- ソースコードを読み、Webpack のコンパイル、バンドル原理を理解し、さらには共同開発に参加できるようになる
まとめと感想#
この授業では、Webpack の役割、設定構造、主要な設定項目について詳しく説明し、Loader のチェーン呼び出し、プラグインの実装原理、その他の特性についても触れました。先生の Webpack に対する研究は非常に詳細で、授業中は直接デバッグを行い、Loader 内部に入るなどして理解を助けてくれました。先生はまた、Webpack の知識体系をまとめました:Webpack 5 知識体系 - GitMind。
Q&A#
Q:面接ではどの程度の知識が必要ですか?
A:オンラインでの多くの面接は主に 3 つのテーマに基づいています。
- Loader はどのような役割を果たしますか?どうやって Loader を書くのですか?よく使われる Loader は何ですか?
- よく使われる Loader:css-loader、style-loader、vue-loader、file-loader、eslint-loader、babel-loader など
- プラグインはどのような役割を果たしますか?どうやってプラグインを書くのですか?コンパイル原理は?
- Bundle、chunk、module はそれぞれ何を意味しますか?
いくつかのリソース:深入浅出 Webpack
本文で引用したほとんどの内容は范文杰先生の授業に基づいています。先生の公式アカウントをフォローしてください:Tecvan