webpack5入門教程

Webpack入門

Webpack是什麼

Webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler), 也就是個打包工具。它會以一個或多個文件作爲打包的入口,將我們整個項目所有文件編譯組合成一個或多個文件輸出出去。輸出的文件就是編譯好的文件,就可以在瀏覽器運行了。我們將 Webpack 輸出的文件叫做 bundle。

爲什麼需要打包工具

開發時,我們會使用框架(React、Vue),ES6 模塊化語法,Less/Sass 等 css 預處理器等語法進行開發。這樣的代碼要想在瀏覽器運行必須經過編譯成瀏覽器能識別的 JS、Css 等語法,才能運行。所以我們需要打包工具幫我們做完這些事。除此之外,打包工具還能壓縮代碼、做兼容性處理、提升代碼性能等。

 

一、基本使用

先創建項目,然後來到項目根目錄

初始化package.json

npm init -y

此此時會生成一個基礎的 package.json 文件。

安裝webpack

在安裝webpack之前,請確保本地環境安裝了node.js, 儘量使用node新的長期支持的版本,舊版本可能遇到很多問題,因爲它們可能缺少 webpack 功能以及/或者缺少相關 package 包。

npm install webpack --save-dev

如果使用 webpack 4+ 版本,還需要安裝 CLI。

npm install webpack-cli --save-dev

webpack-cli - 此工具用於在命令行中運行 webpack。

創建文件

在項目根目錄創建src文件夾, 再創建index.js文件

  • index.js
function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}

sum(2, 3, 5);

目錄結構

webpack-course # 項目根目錄(所有指令必須在這個目錄運行)
    │── node_modules
    │── src # 項目源碼目錄
    |    └── index.js # 項目主文件
    |
    └── package-lock.json
    └── package.json

webpack打包

npx webpack ./src/index.js --mode=development

npx webpack: 是用於運行本地安裝 Webpack 

./src/index.js: 指定 Webpack  index.js 文件開始打包

--mode=development:指定打包模式

默認 Webpack 會將文件打包輸出到 dist 目錄下,如果自動創建了dist目錄那就代表打包成功了

總結

Webpack 本身功能比較少,只能處理 js 資源,一旦遇到其他資源就會報錯

所以我們學習 Webpack,就是主要學習如何處理其他資源

 

二、核心概念

entry(入口)

指示 webpack 應該從哪個文件開始打包, 默認爲./src/index.js

output(出口)

指示 webpack 應該將打包好的文件輸出到哪個目錄,以及文件命名等, 默認爲./dist/main.js

loader

webpack 自身只理解 javascript, 而 loader 可以去處理那些非js的文件

loader 可以將所有類型的文件轉換爲 webpack 能夠處理的有效模塊, 然後就可以利用 webpack 的打包能力正常進行打包

plugins(插件)

plugins 用於擴展 webpack 功能,打包優化、壓縮代碼體積等

插件功能極其強大,可以用來處理各種各樣的任務

想要使用一個插件,只需要 require() 它,然後把它添加到 plugins 數組中。多數插件可以通過選項(option)自定義

也可以在一個配置文件中因爲不同目的而多次使用同一個插件,這時需要通過使用 new 操作符來創建它的一個實例

mode(打包模式)

兩種模式:

開發模式:development
生產模式:production

 

三、基本配置

webpack配置文件

在項目根目錄下新建文件:webpack.config.js

  • webpack.config.js的作用

    • webpack.config.js  webpack 的配置文件

    • webpack 在打包構建之前,會先讀取這個配置文件, 從而基於給定的配置,再對項目進行打包

Webpack 是基於 Node.js 運行的,所以配置文件採用 Common.js 模塊化規範

編輯配置文件

webpack.config.js

// Node.js的核心模塊,用於處理文件路徑
const path = require('path'); 

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'),  // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js'  // 輸出文件的文件名
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        // 暫時只有js文件,現在用不着
    },
    // 插件列表 webpack各種擴展功能 
    plugins: [],
}

