原文出處:https://dev.to/antonmelnyk/how-to-configure-webpack-from-scratch-for-a-basic-website-46a5
你好,讀者!
如您所知,設定 Webpack 可能是一項令人沮喪的任務。儘管有很好的文件,但由於一些原因,這個捆綁器並不是一匹舒服的馬。
Webpack 團隊正在非常努力且相對快速地開發它,這是一件好事。然而,對於新開發人員來說,一次性學習所有內容是難以承受的。教程已經過時,一些插件損壞,發現的範例可能會令人困惑。有時,您可能會陷入一些瑣碎的事情,並透過 Google 進行大量搜尋,以在 GitHub issues 中找到一些最終有幫助的簡訊。
缺乏關於 Webpack 及其工作原理的介紹性文章,人們直接奔向 create-react-app 或 vue-cli 等工具,但有時需要編寫一些簡單的純 JavaScript 和 SASS,無需框架或任何奇特的東西。
本指南將逐步介紹 ES6、SASS 和圖片/字體的 Webpack 配置,無需任何框架。對於大多數簡單的網站開始使用 Webpack 或將其用作進一步學習的平台應該足夠了。儘管本指南需要一些有關 Web 開發和 JavaScript 的先驗知識,但它可能對某些人有用。至少當我開始使用 Webpack 時,我會很高興遇到這樣的事情!
我們將使用 Webpack 將 JavaScript、樣式、圖像和字體檔案捆綁到一個 dist 資料夾中。
Webpack 將產生 1 個捆綁的 JavaScript 檔案和 1 個捆綁的 CSS 檔案。您可以像這樣簡單地將它們加入到 HTML 文件中(當然,如果需要,您應該更改 dist 資料夾的路徑):
<link rel="stylesheet" href="dist/bundle.css">
<script src="dist/bundle.js"></script>
你就可以走了:tropical_drink:
您可以查看本指南中完成的範例::link:link。
注意:我最近更新了依賴項。本指南適用於最新的 Webpack 5,但設定仍適用於 Webpack 4,以防您需要!
我們使用 npm: $ npm init
命令在專案資料夾中建立一個 package.json 文件,我們將在其中放置 JavaScript 依賴項。然後我們可以使用 $ npm i --save-dev webpack webpack-cli 來安裝 Webpack 本身。
Webpack 從單一 JavaScript 檔案開始運作,該檔案稱為入口點。在 javascript 資料夾中建立 index.js。您可以在這裡編寫一些簡單的程式碼,例如 console.log('Hi')
以確保其正常運作。
....在專案資料夾中。這裡是所有:sparkles:魔法發生的地方。
// Webpack uses this to work with directories
const path = require('path');
// This is the main configuration object.
// Here, you write different options and tell Webpack what to do
module.exports = {
// Path to your entry point. From this file Webpack will begin its work
entry: './src/javascript/index.js',
// Path and filename of your result bundle.
// Webpack will bundle all JavaScript into this file
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '',
filename: 'bundle.js'
},
// Default mode for Webpack is production.
// Depending on mode Webpack will apply different things
// on the final bundle. For now, we don't need production's JavaScript
// minifying and other things, so let's set mode to development
mode: 'development'
};
要執行 Webpack,我們必須使用 npm 腳本和簡單的命令「webpack」以及我們的設定檔作為 config 選項。我們的 package.json 現在應該如下所示:
{
"scripts": {
"build": "webpack --config webpack.config.js"
},
"devDependencies": {
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
}
}
透過基本設置,您可以執行“$ npm run build”命令。 Webpack 將尋找我們的入口文件,解析其中的所有import 模組相依性並將其捆綁到dist 資料夾中的單一 .js 檔案。在控制台中,您應該看到如下內容:
如果您將 <script src="dist/bundle.js"></script>
加入到 HTML 檔案中,您應該在瀏覽器控制台中看到「Hi」!
偉大的!我們捆綁了標準 JavaScript。但是,如果我們想使用 ES6(及更高版本)的所有酷炫功能並保持瀏覽器相容性怎麼辦?我們應該如何告訴 Webpack 將我們的 ES6 程式碼轉換(transpile)相容於瀏覽器的程式碼?
這就是 Webpack loaders 發揮作用的地方。 Loader 是 Webpack 的主要功能之一。他們對我們的程式碼進行某些轉換。
讓我們在 webpack.config.js 檔案中新增選項 module.rules。在此選項中,我們將介紹 Webpack 如何準確地轉換不同類型的檔案。
entry: /* ... */,
output: /* ... */,
module: {
rules: [
]
}
對於 JavaScript 文件,我們將使用:
Babel 是目前最好的 JavaScript 轉譯器。我們將告訴 Webpack 在捆綁之前使用它將現代 JavaScript 程式碼轉換為與瀏覽器相容的 JavaScript 程式碼。
Babel-loader 正是這樣做的。讓我們安裝它:
$ npm i --save-dev babel-loader @babel/core @babel/preset-env
現在我們要新增有關 JavaScript 檔案的規則:
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
test
是我們要轉換的檔案副檔名的正規表示式。在我們的例子中,它是 JavaScript 檔案。
exclude
是一個正規表示式,它告訴 Webpack 在轉換模組時應該忽略哪個路徑。這意味著如果我們將來導入它們,我們將不會轉換從 npm 匯入的供應商庫。
use
是主要規則的選項。這裡我們設定 loader,它將應用於與「test」正規表示式相對應的檔案(在本例中為 JavaScript 檔案)
“選項”可能因載入程式而異。在這種情況下,我們為 Babel 設定預設預設,以考慮應該轉換哪些 ES6 功能,哪些不應該轉換。它本身是一個單獨的主題,如果您感興趣,可以深入研究它,但目前保持這樣是安全的。
現在您可以將 ES6 程式碼安全地放置在 JavaScript 模組中!
是時候處理樣式了。通常,我們不想寫純 CSS。我們經常使用 SASS 預處理器。我們將 SASS 轉換為 CSS,然後應用自動前綴和縮小。這是 CSS 的一種「預設」方法。讓我們告訴 Webpack 要這樣做。
假設我們在 javascripts/index.js 入口點導入主 SASS 檔案 sass/styles.scss。
import '../sass/styles.scss';
但目前,Webpack 不知道如何處理 .scss 檔案或除 .js 之外的任何檔案。我們需要新增適當的載入器,以便 Webpack 可以解析這些檔案:
$ npm i --save-dev sass sass-loader postcss-loader css-loader
我們可以為 SASS 檔案新增規則並告訴 Webpack 如何處理它們:
rules: [
{
test: /\.js$/,
/* ... */
},
{
// Apply rule for .sass, .scss or .css files
test: /\.(sa|sc|c)ss$/,
// Set loaders to transform files.
// Loaders are applying from right to left(!)
// The first loader will be applied after others
use: [
{
// This loader resolves url() and @imports inside CSS
loader: "css-loader",
},
{
// Then we apply postCSS fixes like autoprefixer and minifying
loader: "postcss-loader"
},
{
// First we transform SASS to standard CSS
loader: "sass-loader"
options: {
implementation: require("sass")
}
}
]
}
]
請注意此處有關 Webpack 的重要事項。可連結多個裝載機;它們將從“use”陣列中的最後一個到第一個逐個應用。
現在,當 Webpack 在程式碼中遇到“import 'file.scss';”時,它知道該怎麼做!
我們應該如何告訴 postcss-loader 它必須應用哪些轉換?我們建立一個單獨的設定檔 postcss.config.js
並使用我們的樣式所需的 postcss 外掛程式。您可能會發現對最基本和有用的插件進行縮小和自動加入前綴,以確保 CSS 為您的真實網站做好準備。
首先,安裝這些 postcss 外掛:$ npm i --save-dev autoprefixer cssnano
。
其次,將它們加入到 postcss.config.js 檔案中,如下所示:
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
// More postCSS modules here if needed
]
}
您可以更深入地研究 PostCSS,找到更多適合您的工作流程或專案需求的插件。
在完成所有 CSS 設定之後,只剩下一件事了。 Webpack 將解析您的 .scss 導入,對其進行轉換,然後...下一步是什麼?它不會神奇地建立一個與您的樣式捆綁在一起的單一 .css 檔案;我們必須告訴 Webpack 要這樣做。但這個任務超出了裝載機的能力範圍。為此,我們必須使用 Webpack 的 插件。
他們的目的是做裝載機做不到的任何事。如果我們需要將所有轉換後的 CSS 提取到一個單獨的「捆綁」檔案中,我們必須使用插件。我們的案例有一個特殊的插件:MiniCssExtractPlugin:
$ npm i --save-dev mini-css-extract-plugin
我們可以在 webpack.config.js 檔案的開頭單獨導入外掛:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
在我們設定載入器的“module.rules”陣列之後加入新的“plugins”程式碼,我們用選項啟動我們的插件:
module: {
rules: [
/* ... */
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "bundle.css"
})
]
現在我們可以將此插件連結到我們的 CSS 載入器中:
{
test: /\.(sa|sc|c)ss$/,
use: [
{
// After all CSS loaders, we use a plugin to do its work.
// It gets all transformed CSS and extracts it into separate
// single bundled file
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader",
},
/* ... Other loaders ... */
]
}
完畢!如果您按照步驟操作,則可以執行「$ npm run build」命令並在 dist 資料夾中找到 bundle.css 檔案。現在的一般設定應如下所示:
Webpack 有大量用於不同目的的插件。您可以根據需要在官方文件中探索它們。
此時,您應該了解 Webpack 工作原理的基礎知識。但我們還沒完成。大多數網站都需要一些資源:我們透過 CSS 設定的圖像和字體。由於 css-loader,Webpack 可以解析 background-image: url(...)
行,但它不知道如果將 URL 設為 .png 或 jpg 檔案該怎麼辦。
我們需要一個新的載入器來處理 CSS 內的檔案或能夠直接在 JavaScript 中匯入它們。這是:
使用 $ npm i --save-dev file-loader
安裝它,並在我們的 webpack.config.js 新增規則:
rules: [
{
test: /\.js$/,
/* ... */
},
{
test: /\.(sa|sc|c)ss$/,
/* ... */
},
{
// Now we apply rule for images
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
// Using file-loader for these files
loader: "file-loader",
// In options we can set different things like format
// and directory to save
options: {
outputPath: 'images'
}
}
]
}
]
現在,如果你在 CSS 中使用一些像這樣的圖像:
body {
background-image: url('../images/cat.jpg');
}
Webpack 將成功解決它。您將在 dist/images 資料夾中找到帶有雜湊名稱的圖像。在 bundle.css 會發現類似這樣的內容:
body {
background-image: url(images/e1d5874c81ec7d690e1de0cadb0d3b8b.jpg);
}
正如你所看到的,Webpack 非常聰明——它正確解析了你的 url 相對於 dist 資料夾的路徑!
您也可以為字體加入規則並以與圖像類似的方式解析它們;將 outputPath 變更為 fonts 資料夾以保持一致性:
rules: [
{
test: /\.js$/,
/* ... */
},
{
test: /\.(sa|sc|c)ss$/,
/* ... */
},
{
test: /\.(png|jpe?g|gif|svg)$/,
/* ... */
},
{
// Apply rule for fonts files
test: /\.(woff|woff2|ttf|otf|eot)$/,
use: [
{
// Using file-loader too
loader: "file-loader",
options: {
outputPath: 'fonts'
}
}
]
}
]
就是這樣!經典網站的簡單 Webpack 設定。我們介紹了 入口點、載入器 和 插件 的概念以及 Webpack 如何轉換和捆綁檔案。
當然,這是一個非常簡單的配置,旨在了解 Webpack 的一般概念。如果您需要的話,還有很多事情可以加入:來源映射、熱重載、設定 JavaScript 框架以及 Webpack 可以做的所有其他事情,但我覺得這些事情超出了本指南的範圍。
如果您遇到困難或想了解更多訊息,我鼓勵您查看 Webpack 官方文件。快樂捆綁!