webpack 常用插件

  1. clean-webpack-plugin
    这个插件的主要作用是清除构建目录中的旧文件,以确保每次构建时都能得到一个干净的环境。
javascript 复制代码
var { CleanWebpackPlugin } = require("clean-webpack-plugin")
const path = require("path");

module.exports = {
    mode: "development",
    devtool: "source-map",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[chunkhash:5].js"
    },
    plugins: [
        new CleanWebpackPlugin()
    ]
}

默认情况下,CleanWebpackPlugin 会清除输出目录(即 output.path 指定的目录)中的所有文件和子目录。如果您想自定义哪些文件或目录需要被清除,您可以在创建 CleanWebpackPlugin 实例时传递一个选项

javascript 复制代码
new CleanWebpackPlugin({
  cleanOnceBeforeBuildPatterns: ['**/*', '!/important-file.txt'],
})

在这个例子中,cleanOnceBeforeBuildPatterns 选项是一个字符串数组,用于指定需要被清除的文件或目录。在这个例子中,所有文件和目录都会被清除,但是名为 'important-file.txt' 的文件将被排除在清除之外。

  1. html-webpack-plugin
    在 Webpack 中,html-webpack-plugin 是一个用于生成 HTML 文件的插件。template 参数是这个插件的一个重要配置选项,它指定了要使用的 HTML 模板文件的路径。

当您使用 html-webpack-plugin 时,通常会提供一个 HTML 模板文件,该文件包含了网站的基本结构和引用。html-webpack-plugin 会读取这个模板文件,并根据您的 Webpack 配置和入口点来生成最终的 HTML 文件。

chunks 参数是这个插件的一个重要配置选项,它指定了应该在最终生成的 HTML 文件中包含哪些 chunk(即代码块)

javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require("path");
module.exports = {
    mode: "development",
    devtool: "source-map",
    entry: {
        home: "./src/index.js",
        a: "./src/a.js"
    },
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "scripts/[name].[chunkhash:5].js"
    },
    plugins: [
        new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ["dist/**/*"] }),
        new HtmlWebpackPlugin({
            template: "./public/index.html",
            filename: "home.html",
            chunks: ["home"]
        }),
        new HtmlWebpackPlugin({
            template: "./public/index.html",
            filename: "a.html",
            chunks: ["a"]
        })
    ]
}
  1. copy-webpack-plugin
    复制某个文件或整个文件夹到生成目录中
javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin');
const path = require("path");
module.exports = {
    mode: "development",
    devtool: "source-map",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "scripts/[name].[chunkhash:5].js"
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./public/index.html"
        }),
        new CopyPlugin([
            { from: "./public", to: "./" }
        ])
    ]
}

复制public下的文件和文件夹到dist目录下。

  1. webpack-dev-server
    open:true,告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true 以打开你的默认浏览器。
javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode: "development",
    devtool: "source-map",
    output: {
        filename: "scripts/[name].[chunkhash:5].js"
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./public/index.html"
        })
    ],
    devServer: {
        port: 8000,
        open: true,
        proxy: { //代理规则
            "/api": {
                target: "https://www.bing.com",
                changeOrigin: true //更改请求头中的host和origin
            }
        }
    },
    stats: {
        modules: false,
        colors: true
    }
}
  1. file-loader url-loader

file-loader 和 url-loader 都是 Webpack 的加载器(loaders),它们的作用如下:

file-loader:

描述:将文件发送到输出目录,并返回(相对)URL。

用途:通常用于处理图片、字体等文件资源。

配置:您可以通过在 Webpack 配置文件中添加 file-loader 来使用这个加载器。

url-loader:

描述:如果文件大小小于指定的大小,则将文件转换为 base64 URL,否则使用 file-loader 进行处理。

用途:通常与 file-loader 一起使用,用于处理较小的文件资源,将其转换为 base64 URL,以减少 HTTP 请求。

配置:您可以通过在 Webpack 配置文件中添加 url-loader 来使用这个加载器。

总的来说,file-loader 主要用于处理文件资源,而 url-loader 则在 file-loader 的基础上增加了对较小文件的处理能力,以减少 HTTP 请求。

javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: "development",
    devtool: "source-map",
    output: {
        filename: "scripts/[name].[chunkhash:5].js"
    },
    module: {
        rules: [
            {
                test: /\.(png)|(gif)|(jpg)$/,
                use: [{
                    loader: "url-loader",
                    options: {
                        // limit: false //不限制任何大小,所有经过loader的文件进行base64编码返回
                        limit: 100 * 1024, //只要文件不超过 100*1024 字节,则使用base64编码,否则,交给file-loader进行处理
                        name: "imgs/[name].[hash:5].[ext]"
                    }
                }]
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./public/index.html"
        })
    ],
    devServer: {
        open: true
    },
    stats: {
        modules: false,
        colors: true
    }
}

解决路径问题

在使用file-loader或url-loader时,可能会遇到一个非常有趣的问题

比如,通过webpack打包的目录结构如下:

yaml 复制代码
dist
    |------ img
        |------ a.png  #file-loader生成的文件
    |------ scripts
        |------ main.js  #export default "img/a.png"
    |------ html
        |------ index.html #<script src="../scripts/main.js" ></script>

这种问题发生的根本原因:模块中的路径来自于某个loader或plugin,当产生路径时,loader或plugin只有相对于dist目录的路径,并不知道该路径将在哪个资源中使用,从而无法确定最终正确的路径

面对这种情况,需要依靠webpack的配置publicPath解决