配置腳本命令

可以在package.json ---> scripts對象下面配置腳本

"scripts": {
	"build": "webpack" // script 節點下的腳本,可以通過npm run 執行。例如npm run build  就可以執行webpack這條命令了
}

運行腳本打包

npm run build

此時功能和前面一樣,也不能處理樣式資源

總結

Webpack 都通過 webpack.config.js 文件進行配置,來增強 Webpack 的功能

 

四、處理樣式資源

webpack 默認只能打包處理以.js後綴名結尾的模塊。其他非.js後綴名結尾的模塊webpack默認處理不了,需要調用loader纔可以正常打包

loader的作用:協助webpack打包處理特定的文件模塊

處理css資源

添加css資源

  • src/index.css
.box1 {
    width: 300px;
    height: 300px;
    background-color: red;
}

引入css資源

function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}
sum(2, 3, 5);

// 引入 Css 資源,Webpack纔會對其打包
import './index.css'

下載依賴

npm i css-loader style-loader --save-dev

loader介紹

  • css-loader: 負責將 Css 文件編譯成 Webpack 能識別的模塊
  • style-loader: 會動態創建一個 Style 標籤,裏面放置 Webpack 中 Css 模塊內容, 樣式就會以 Style 標籤的形式在頁面上生效

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path'); 

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'),  // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js'  // 輸出文件的文件名
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            }
        ]
    },
    // 插件列表 webpack各種擴展功能 
    plugins: [],
}

test 表示匹配的文件類型

use 表示對應要調用的 loader

include 表示需要檢查的目錄

exclude 表示不需要檢查的目錄

注意:

use數組中指定的loader順序是固定的

多個loader的調用順序是:從後往前調用

webpack 默認只能打包處理.js結尾的文件,處理不了其他後綴的文件
由於代碼中包含了index.css這個文件,因此webpack默認處理不了
當webpack發現某個文件處理不了,會查找webpack.config.js這個配置文件,看module.rules數組中,是否配置了對應的loader。
webpack把index.css這個文件,先轉交給配置數組的最後一個loader進行處理(先轉交給css-loader)
當css-loader處理完畢之後,會把處理的結果,轉交給前一個loader(轉交給style-loader)
當style-loader處理完畢後,發現前面沒有loader了,於是就把處理的結果,轉交給了webpack
webpack把style-loader處理的結果,合併到/dist/bundle.js中,最終生成打包好的文件。

打包

npm run build

查看效果

創建html模板文件

dist/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 準備一個使用樣式的 DOM 容器 -->
    <div class="box1"></div>
    <!-- 引入打包後的js文件 -->
    <script src="./bundle.js"></script>
</body>

</html>

處理 less 和 sass/scss 資源

添加資源

  • src/index.less
#app {
    .box2 {
        height: 300px;
        width: 300px;
        background-color: aquamarine;
    }
}
  • src/index.scss
#app {
    .box3 {
        height: 300px;
        width: 300px;
        background-color: burlywood;
    }
}

引入資源

function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}
sum(2, 3, 5);

// 引入 Css 資源,Webpack纔會對其打包
import './index.css'
import './index.less'
import './index.scss'

下載依賴

npm i less-loader node-sass sass-loader --save-dev

loader介紹

  • less-loader: 負責將 Less 文件編譯成 Css 文件
  • sass-loader: 負責將 Sass 文件編譯成 css 文件
  • node-sass: sass-loader 依賴 node-sass 進行編譯

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path'); 

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'),  // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js'  // 輸出文件的文件名
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "less-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
        ]
    },
    // 插件列表 webpack各種擴展功能 
    plugins: [],
}

打包

npm run build

查看效果

dist/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 準備一個使用樣式的 DOM 容器 -->
    <div id="app">
        <div class="box2">less</div>
        <div class="box3">sacc/scss</div>
    </div>
    <!-- 引入打包後的js文件 -->
    <script src="./bundle.js"></script>
</body>

</html>

可以看到,lesssass/scss的語法已經被轉換爲css格式

 

