webpack 插件

Webpack的另一个核心是Plugin,官方有这样一段对Plugin的描述:

While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.

上面表达的含义翻译过来就是:

  • Loader是用于特定的模块类型进行转换;
  • Plugin可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

image.png

插件的基本使用

插件是一个独立的模块,所以要使用它们我就需要引入它们,并在 webpack.config.js 的 plugins 数组中进行实例化。

const { CleanWebpackPlugin } =  require("clean-webpack-plugin")

module.exports = {
  plugins: [
    new CleanWebpackPlugin()
  ]
}

CleanWebpackPlugin

每次重新打包时,都需要手动删除dist文件夹:我们可以借助于一个插件来帮助我们完成,这个插件就是CleanWebpackPlugin;
安装:npm install clean-webpack-plugin -D

HtmlWebpackPlugin

当前打包后,我们是将生成的 js 文件手动引入到 html 文件中,这很不方便。我们的目标是 webpack 构建后在 disk 文件夹中的产物就是一个完整的整体,我们可以直接部署 dist 目录内的东西到静态服务器上。
所以我们也需要对index.html进行打包处理,这时我们可以使用另外一个插件:HtmlWebpackPlugin;

安装:npm install html-webpack-plugin -D

生成 index.html

HtmlWebpackPlugin 的工作,实际上不是将我们自己写的 html 文件打包到 dist 中。而是自动在dist文件夹中,生成了一个index.html的文件:并且插件会将打包后的 js 文件自动引入到生成的 index.html 中。

这个文件是如何生成的呢?

  • 默认情况下是根据ejs的一个模板来生成的;
  • 在html-webpack-plugin的源码中,有一个 default_index.ejs 模块

指定 HTML 的生成模板

如果我们不想使用默认 EJS 默认的生成模板,想在自己的模块中加入一些比较特别的内容:

  • 比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;
  • 比如在开发vue或者react项目时,我们需要一个可以挂载后续组件的根标签

这时我们就可以指定自己编写的 html 文件为模板,让插件来参照生成。
HtmlWebpackPlugin 实例化时的构造函数可以接收一个对象,里面的 template 属性就可以指定我们想要使用的 html 文件路径。

配置 template 后,打包后的 js 文件也会自动引入到新模板生成的 html 文件中。并且,我们还可以在模板中留一些数据占位符,让插件生成 html 时进行数据填充,也是直接在构造函数中进行配置。

模块中使用<%= htmlWebpackPlugin.options.变量 %>占位,这个是EJS模块填充数据的语法。不止是 HtmlWebpackPlugin 插件使用。

<html>
  <head></head>
  <body>
    <p>
      <%= htmlWebpackPlugin.options.hhh %>
    </p>
  </body>
</html>
const HtmlWebpackPlugin = require("html-webpack-plugin")

plugins: [
  new CleanWebpackPlugin(),
  new HtmlWebpackPlugin({
    template: "./test.html",
    hhh: "FFFFFFFF"
  })
]
<html>
  <head><script defer src="bundle.js"></script></head>
  <body>
    <p>
      FFFFFFFF
    </p>
  </body>
</html>

DefinePlugin

上面是例子创建的是局部变量,属于 HtmlWebpackPlugin,所以我们访问的时候是通过 htmlWebpackPlugin.options.变量去访问。

DefinePlugin 允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装):
比如可以用它来设置 BASE_URL。然后在引入 favicon.ico 时使用。

  • 虽然只要将 favcion.ico 放在根目录,浏览器就会自动检测加载它。但是最好还是明确 link 写出来。
<link ref="icon" href="<%= BASE_URL %>favicon.ico">  
plugins: [ new DefinePlugin({
  BASE_URL: "'./'" // 注意:插入的路径一定要使用引号再包裹一层,要不然 webpack 识别报错
}) ] 

CopyWebpackPlugin

因为 webpack 只能打包入口 js 文件引入了的模块,对于那些没有被 js 引入的文件是不会被打包到 dist 目录的。典型的就是站点图标 favicon.ico。

另外还要注意:上面代码 BASE_URL 设置的./目录,这个目录就是 dist 目录,也就是部署后的主机根目录。比如www.baidu.com/。所以站点图标放在 dist 根目录也是合情合理。

现在问题来了,站点图标并不在 js 的依赖图谱中,dist 目录中压根没有这个 ico 文件。所以我们需要一个插件,能在构建时复制文件到指定目录中。这个插件就是 CopyWebpackPlugin。

安装:npm install copy-webpack-plugin -D

接下来配置CopyWebpackPlugin即可,复制的规则在patterns中设置;

  • from:设置从哪一个源中开始复制;
  • to:复制到的位置,可以省略,会默认复制到打包的目录下;
  • globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:
    • .DS_Store:mac目录下回自动生成的一个文件;
    • index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;

一般不会被 js 引入的静态文件都放在 src 同级的 public 目录中。

const copyWebpackPlugin = require("copy-webpack-plugin")

new copyWebpackPlugin({
  patterns: [{
    from: "./public",
    to: "./img/[name]-[hash:4][ext]",
    globOptions: {
   	 	ignore: [ "**/.DS_Store", "**/index.html" ]
    }
  }]
})

汇总插件的配置

const { CleanWebpackPlugin } =  require("clean-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const copyWebpackPlugin = require("copy-webpack-plugin")
const { DefinePlugin } = require("webpack")

module.exports = {
	plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      title: "DEMO"
    }),
    new DefinePlugin({
      BASE_URL: "'./'"
    }),
    new copyWebpackPlugin({
      patterns: [{
        from: "./public",
        to: "./"
        globOptions: {
        	ignore: [ "**/.DS_Store", "**/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">
    <link ref="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>

  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值