Webpack 起步

2023-05-17 14:54 更新

webpack 用于編譯 JavaScript 模塊。一旦完成 安裝,你就可以通過 webpack CLI 或 API 與其配合交互。如果你還不熟悉 webpack,請(qǐng)閱讀 核心概念 和 對(duì)比,了解為什么要使用 webpack,而不是社區(qū)中的其他工具。

基本安裝

首先我們創(chuàng)建一個(gè)目錄,初始化 npm,然后 在本地安裝 webpack,接著安裝 webpack-cli(此工具用于在命令行中運(yùn)行 webpack):

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

在整個(gè)指南中,我們將使用 diff 塊,來展示對(duì)目錄、文件和代碼所做的修改。例如:

+ this is a new line you shall copy into your code
- and this is a line to be removed from your code
  and this is a line not to touch.

現(xiàn)在,我們將創(chuàng)建以下目錄結(jié)構(gòu)、文件和內(nèi)容:

project

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- index.html
+ |- /src
+   |- index.js

src/index.js

function component() {
  const element = document.createElement('div');

  // lodash(目前通過一個(gè) script 引入)對(duì)于執(zhí)行這一行是必需的
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>起步</title>
    <script src="https://unpkg.com/lodash@4.17.20" rel="external nofollow"  rel="external nofollow" ></script>
  </head>
  <body>
    <script src="./src/index.js"></script>
  </body>
</html>

我們還需要調(diào)整 package.json 文件,以便確保我們安裝包是 private(私有的),并且移除 main 入口。這可以防止意外發(fā)布你的代碼。

package.json

 {
   "name": "webpack-demo",
   "version": "1.0.0",
   "description": "",
-  "main": "index.js",
+  "private": true,
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "keywords": [],
   "author": "",
   "license": "MIT",
   "devDependencies": {
     "webpack": "^5.38.1",
     "webpack-cli": "^4.7.2"
   }
 }

在此示例中,<script> 標(biāo)簽之間存在隱式依賴關(guān)系。在 ?index.js? 文件執(zhí)行之前,還需要在頁面中先引入 lodash。這是因?yàn)?nbsp;?index.js? 并未顯式聲明它需要 lodash,假定推測已經(jīng)存在一個(gè)全局變量 _。

使用這種方式去管理 JavaScript 項(xiàng)目會(huì)有一些問題:

  • 無法直接體現(xiàn),腳本的執(zhí)行依賴于外部庫。
  • 如果依賴不存在,或者引入順序錯(cuò)誤,應(yīng)用程序?qū)o法正常運(yùn)行。
  • 如果依賴被引入但是并沒有使用,瀏覽器將被迫下載無用代碼。

讓我們使用 webpack 來管理這些腳本。

創(chuàng)建一個(gè) bundle

首先,我們稍微調(diào)整下目錄結(jié)構(gòu),創(chuàng)建分發(fā)代碼(./dist)文件夾用于存放分發(fā)代碼,源代碼(./src)文件夾仍存放源代碼。源代碼是指用于書寫和編輯的代碼。分發(fā)代碼是指在構(gòu)建過程中,經(jīng)過最小化和優(yōu)化后產(chǎn)生的輸出結(jié)果,最終將在瀏覽器中加載。調(diào)整后目錄結(jié)構(gòu)如下:

project

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- /dist
+   |- index.html
- |- index.html
  |- /src
    |- index.js

要在 ?index.js? 中打包 lodash 依賴,我們需要在本地安裝 library:

npm install --save lodash

現(xiàn)在,在我們的 script 中 import lodash:

src/index.js

+import _ from 'lodash';
+
 function component() {
   const element = document.createElement('div');

-  // lodash(目前通過一個(gè) script 引入)對(duì)于執(zhí)行這一行是必需的
+  // lodash 在當(dāng)前 script 中使用 import 引入
   element.innerHTML = _.join(['Hello', 'webpack'], ' ');

   return element;
 }

 document.body.appendChild(component());

現(xiàn)在,我們將會(huì)打包所有腳本,我們必須更新 index.html 文件。由于現(xiàn)在是通過 import 引入 lodash,所以要將 lodash <script> 刪除,然后修改另一個(gè) <script> 標(biāo)簽來加載 bundle,而不是原始的 ?./src? 文件:

?dist/index.html?

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
     <title>起步</title>
-    <script src="https://unpkg.com/lodash@4.17.20" rel="external nofollow"  rel="external nofollow" ></script>
   </head>
   <body>
-    <script src="./src/index.js"></script>
+    <script src="main.js"></script>
   </body>
 </html>

在這個(gè)設(shè)置中,?index.js? 顯式要求引入的 lodash 必須存在,然后將它綁定為 _(沒有全局作用域污染)。通過聲明模塊所需的依賴,webpack 能夠利用這些信息去構(gòu)建依賴圖,然后使用圖生成一個(gè)優(yōu)化過的 bundle,并且會(huì)以正確順序執(zhí)行。