五、處理圖片資源

過去在 Webpack4 時,處理圖片資源通過 file-loader  url-loader 進行處理

現在 Webpack5 已經將兩個 Loader 功能內置到 Webpack 裏了,只需要簡單配置即可處理圖片資源

添加圖片資源

src/img/big.jpg - 50.26kb

src/img/small.png - 5.49kb

使用圖片資源

  • src/index.scss
#app {
    .box3 {
        height: 300px;
        width: 300px;
        background-color: burlywood;
    }

    .box4 {
        width: 200px;
        height: 200px;
        background-image: url('./img/big.jpg');
        background-size: cover;
    }

    .box5 {
        width: 100px;
        height: 100px;
        background-image: url('./img/small.png');
        background-size: cover;
    }
}

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "less-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset",
                parser: {
                  dataUrlCondition: {
                    maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                  }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            }
        ]
    },
    // 插件列表 webpack各種擴展功能 
    plugins: [],
}

打包

npm run build

查看效果

dist/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app {
            display: flex;
        }
    </style>
</head>

<body>
    <!-- 準備一個使用樣式的 DOM 容器 -->
    <div id="app">
        <div class="box2">less</div>
        <div class="box3">sacc/scss</div>
        <div class="box4"></div>
        <div class="box5"></div>
    </div>
    <!-- 引入打包後的js文件 -->
    <script src="./bundle.js"></script>
</body>

</html>

查看資源目錄

可以看到只有一張big.jpg打包後的圖片文件,因爲small.png的大小不足10kb data URI 形式內置到 js 中了

 

六、處理js資源

webpack默認處理了js資源, 爲什麼還要處理js資源

這是因爲瀏覽器無法識別es6語法,webpack默認只對js進行打包,不會將es6語法轉換爲es5語法供瀏覽器使用,所以需要我們自己配置,使 es6 語法轉換爲瀏覽器能識別的 es5 語法

下載依賴包

npm i babel-loader @babel/core @bable/preset-env

準備es6資源

src/index.js

function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}
sum(2, 3, 5);

// 添加es6語法
const string = () => {
  return '溫情key'
}

console.log(string());;

// 引入 Css 資源,Webpack纔會對其打包
import './index.css'
import './index.less'
import './index.scss'

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        // clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "less-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"]  // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件列表 webpack各種擴展功能 
    plugins: [],
}

打包

npm run build

查看效果

配置前

配置後

可以看到箭頭函數已經轉換爲了普通的命名函數

 

七、處理html資源

dist 目錄屬於構建目錄,是我們源碼的輸出目錄,我們希望裏面的一切都是可以自動化的,包括 index.html 文件也能自動創建,js 文件也能自動引入到頁面

所以我們需要用到插件 html-webpack-plugin

下載依賴

npm install html-webpack-plugin -D

添加模板文件

src/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app {
            display: flex;
        }
    </style>
</head>

<body>
    <!-- 準備一個使用樣式的 DOM 容器 -->
    <div id="app">
        <div class="box2">less</div>
        <div class="box3">sacc/scss</div>
        <div class="box4"></div>
        <div class="box5"></div>
    </div>
    
</body>

</html>

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');
// 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "less-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"]  // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件配置列表 webpack各種擴展功能 
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',  // 輸出文件的名稱
            // 打包後產出的html文件有兩個特點:1. 內容和源文件一致 2. 自動引入打包生成的js等資源
            template: path.resolve(__dirname, 'src/index.html'),  // 模板文件的路徑
            title: 'webpack-index'  // 生成頁面的標題
        })
    ],
}

打包

npm run build

然後就可以看到dist目錄下自動構建的html文件了。

 

八、開發服務器

在開發階段,遇到的問題是打包、運行、調試過程過於繁瑣,回顧一下我們的操作流程:

編寫代碼
控制檯運行命令完成打包
打開頁面查看效果

並且,我們往往希望把最終生成的代碼和頁面部署到服務器上,來模擬真實環境

