JavaScript >> Javascript 文檔 >  >> Tags >> Webpack

webpack 教程:如何從頭開始設置 webpack 5

網絡包 曾經對我來說是一個令人沮喪和壓倒性的野獸。我覺得使用類似 create-react-app 的東西很安全 建立一個項目,但我盡可能避免使用 webpack,因為它看起來很複雜和令人困惑。

如果您不習慣從頭開始設置 webpack 以與 Babel、TypeScript、Sass、React 或 Vue 一起使用,或者不知道為什麼要使用 webpack,那麼這篇文章非常適合您。像所有事物一樣,一旦您深入了解並了解它,您就會發現它並沒有那麼可怕,只需學習一些主要概念即可進行設置。

除了本文之外,我還創建了一個非常可靠的 webpack 5 Boilerplate 來幫助您開始任何項目。如果您熟悉 webpack 4 但想查看 webpack 5 設置,我還建議您檢查一下。

先決條件

  • 熟悉 HTML 和 CSS
  • JavaScript 和編程的基本知識
  • 熟悉 ES6 語法和特性
  • 能夠設置 Node.js 環境
  • 命令行知識

目標

  • 了解什麼是 webpack 以及為什麼要使用它
  • 使用 webpack 設置開發服務器
  • 使用 webpack 設置生產構建流程

內容

  • 什麼是 webpack
  • 安裝
  • 基本配置
    • 參賽作品
    • 輸出
  • 插件
    • HTML 模板
    • 乾淨
  • 模塊和加載器
    • Babel (JavaScript)
    • 圖片
    • 字體和內嵌
    • 樣式
  • 發展

什麼是 webpack?

在大多數情況下,網站不再只是用帶有一些可選 JavaScript 的純 HTML 編寫——它們通常完全由 JavaScript 構建。所以我們必須將代碼打包、縮小、轉譯成所有瀏覽器都能理解的東西,這就是 webpack 的用武之地。

webpack 是一個模塊打包器。它為瀏覽器整齊地打包了所有代碼。它允許您使用 Babel 或使用 TypeScript 編寫最新的 JavaScript,並將其編譯成跨瀏覽器兼容且簡潔的東西。它還允許您將靜態資源導入 JavaScript。

對於開發,webpack 還提供了一個開發服務器,可以在您保存時即時更新模塊和样式。 vue createcreate-react-app 在底層依賴 webpack,但您可以輕鬆地為它們設置自己的 webpack 配置。

webpack 可以做的事情還有很多,但本文將幫助您熟悉這些概念並進行設置。

安裝

首先,為您的項目創建一個目錄來運行並啟動一個 Node 項目。我叫它webpack-tutorial .

mkdir webpack-tutorial
cd webpack-tutorial
npm init -y # creates a default package.json

首先,安裝 webpackwebpack-cli .這些是設置的核心技術。

npm i -D webpack webpack-cli
  • webpack - 模塊和資產捆綁器
  • webpack-cli - webpack 的命令行界面

我們將製作一個 src 文件夾以包含所有源文件。我將從創建一個簡單的 index.js 開始 文件。

src/index.js
console.log('Interesting!')

好的,現在你有了一個安裝了基礎包的 Node 項目和一個要啟動的索引文件。我們現在開始創建配置文件。

基本配置

讓我們開始設置一個 Webpack 構建。創建一個 webpack.config.js 在項目的根目錄中。

Entry

設置 webpack 配置的第一部分是定義 入口點 , webpack 將查看哪些文件或文件進行編譯。在本例中,我們將入口點設置為 src/index.js .

webpack.config.js
const path = require('path')

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

輸出

輸出是捆綁文件將解析的位置。我們將它輸出到 dist 文件夾,這是構建生產代碼的地方。 [name] 在輸出中將是 main ,在入口對像中指定。

webpack.config.js
module.exports = {
  /* ... */

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: '[name].bundle.js',
  },
}

現在我們有了構建捆綁包所需的最低配置。在 package.json ,我們可以製作一個build 運行 webpack 的腳本 命令。

package.json
"scripts": {
  "build": "webpack"
}

現在你可以運行它了。