javascript 复制代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: "development",
    devtool: "source-map",
    output: {
        filename: "scripts/[name].[chunkhash:5].js",
        // publicPath: "/"  //配置关闭时,html文件里的script标签是<script defer src="../scripts/main.e5bb4.js"></script>。配置是'/'时,html文件里的script标签是<script defer src="/scripts/main.c9195.js"></script>
    },
    module: {
        rules: [
            {
                test: /\.(png)|(gif)|(jpg)$/,
                use: [{
                    loader: "file-loader",
                    options: {
                        name: "imgs/[name].[hash:5].[ext]"
                    }
                }]
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./public/index.html",
            filename: "html/index.html"
        })
    ],
    devServer: {
        open: true,
        openPage: "html/index.html",
    },
    stats: {
        modules: false,
        colors: true
    }
}

在 Webpack 中,output.publicPath 是一个配置项,它用于指定在引用资源(如图片、字体等)时应该使用的公共路径。

当您在开发环境中使用 Webpack 时,通常会将资源文件(例如 CSS、JS、图片等)放在一个服务器上,并通过一个 URL 来访问这些文件。然而,如果您的资源文件和您的 HTML 文件(即入口文件)不在同一个域名下,那么浏览器可能会阻止您加载这些资源,因为它们被视为跨域请求。

为了解决这个问题,您可以使用 output.publicPath 来告诉 Webpack 在生成资源文件 URL 时应该使用什么样的公共路径。例如,如果您的资源文件放在 https://cdn.example.com/assets/ 这个 URL 下,您可以这样配置 publicPath:

javascript 复制代码
module.exports = {
  //...
  output: {
    publicPath: 'https://cdn.example.com/assets/',
  },
};

然后,Webpack 就会在生成资源文件 URL 时,自动为这些文件添加 publicPath 作为前缀。例如,如果 Webpack 生成了一个名为 main.js 的 JavaScript 文件,并且 publicPath 被设置为 https://cdn.example.com/assets/,那么最终生成的 URL 可能看起来像这样:https://cdn.example.com/assets/main.js。

需要注意的是,publicPath 的值也可以是一个相对路径。例如,如果您的资源文件放在与 HTML 文件相同的域名下,但是位于不同的目录中,您可以这样配置 publicPath:

javascript 复制代码
module.exports = {
  //...
  output: {
    publicPath: '/assets/',
  },
};

在这个例子中,publicPath 被设置为 /assets/,这意味着资源文件会被放置在与 HTML 文件相同域名的根目录下的 /assets/ 目录下。

  1. 内置插件 DefinePlugin BannerPlugin ProvidePlugin

DefinePlugin 允许在 编译时 将你代码中的变量替换为其他值或表达式。这在需要根据开发模式与生产模式进行不同的操作时,非常有用。例如,如果想在开发构建中进行日志记录,而不在生产构建中进行,就可以定义一个全局常量去判断是否记录日志。这就是 DefinePlugin 的发光之处,设置好它,就可以忘掉开发环境和生产环境的构建规则。

请注意,由于本插件会直接替换文本,因此提供的值必须在字符串本身中再包含一个 实际的引号 。通常,可以使用类似 '"production"' 这样的替换引号,或者直接用 JSON.stringify('production')。

为每个 chunk 文件头部添加 banner。

ProvidePlugin自动加载模块,而不必导入或随处要求这些模块。

所有的webpack内置插件都作为webpack的静态属性存在的,使用下面的方式即可创建一个插件对象

js 复制代码
const webpack = require("webpack")

new webpack.插件名(options)

DefinePlugin

全局常量定义插件,使用该插件通常定义一些常量值,例如:

js 复制代码
new webpack.DefinePlugin({
    PI: `Math.PI`, // PI = Math.PI
    VERSION: `"1.0.0"`, // VERSION = "1.0.0"
    DOMAIN: JSON.stringify("duyi.com")
})

这样一来,在源码中,我们可以直接使用插件中提供的常量,当webpack编译完成后,会自动替换为常量的值

BannerPlugin

它可以为每个chunk生成的文件头部添加一行注释,一般用于添加作者、公司、版权等信息

js 复制代码
new webpack.BannerPlugin({
  banner: `
  hash:[hash]
  chunkhash:[chunkhash]
  name:[name]
  author:yuanjin
  corporation:duyi
  `
})

ProvidePlugin

自动加载模块,而不必到处 import 或 require

js 复制代码
new webpack.ProvidePlugin({
  $: 'jquery',
  _: 'lodash'
})

然后在我们任意源码中:

js 复制代码
$('#item'); // <= 起作用
_.drop([1, 2, 3], 2); // <= 起作用
相关推荐
guzicheng19901 天前
webpack 安装笔记:全局 vs 本地,以及一个 PATH 环境变量的坑
前端·webpack
liangshanbo121510 天前
面试题:Webpack 的 publicPath 有什么作用?
前端·webpack·node.js
liangshanbo121512 天前
Webpack vs Vite 底层原理高频追问的问题
前端·webpack·node.js
liangshanbo121512 天前
面试题:AI 对话上下文超限怎么办?
面试·webpack·devops
liangshanbo121513 天前
Webpack 文件指纹面试题整理
前端·webpack·node.js
liangshanbo121513 天前
Webpack 常见 Plugin 面试题
前端·webpack·node.js
liangshanbo121513 天前
Webpack Tree Shaking 面试题整理
前端·webpack·node.js
陪我一起学编程13 天前
vue3笔记
前端·webpack·vue3·vite·脚手架·vue3笔记·组件式
liangshanbo121513 天前
Webpack的分包策略面试题
前端·webpack·node.js
liangshanbo121515 天前
面试题:如何优化 Webpack 的打包速度?
前端·webpack·node.js