爲了解決這些問題,webpack官方製作了一個單獨的庫:webpack-dev-server

它既不是plugin也不是loader

接下來看看它怎麼用

下載依賴

npm i webpack-dev-server -D

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');
// 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "less-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader"
                ],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"]  // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件配置列表 webpack各種擴展功能 
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',  // 輸出文件的名稱
            // 打包後產出的html文件有兩個特點:1. 內容和源文件一致 2. 自動引入打包生成的js等資源
            template: path.resolve(__dirname, 'src/index.html'),  // 模板文件的路徑
        })
    ],
    // 開發服務器 devServer 自動化(修改代碼自動編譯,自動刷新瀏覽器)
    // 特點:只會在內存中編譯打包,不會有任何輸出
    // 啓動devServer指令爲:webpack-dev-server
    devServer: {
        port: 8088, // 服務器啓動端口號
        static: path.join(__dirname, 'dist'), // 服務器靜態資源目錄
        open: false, // 啓動服務器後自動打開瀏覽器
        compress: true, // 開啓gzip壓縮
    }
}

配置命令

package.json

"scripts": {
    "dev": "webpack-dev-server",
    "build": "webpack"
}

執行命令

npm run dev

當在使用開發服務器時,所有代碼都會在內存中編譯打包,並不會輸出到 dist 目錄下。

 

九、css方面優化

單獨文件

css文件不處理會被打包到js文件中,當js文件加載時,會創建一個style標籤來生成樣式

這樣對於網站來說,可能會出現閃屏現象,用戶體驗不好

我們應該要使用單獨的css文件,通過link標籤加載提高用戶體驗

安裝依賴

npm i mini-css-extract-plugin -D

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');
// 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, "css-loader"],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"] // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件配置列表 webpack各種擴展功能 
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html', // 輸出文件的名稱
            // 打包後產出的html文件有兩個特點:1. 內容和源文件一致 2. 自動引入打包生成的js等資源
            template: path.resolve(__dirname, 'src/index.html'), // 模板文件的路徑
        }),
        // 提取css成單獨文件
        new MiniCssExtractPlugin({
            // 定義輸出文件名和目錄
            filename: "static/css/main.css",
        }),
    ],
    // 開發服務器 devServer 自動化(修改代碼自動編譯,自動刷新瀏覽器)
    // 特點:只會在內存中編譯打包,不會有任何輸出
    // 啓動devServer指令爲:webpack-dev-server
    devServer: {
        port: 8088, // 服務器啓動端口號
        static: path.join(__dirname, 'dist'), // 服務器靜態資源目錄
        open: false, // 啓動服務器後自動打開瀏覽器
        compress: true, // 開啓gzip壓縮
    }
}

打包

npm run build

打包成功後可以看到dist目錄下static/css多出一個單獨的css文件main.css

兼容性處理

因爲css3樣式需要加不同的瀏覽器前綴才能兼容對應的瀏覽器,因此在項目打包編譯的時候,需要對css3屬性進行統一的兼容性處理。

下載依賴

npm i postcss-loader postcss postcss-preset-env -D

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');
// 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// 獲取處理樣式的Loaders
const getStyleLoaders = (preProcessor) => {
    return [
      MiniCssExtractPlugin.loader,
      "css-loader",
      {
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            plugins: [
              "postcss-preset-env", // 將package文件中的css兼容性樣式引入進來
            ],
          },
        },
      },
      preProcessor,
    ].filter(Boolean);
  };

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: getStyleLoaders(),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: getStyleLoaders("less-loader"),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders("sass-loader"),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"] // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件配置列表 webpack各種擴展功能 
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html', // 輸出文件的名稱
            // 打包後產出的html文件有兩個特點:1. 內容和源文件一致 2. 自動引入打包生成的js等資源
            template: path.resolve(__dirname, 'src/index.html'), // 模板文件的路徑
        }),
        // 提取css成單獨文件
        new MiniCssExtractPlugin({
            // 定義輸出文件名和目錄
            filename: "static/css/main.css",
        }),
    ],
    // 開發服務器 devServer 自動化(修改代碼自動編譯,自動刷新瀏覽器)
    // 特點:只會在內存中編譯打包,不會有任何輸出
    // 啓動devServer指令爲:webpack-dev-server
    devServer: {
        port: 8088, // 服務器啓動端口號
        static: path.join(__dirname, 'dist'), // 服務器靜態資源目錄
        open: false, // 啓動服務器後自動打開瀏覽器
        compress: true, // 開啓gzip壓縮
    }
}