可以這樣說,執(zhí)行 npx webpack,會(huì)將我們的腳本 ?src/index.js? 作為 入口起點(diǎn),也會(huì)生成 ?dist/main.js? 作為 輸出。Node 8.2/npm 5.2.0 以上版本提供的 npx 命令,可以運(yùn)行在初次安裝的 webpack package 中的 webpack 二進(jìn)制文件(即 ?./node_modules/.bin/webpack?):

$ npx webpack
[webpack-cli] Compilation finished
asset main.js 69.3 KiB [emitted] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable modules 530 KiB
  ./src/index.js 257 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 1851 ms

在瀏覽器中打開 dist 目錄下的 index.html,如果一切正常,你應(yīng)該能看到以下文本:?'Hello webpack'?。

模塊

ES2015 中的 import 和 export 語句已經(jīng)被標(biāo)準(zhǔn)化。雖然大多數(shù)瀏覽器還無法支持它們,但是 webpack 卻能夠提供開箱即用般的支持。

事實(shí)上,webpack 在幕后會(huì)將代碼 “轉(zhuǎn)譯”,以便舊版本瀏覽器可以執(zhí)行。如果你檢查 dist/main.js,你可以看到 webpack 具體如何實(shí)現(xiàn),這是獨(dú)創(chuàng)精巧的設(shè)計(jì)!除了 import 和 export,webpack 還能夠很好地支持多種其他模塊語法,更多信息請(qǐng)查看 模塊 API。

注意,webpack 不會(huì)更改代碼中除 import 和 export 語句以外的部分。如果你在使用其它 ES2015 特性,請(qǐng)確保你在 webpack loader 系統(tǒng) 中使用了一個(gè)像是 Babel 的 transpiler(轉(zhuǎn)譯器)。

使用一個(gè)配置文件

在 webpack v4 中,可以無須任何配置,然而大多數(shù)項(xiàng)目會(huì)需要很復(fù)雜的設(shè)置,這就是為什么 webpack 仍然要支持 配置文件。這比在 terminal(終端) 中手動(dòng)輸入大量命令要高效的多,所以讓我們創(chuàng)建一個(gè)配置文件:

project

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- webpack.config.js
  |- /dist
    |- index.html
  |- /src
    |- index.js

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

現(xiàn)在,讓我們通過新的配置文件再次執(zhí)行構(gòu)建:

$ npx webpack --config webpack.config.js
[webpack-cli] Compilation finished
asset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable modules 530 KiB
  ./src/index.js 257 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 1934 ms

比起 CLI 這種簡單直接的使用方式,配置文件具有更多的靈活性。我們可以通過配置方式指定 loader 規(guī)則(loader rule)、plugin(插件)、resolve 選項(xiàng),以及許多其他增強(qiáng)功能。更多詳細(xì)信息請(qǐng)查看 配置文檔。

npm scripts

考慮到用 CLI 這種方式來運(yùn)行本地的 webpack 副本并不是特別方便,我們可以設(shè)置一個(gè)快捷方式。調(diào)整 package.json 文件,添加一個(gè) npm script:

package.json

 {
   "name": "webpack-demo",
   "version": "1.0.0",
   "description": "",
   "private": true,
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "build": "webpack"
   },
   "keywords": [],
   "author": "",
   "license": "ISC",
   "devDependencies": {
     "webpack": "^5.4.0",
     "webpack-cli": "^4.2.0"
   },
   "dependencies": {
     "lodash": "^4.17.20"
   }
 }

現(xiàn)在,可以使用 npm run build 命令,來替代我們之前使用的 npx 命令。注意,使用 npm scripts,我們可以像使用 npx 那樣通過模塊名引用本地安裝的 npm packages。這是大多數(shù)基于 npm 的項(xiàng)目遵循的標(biāo)準(zhǔn),因?yàn)樗试S所有貢獻(xiàn)者使用同一組通用腳本。

現(xiàn)在運(yùn)行以下命令,然后看看你的腳本別名是否正常運(yùn)行:

$ npm run build

...

[webpack-cli] Compilation finished
asset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable modules 530 KiB
  ./src/index.js 257 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 1940 ms

結(jié)論

現(xiàn)在,你已經(jīng)有了一個(gè)基礎(chǔ)構(gòu)建配置,你應(yīng)該移至下一章節(jié) 資源管理 指南,以了解如何通過 webpack 來管理資源,例如 images、fonts。此刻你的項(xiàng)目看起來應(yīng)該如下:

project

webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
|- /dist
  |- main.js
  |- index.html
|- /src
  |- index.js
|- /node_modules

如果想要了解 webpack 設(shè)計(jì)思想,你應(yīng)該看下 基本概念 和 配置 頁面。此外,API 章節(jié)可以深入了解 webpack 提供的各種接口。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)