ウェブパックとは
公式の定義: 本質的に、webpack は最新の JavaScript 静的モジュール パッケージ ツールです。
Webpack は、フロントエンド エンジニアリングのソリューションです。
主な機能:フロントエンドのモジュラー機能のサポート、モジュールの難読化、コードの圧縮、処理ブラウザー JS の互換性、パフォーマンスの最適化などの強力な機能を提供します。
ウェブパックの前提条件
webpack を学習する前提は、モジュラー機能を提供する es6 のモジュラー知識または commonjs の知識 (深すぎない) を知っていることです。es6 のモジュール化は公式の標準であり、比較的新しいものであり、将来の主流になることは間違いありませんが、commonjs は長い間存在し、深い経験を持っています。どちらか、または両方を知っておくとよいでしょう。見ることを学びませんでした。そうでなければ、webpack の例を理解できませんでした。
その他の前提条件:
JavaScript の es5 基盤 (深すぎない)
html (深すぎない)
css (深すぎない)
node.js (深すぎない)
webpack のインストール
webpack は node.js に依存します。最初に node.js をインストールする必要はありません。取り付け方は言うまでもありません。
このバージョンの webpack3.6.0 をインストールします。
npm install [email protected] -g
バージョン番号が表示されていれば、インストールは成功しています。
webpack -version
webpackの基本的な使い方
まず、js のエントリ ファイルである main.js ファイルというディレクトリを作成します。dist フォルダーは、後で使用するパッケージ化されたファイルを格納するために使用されます。webpack はモジュール化をサポートしているため、単純にモジュール化をシミュレートするために mathUtil.js が追加されています。
main.js のコードは次のとおりです。mathUtils.js
のコードは、単純な出力を実現するために呼び出されます。コードの 1 行目は commonjs の構文です. 理解できない場合は、これが参照モジュールであることを知っておく必要があります。
const {
add,mult}=require("./mathUtils.js")
console.log(add(1,2))
console.log(mult(1,2))
mathUtils.js は 2 つのメソッドを定義し、他のユーザーが使用できるようにエクスポートします。
function add(a, b) {
return a+b
}
function mult(a, b) {
return a*b
}
//使用commonJs导出
module.exports = {
add,
mult
}
index.html の内容はデフォルトの html テキストである空で、何も書かれていません。
分析:
これで、mathUtils.js の内容を参照する main.js ができました。
js が利用できるので、js で引用する必要がありますか? 答えはいいえだ。webpack を使用しない場合、main.js や mathUtils.js など、複数の js ファイルを参照することがありますが、もちろん js ファイルが多数存在する場合があり、それらすべてを参照するのは非常に面倒です。webpack は、これらの js ファイルを 1 つのファイルにパッケージ化できます。次に、パッケージ化されたファイルをインポートするだけでよく、パッケージ化は非常に簡単です。
次のコードを実行すると、dist ディレクトリの下に bundle.js ファイルが生成されます. これがパッケージ化されたファイルです. ここでパッケージ化するときは main.js のみを記述します. webpack は関連するすべての js ファイルをパッケージ化するのに役立ちます. これは、webpack が手順を簡素化するのに役立つ場所です. 手動参照を 1 つずつ比較すると、これは自動参照と同等です. エントリ js を提供するだけで済みます.これは main.js js ファイルです.
webpack ./src/main.js ./disk/bundle.js
生成された bundle.js を簡単に見てみましょう。前のコードを見る必要はありませんが、主に次の数行を見てください. 後の数行は、実際には main.js と mathUtils.js のコードをマージしており、いくつかの commonjs のコードがまだ残っています.ブラウザに認識されない. , 先に生成された理解不能なコードの束は、commonjs をサポートするために使用されます.
/******/ (function(modules) {
// webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {
};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {
}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() {
return module['default']; } :
/******/ function getModuleExports() {
return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
const {
add,mult}=__webpack_require__(1)
console.log(add(1,2))
console.log(mult(1,2))
/***/ }),
/* 1 */
/***/ (function(module, exports) {
function add(a, b) {
return a+b
}
function mult(a, b) {
return a*b
}
//使用commonJs导出
module.exports = {
add,
mult
}
/***/ })
/******/ ]);
最後に、生成された bundle.js を index.html で参照するだけです。
<script src="./dist/bundle.js"></script>
ブラウザーを開いて、js の実行出力を確認します。
ウェブパックの構成
パッケージ化に webpack を使用したときは、手動でパスを指定しましたが、便宜上、これらを構成ファイルに書き込むことができます。
webpack ./src/main.js ./disk/bundle.js
プロジェクトのルート ディレクトリに webpack.config.js ファイルを作成する必要があります。これは webpack の構成ファイルで、デフォルトではこの名前が付けられています。
以下の内容を記述し、ターミナルで webpack コマンドをパラメータを追加せずに実行すると、エラーが報告され、絶対パスを使用するように指示されます。実は以下のパスは間違った書き方で絶対パスが必要なので、直接書くのは適切ではなく、node.jsが提供するパスパッケージから取得するのが適切です。
module.exports = {
entry:"./src/main.js",
output:{
path:"./dist",
filename:"bundle.js"
}
}
デフォルトでは、パス パッケージはありません。プロジェクトをノード プロジェクトとして初期化する必要があります。
ノード プロジェクトを初期化するには、次のコマンドを入力します。index.html の親ディレクトリで実行します。
npm init
いくつかの値を入力するように求められます。中国語を書かないでください。中国語でない場合は、いつでもデフォルトにすることができます。具体的な構成については後で説明します。
完了すると、ノードの構成ファイルである package.json ファイルが追加されます。
中身は大まかに以下の通り。
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
これで、ノードが提供するパス ライブラリを使用できるようになりました。
require を介してライブラリをインポートし、path.resolve メソッドを介して絶対パスを取得します。__dirname は、パス ライブラリによって提供されるプロジェクト パスです。
const path=require("path")
module.exports = {
entry:"./src/main.js",
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
}
}
これで、パスを指定せずに webpack を使用して直接パッケージ化できます。
以前の方法で webpack を実行することは既に利用可能です。しかし、もっと良い方法があります。つまり、ノードのスクリプトを使用して webpack を実行します。
前の問題は、複数の webpack 構成ファイルがあり、1 つは運用環境用、もう 1 つは開発環境用である可能性があるため、環境が変更された場合、webpack パッケージ化コマンドで構成ファイルを指定する必要があることです。
デフォルトの構成ファイル名は webpack.config.js であるため、構成ファイル名は以前に指定されていません。
webpack production.config.js
これらのコマンドをスクリプトに構成するという、より柔軟な方法を使用できます。次のコマンドは、自分で定義したビルド スクリプトを実行するものです。
npm run build
package.json 内には、次のスクリプトがあります。ここで独自のビルド スクリプトを作成できます。test というスクリプトがデフォルトで記述されています。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
}
npm run build を実行して、以前と同じ効果を達成します。
ここにはまだ問題があります。つまり、ターミナルでコマンドを実行すると、グローバル webpack コマンドが呼び出されます。実際のプロジェクトでは、何らかの理由でローカルとグローバルが異なるバージョンを使用する必要がある場合があるため、これは問題を引き起こします。グローバルを使用すると問題が発生します。
現時点では、ローカル バージョンをインストールする必要があります。
npm install [email protected] --save-dev
実行後、以下のディレクトリが表示されます。node_modules には node のすべてのモジュールが含まれており、何百ものモジュールがあり、webpack が内部にあります。
デフォルトでは、ターミナルで webpack を実行すると、次のように記述されていない限り、グローバル ノードが実行されます。
./node_modules/webpack xxxxx
もちろん、今はもっと良い方法があります。次のコードを実行するだけです。これが最終的な効果です。
npm run build
また、package.json には次のノードがあります。
"devDependencies": {
"webpack": "^3.6.0"
}
webpack 構成 CSS
最初に css ディレクトリを作成し、normal.css ファイルを追加します。内容は次のとおりです。
body{
background-color: lightgreen;
}
js ファイル構造を調整し、main.js をエントリとして外部に公開します。
今回はcssコードをhtmlに導入せず、webpackに引き継ぎます。
Webpack 自体は CSS 機能をサポートしておらず、これらの機能はローダーを通じて提供されます。
対応するローダーをロードするだけで、対応する機能を実現できます。
webpack は多くのローダーを提供しますが、CSS ローダーはその 1 つにすぎません。
ドキュメントを開きます:
https://www.webpackjs.com/loaders/#%E6%A0%B7%E5%BC%8F
使用する必要がある css ローダーは 2 つだけです。1 つは css-loader で、css コードを解析して css コードを返すために使用されます。このローダーのみを単独で使用する場合、影響はありません。このローダーはロードのみを担当し、dom へのエクスポートと表示は担当しないためです。そのため、これ専用の style-loader モジュールも必要です。
モジュールをインストールすると、webpack 3.6.0 に対応する 0.9.0 が使用でき、バージョンが高すぎる場合は警告が表示されます。
npm を使用するとエラーを直接報告するように見えますが、cnpm は警告のみであり、現在のバージョンがバージョン範囲にしか対応できないというヒントを提供します。
npm install --save-dev [email protected]
npm install [email protected] --save-dev
次に、構成ファイルにモジュール ノードを追加し、ルールの内容を追加する必要があります。
ドキュメントに記載されているように、使用中の 2 つのローダーは後でロードされ、順序が間違っている場合はエラーが報告されることに注意してください。なぜこのように設計されているのかわかりません。
const path=require("path")
module.exports = {
entry:"./src/main.js",
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader" },
{
loader: "css-loader" }
]
}
]
}
}
この時点で、次のコードを実行し、次に index.html を実行して css スタイルを確認します。
npm run build
背景色が変われば成功です。
webpack構成レス
less の構成は、css の構成と似ています。
ここでの問題の 1 つはバージョンの問題です。どのバージョンが webpack に一致するかわかりません。
また、バージョン番号は統一されておらず、ローダーは独立したバージョン番号です。
解決策は、github にアクセスして、インストールしたいローダー (ここにある less-loader など) を直接検索し、タグのバージョンをクリックすることです。内部の package.json を確認すると、webpack のバージョン範囲が表示されます。
どのローダーでも同様で、これらのローダーは webpack によって公式にリリースされています。
webpack3.6.0に対応した以下のバージョンを利用することは可能ですが、放棄されたとのことで、演算方法にバグがあります。実際のプロジェクトはまだ使用されておらず、webpack のバージョンをアップグレードする必要があります。
npm install --save-dev [email protected] [email protected]
webpack.config.js の下の rules ノードに次のコードを追加します。
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
css フォルダーを作成し、その中に special.less テスト ファイルを準備します。
@fontSize:50px;
@fontColor:lightblue;
body{
font-size: @fontSize;
color: @fontColor;
}
main.js のリファレンスレス
require("./css/special.less")
次のコンテンツを index.html に追加します。
<div id="box">
Hello Webpack
</div>
最後に実行します。
npm run build
効果が正しければ、構成は成功です。
Webpack の画像処理
画像にもローダーが必要です. webpack には 2 種類の画像があります. 設定ファイルで limit 属性を設定して, 画像のサイズがこの値を超えているかどうかを判断できます. この値よりも小さい場合, として扱われます. base64.この値より大きい場合、通常の画像ファイルとして扱われます。
バージョンは 1.1.2 である必要があります。1.0.0 では画像を表示できません。webpack3.6.9 の場合です。
npm install --save-dev [email protected]
ここで重要な点は、追加の制限があることです。これは、前述の画像サイズの制限です。
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
gun.jpg のサイズは 4kb、baidu.png のサイズは 15kb の 2 つの写真を紹介します。
画像のサイズが制限よりも小さいため、本文の背景を gnu.jpg として指定します。そのため、画像は base64 の形式で送信されます。
body{
/*background-color: lightgreen;*/
background: url("../img/gnu.jpg");
}
次のコードを実行すると、効果を確認できます。
npm run build
画像を Baidu.jpg に変更すると、エラーが直接報告されます。ファイルローダーが見つからないことを通知します。前述のように、webpack で画像を処理するには 2 つの方法があり、画像のサイズが制限より小さい場合は、base64 文字列メソッドが使用されます。このとき、url-loader を使用する必要があり、画像が制限より大きい場合は、url-loader を使用できず、file-loader を使用します。
Module build failed: Error: Cannot find module 'file-loader'
ファイルローダーをダウンロードします。
npm install [email protected] --save-dev
ファイルローダーを構成します。
以前の url-loader は file-loader をベースに実装されており、2 つのうちの 1 つしか書き込むことができず、同時に書き込むことによって画像を生成することはできません。
以前の url-loader は file-loader をベースに実装されており、2 つのうちの 1 つしか書き込むことができず、同時に書き込むことによって画像を生成することはできません。
以前の url-loader は file-loader をベースに実装されており、2 つのうちの 1 つしか書き込むことができず、同時に書き込むことによって画像を生成することはできません。
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
}
}
]
}
コンパイルして実行した後、画像が表示されないことがわかりました。ただし、画像は dist ディレクトリに生成されます。
ブラウザ本体のURLアドレスを見てみると、パスが間違っていて、dist/を先頭に追加する必要があります。これは、構成を提供することで実現できます。
url(d9c8750bed0b3c7d089fa7d55720d6cf.png)
webpack 構成ファイルに publicPath ノードを追加する必要があります。
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js",
publicPath:"dist/"
},
これで、baidu.jpg を画像として表示できるようになりました。
すべての画像を dist ルート ディレクトリに配置することはまずありません. dist 用の img ディレクトリを作成する方が合理的です. 次のコードを実装用に提供できます. [name] は元のファイル名を意味します [hash:8] は 8 ビットのハッシュ値を意味し、書き込まれない場合、デフォルトは 32 ビットで、[ext] は拡張子を意味します。これは非常に工学的です。
options: {
name:"img/[name]-[hash:8].[ext]"
}
出力効果:
ES6 構文を ES5 構文に変換する
webpack の最大の利点の 1 つは、互換性の問題に対処できることです。これは、babel-loader を介して実現できます。
npm install [email protected] @babel/core @babel/preset-env
以下を webpack 構成ファイルに追加します。
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
出力された js ファイルを確認すると、以前の const およびその他の es6 文法が es5 文法に変換されています。