兼容配置

package.json

"browserslist": [
    "> 1%",
    "last 2 versions"
]

配置兼容性前後對比

配置前

配置後

css壓縮

壓縮css代碼體積

下載依賴

npm i css-minimizer-webpack-plugin -D

配置

// Node.js的核心模塊,用於處理文件路徑
const path = require('path');
// 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// 獲取處理樣式的Loaders
const getStyleLoaders = (preProcessor) => {
    return [
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        "postcss-preset-env", // 將package文件中的css兼容性樣式引入進來
                    ],
                },
            },
        },
        preProcessor,
    ].filter(Boolean);
};

module.exports = {
    // 模式 
    mode: 'development',
    // 入口 告訴webpack從哪個文件開始進行打包  path.resolve()方法返回一個絕對路徑  __dirname 當前文件的文件夾絕對路徑
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // 出口 webpack 輸出結果的相關配置
    output: {
        path: path.resolve(__dirname, 'dist'), // 所有輸出文件的目標路徑  必須是絕對路徑(使用 Node.js 的 path 模塊)
        filename: 'bundle.js', // 輸出文件的文件名
        clean: true, // 自動將上次打包目錄資源清空
    },
    // 模塊  處理項目中各種不同類型的模塊
    module: {
        rules: [{
                test: /\.css$/,
                use: getStyleLoaders(),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: getStyleLoaders("less-loader"),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders("sass-loader"),
                include: path.join(__dirname, 'src'),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|webp)$/,
                type: "asset", // 相當於url-loader, 將文件轉化成 Webpack 能識別的資源,同時小於某個大小的資源會處理成 data URI 形式
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024 // 小於10kb的圖片會被base64處理
                    }
                },
                generator: {
                    // 將圖片文件輸出到 static 目錄中
                    // 將圖片文件命名 [hash:8][ext][query]
                    // [hash:8]: hash值取8位
                    // [ext]: 使用之前的文件擴展名
                    // [query]: 添加之前的query參數
                    filename: "static/[hash:8][ext][query]",
                },
            },
            {
                test: /\.js/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env"] // 預設: babel一系列插件的集合
                    }
                }
            }
        ]
    },
    // 插件配置列表 webpack各種擴展功能 
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html', // 輸出文件的名稱
            // 打包後產出的html文件有兩個特點:1. 內容和源文件一致 2. 自動引入打包生成的js等資源
            template: path.resolve(__dirname, 'src/index.html'), // 模板文件的路徑
        }),
        // 提取css成單獨文件
        new MiniCssExtractPlugin({
            // 定義輸出文件名和目錄
            filename: "static/css/main.css",
        }),
        // css壓縮
        new CssMinimizerPlugin(),
    ],
    // 開發服務器 devServer 自動化(修改代碼自動編譯,自動刷新瀏覽器)
    // 特點:只會在內存中編譯打包,不會有任何輸出
    // 啓動devServer指令爲:webpack-dev-server
    devServer: {
        port: 8088, // 服務器啓動端口號
        static: path.join(__dirname, 'dist'), // 服務器靜態資源目錄
        open: false, // 啓動服務器後自動打開瀏覽器
        compress: true, // 開啓gzip壓縮
    }
}

打包

npm run build

可以看下打包後的css文件,配置css壓縮前和配置css壓縮後有很明顯的變化

https://gitee.com/wenqingkey/webpack-course

 

轉自:https://blog.csdn.net/qq_48960335/article/details/126680154

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章