npm run build
asset main.bundle.js 19 bytes [emitted] [minimized] (name: main)
./src/index.js 18 bytes [built] [code generated]
webpack 5.1.0 compiled successfully in 152 mss

你會看到一個 dist 已使用 main.bundle.js 創建文件夾 .文件還沒有發生任何事情,但我們現在已經成功構建了 webpack。

插件

webpack 有一個插件接口,使它變得靈活。內部 webpack 代碼和第三方擴展使用插件。幾乎每個 webpack 項目都會用到幾個主要的。

HTML 模板文件

所以我們有一個隨機的捆綁文件,但它對我們來說還不是很有用。如果我們正在構建一個 Web 應用程序,我們需要一個 HTML 頁面,該頁面將該 JavaScript 包作為腳本加載。由於我們希望 HTML 文件自動引入腳本,我們將使用 html-webpack-plugin 創建一個 HTML 模板 .

  • html-webpack-plugin - 從模板生成 HTML 文件

安裝插件。

npm i -D html-webpack-plugin

創建一個 template.html src 中的文件 文件夾。我們可以在模板中包含其他自定義信息的變量。我們將添加一個自定義 title , 否則它將看起來像帶有 root 的常規 HTML 文件 分區。

src/template.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>

  <body>
    <div id="root"></div>
  </body>
</html>

創建一個 plugins 您的配置的屬性,您將添加插件,文件名輸出(index.html ),並鏈接到它將基於的模板文件。

webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  /* ... */

  plugins: [    new HtmlWebpackPlugin({      title: 'webpack Boilerplate',      template: path.resolve(__dirname, './src/template.html'), // template file      filename: 'index.html', // output file    }),  ],}

現在再次運行構建。你會看到 dist 文件夾現在包含 index.html 加載了捆綁包。成功!如果將該文件加載到瀏覽器中,您將看到 Interesting! 在控制台中。

讓我們更新它以將一些內容注入 DOM。更改 index.js 入口點,然後再次運行構建命令。

src/index.js
// Create heading node
const heading = document.createElement('h1')
heading.textContent = 'Interesting!'

// Append heading node to the DOM
const app = document.querySelector('#root')
app.append(heading)

現在要測試它,您可以轉到 dist 文件夾並啟動服務器。 (必要時全局安裝http-server。)

http-server

你會看到我們的 JavaScript 被注入到 DOM 中,說“有趣!”。您還會注意到捆綁文件已縮小。

乾淨

您還需要設置 clean-webpack-plugin ,這會清除 dist 中的任何內容 每次構建後的文件夾。這對於確保不會遺留舊數據非常重要。

  • clean-webpack-plugin - 刪除/清理構建文件夾
webpack.config.js
const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
  /* ... */

  plugins: [
    /* ... */
    new CleanWebpackPlugin(),  ],
}

模塊和加載器

webpack 使用加載器來預處理通過模塊加載的文件。這可以是 JavaScript 文件、圖像和 CSS 樣式等靜態資產,以及 TypeScript 和 Babel 等編譯器。 webpack 5 也有一些內置的資產加載器。

在您的項目中,您有一個 HTML 文件,它加載並引入了一些 JavaScript,但它實際上仍然沒有做任何事情。我們希望這個 webpack 配置做的主要事情是什麼?

  • 將最新最好的 JavaScript 編譯成瀏覽器可以理解的版本
  • 導入樣式並將 SCSS 編譯成 CSS
  • 導入圖片和字體
  • (可選)設置 React 或 Vue

我們要做的第一件事是設置 Babel 來編譯 JavaScript。

Babel (JavaScript)

Babel 是一個讓我們今天就可以使用明天的 JavaScript 的工具。

我們將設置一個檢查任何 .js 的規則 項目中的文件(在 node_modules 之外 ) 並使用 babel-loader 轉譯。 Babel 也有一些額外的依賴項。

  • babel-loader - 使用 Babel 和 webpack 轉譯文件。
  • @babel/core - 將 ES2015+ 轉換為向後兼容的 JavaScript
  • @babel/preset-env - Babel 的智能默認設置
  • @babel/plugin-proposal-class-properties - 自定義 Babel 配置示例(直接在類上使用屬性)
npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-env @babel/plugin-proposal-class-properties
webpack.config.js
module.exports = {
  /* ... */

  module: {    rules: [      // JavaScript      {        test: /\.js$/,        exclude: /node_modules/,        use: ['babel-loader'],      },    ],  },}

現在 Babel 已經設置好了,但是我們的 Babel 插件還沒有。您可以通過將示例 pre-Babel 代碼添加到 index.js 來證明它不起作用 .

src/index.js
// Create a class property without a constructorclass Game {  name = 'Violin Charades'}const myGame = new Game()// Create paragraph nodeconst p = document.createElement('p')p.textContent = `I like ${myGame.name}.`
// Create heading node
const heading = document.createElement('h1')
heading.textContent = 'Interesting!'

// Append SVG and heading nodes to the DOM
const app = document.querySelector('#root')
app.append(heading, p)
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/you/webpack-tutorial/src/index.js: Support for the experimental syntax 'classProperties' isn't currently enabled (3:8):

  1 | // Create a class property without a constructor
  2 | class Game {
> 3 |   name = 'Violin Charades'
    |        ^
  4 | }

要解決此問題,只需創建一個 .babelrc 項目根目錄中的文件。這將使用 preset-env 添加很多默認值 以及我們想要的插件 plugin-proposal-class-properties .

.babelrc
{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

現在又一個 npm run build 一切都會準備就緒。

圖片

您希望能夠將圖像直接導入到 JavaScript 文件中,但這不是 JavaScript 默認可以做的事情。為了演示,創建 src/images 並向其中添加圖像,然後嘗試將其導入您的 index.js 文件。

src/index.js
import example from './images/example.png'

/* ... */

當你運行構建時,你會再次看到一個錯誤:

ERROR in ./src/images/example.png 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

webpack 有一些內置的資產模塊,可用於靜態資產。對於圖像類型,我們將使用 asset/resource .請注意,這是一個 type 而不是 loader .

webpack.config.js
module.exports = {
  /* ... */
  module: {
    rules: [
      // Images      {        test: /\.(?:ico|gif|png|jpg|jpeg)$/i,        type: 'asset/resource',      },    ],
  },
}

你會看到文件輸出到 dist 構建後的文件夾。

字體和內聯

webpack 還有一個資產模塊來內聯一些數據,比如 svgs 和字體,使用 asset/inline 輸入。

src/index.js
import example from './images/example.svg'

/* ... */
webpack.config.js
module.exports = {
  /* ... */
  module: {
    rules: [
      // Fonts and SVGs      {        test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,        type: 'asset/inline',      },    ],
  },
}

樣式

必須使用樣式加載器才能執行 import 'file.css' 之類的操作 在你的腳本中。

現在很多人都在使用 CSS-in-JS、styled-components 和其他工具將樣式引入他們的 JavaScript 應用程序。

有時,僅僅能夠加載 CSS 文件就足夠了。這個網站只有一個 CSS 文件。也許您想使用 PostCSS,它允許您在任何瀏覽器中使用所有最新的 CSS 功能。或者,也許您想使用 CSS 預處理器 Sass。

我想使用所有這三個 - 在 Sass 中編寫,在 PostCSS 中處理,並編譯為 CSS。這涉及引入一些加載器和依賴項。

  • sass-loader - 加載 SCSS 並編譯為 CSS
    • node-sass - 節點薩斯
  • postcss-loader - 使用 PostCSS
      處理 CSS
    • postcss-preset-env - PostCSS 的合理默認值
  • css-loader - 解決 CSS 導入問題
  • style-loader - 將 CSS 注入 DOM
npm i -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass

就像 Babel 一樣,PostCSS 需要一個配置文件,所以創建它並將其添加到根目錄。

postcss.config.js
module.exports = {
  plugins: {
    'postcss-preset-env': {
      browsers: 'last 2 versions',
    },
  },
}

為了測試 Sass 和 PostCSS 是否正常工作,我將製作一個 src/styles/main.scss 使用 Sass 變量和 PostCSS 示例(lch )。

src/styles/main.scss
$font-size: 1rem;
$font-color: lch(53 105 40);

html {
  font-size: $font-size;
  color: $font-color;
}

現在在 index.js 中導入文件 並添加四個裝載機。它們從最後一個編譯到第一個,所以列表中最後一個是 sass-loader 因為這需要編譯,然後是 PostCSS,然後是 CSS,最後是 style-loader ,這會將 CSS 注入 DOM。

src/index.js
import './styles/main.scss'

/* ... */
webpack.config.js
module.exports = {
  /* ... */
  module: {
    rules: [
      // CSS, PostCSS, and Sass      {        test: /\.(scss|css)$/,        use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],      },    ],
  },
}

現在當你重建時,你會注意到 Sass 和 PostCSS 已經被應用了。

發展

運行 npm run build 每次進行更新都很乏味。您的網站越大,構建所需的時間就越長。你需要為 webpack 設置兩個配置:

  • 生產配置,用於縮小、優化和刪除所有源映射
  • 一個開發配置,在服務器中運行 webpack,每次更改都會更新,並具有源映射

而不是構建到 dist 文件,開發模式只會運行內存中的所有內容。

要設置開發,您將安裝 webpack-dev-server .

  • webpack-dev-server - webpack 的開發服務器
npm i -D webpack-dev-server

出於演示目的,我們可以將開發配置添加到當前的 webpack.config.js 我們正在構建的文件並對其進行測試。但是,您需要創建兩個配置文件:一個帶有 mode: production 和一個 mode: development .在 webpack 5 樣板中,我演示瞭如何使用 webpack-merge 將所有基本 webpack 配置放在一個文件中,並將任何特殊的開發或生產配置放在 webpack.prod.jswebpack.dev.js 文件。

const webpack = require('webpack')

module.exports =  {
  /* ... */
  mode: 'development',
  devServer: {
    historyApiFallback: true,
    contentBase: path.resolve(__dirname, './dist'),
    open: true,
    compress: true,
    hot: true,
    port: 8080,
  },

  plugins: [
    /* ... */
    // Only update what has changed on hot reload
    new webpack.HotModuleReplacementPlugin(),
  ],
})

我們正在添加 mode: development ,並創建一個 devServer 財產。我在上面設置了一些默認值 - 端口將是 8080 ,它會自動打開一個瀏覽器窗口,並使用熱模塊替換,這需要 webpack.HotModuleReplacementPlugin 插入。這將允許在不完全重新加載頁面的情況下更新模塊 - 因此,如果您更新某些樣式,只有這些樣式會改變,您不需要重新加載整個 JavaScript,這會大大加快開發速度。

現在您將使用 webpack serve 設置服務器的命令。

package.json
"scripts": {
  "start": "webpack serve"
}
npm start

當你運行這個命令時,一個指向 localhost:8080 的鏈接 會自動在瀏覽器中彈出。現在您可以更新 Sass 和 JavaScript 並實時觀察它的更新。

結論

這應該可以幫助您開始使用 webpack。再一次,我創建了一個可用於生產的 webpack 5 樣板,其中包含 Babel、Sass、PostCSS、生產優化和一個開發服務器,它包含本文中的所有內容,但更詳細。從這裡,您可以輕鬆設置 React、Vue、Typescript 或您可能想要的任何其他內容。

  • webpack 5 樣板

看看,玩弄它,然後享受吧!


Tutorial JavaScript 教程
  1. 如何在 React (Route Guard) 中創建私有路由 - 示例:僅適用於經過身份驗證的用戶

  2. Angular CLI 流動。大圖。

  3. 賽普拉斯命令(獲取、單擊、查找)

  4. 非常迷人的 NPM 包

  5. 你如何在 switch 語句中有一個 NaN 案例?

  6. 反應開發?為什麼以及如何使用 Storybook

  7. 哪個是您 2020 年最好的 React UI 組件庫/框架?

  1. 學習 React 概念 2

  2. 如何在 Node 中創建 C/C++ 插件

  3. 對前端和後端使用相同的 mkcert 證書可以嗎?

  4. Pempaltes:引導您的開發環境

  5. React 18 - 性能改進

  6. 行走的 AI:從零開始的簡單神經網絡

  7. EventDispatch(er) 與 EventEmitter

  1. Web 組件的想法:製作一個 if 元素

  2. 什麼是本地存儲?

  3. 如何在 JavaScript 中獲取 CSS 值

  4. 使用手機學習 Web 開發