06_webpack的Plugin
什么是plugin
官方解释:
插件 是 webpack 的 支柱 功能。Webpack 自身也是构建于你在 webpack 配置中用到的 相同的插件系统 之上!
插件目的在于解决 loader 无法实现的其他事。Webpack 提供很多开箱即用的 插件。
Loader是用于特定的模块类型进行转换;
Plugin可以用于执行更加广泛的任务,比如打包优化,资源管理,环境变量注入等;
CleanWebpackPlugin
像我们之前运行npm run build的时候,我们的build文件生成的东西并不会清空掉,一直保留着我们之前打包过的东西
这样我们还需要手动清理,我们可以通过一个插件,帮助我们解决这个问题
安装
npm i clean-webpack-plugin
配置
//导入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin') //在module.export中定义plugins属性,然后new一个对象 plugins: [ new CleanWebpackPlugin() ]
HtmlWebpackPlugin
在之前我们都是手动的创建index.html并且手动的去引入bundle.js
总之我们在之前对html文件的处理是不好的
我们希望在打包之后的build文件夹中有这么一个html文件并且帮我们自动引入bundle.js文件
这个时候我们可以使用HtmlWebpackPlugin插件
安装
npm i html-webpack-plugin
//1.引入 const HtmlWebpackPlugin = require('html-webpack-plugin') //2.在module.exports配置 plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin() ]
那么在运行 npm run build的时候build文件夹下就会自动生成一个index.html文件,并且帮我们把bundle.js文件进行了引入
它是怎么生成的呢?通过ejs模板来进行生成的,node_modules/html-webpack-plugin/default_index.ejs
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= htmlWebpackPlugin.options.title %>title>
head>
<body>
body>
html>
我们可以修改它的title
plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'webpack' }) ]
在vue中我们需要在body中创建一个 id为app的div,这个时候模板不会帮我们自动生成,那么怎么办呢?
我们可以自定义模板引擎
在项目目录中创建public目录,下面新建一个index.html,这里我们把vue默认的public文件拿过来
DOCTYPE html>
<html lang="">
<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 rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %>title>
head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
noscript>
<div id="app">div>
body>
html>
然后在配置文件中进行配置
plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'coderwhy', template: './public/index.html' }) ]
但是这样子运行还是报错,因为我们自定义的模板引擎里面,有引用一个icon图标
它不是像<%= htmlWebpackPlugin.options.title %> 这样取一个变量,而是用的全局的
而我们全局中并没有这么一个BASE_URL
那么我们怎么解决这个问题?
一:删除掉 这段代码
二:在webpack定义一个全局BASE_URL常量进行赋值
怎么在全局定义常量?这就要用到DefinePlugin
DefinePlugin
DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装)
也可以区别开发模式和生产模式
那么怎么使用呢?
const { DefinePlugin } = require('webpack')
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'coderwhy',
template: './public/index.html'
}),
new DefinePlugin({
// 如果这里设置的是BASE_URL='./' 因为webpack在取值的时候相当于 BASE_ULR=./ 这样子的语法是有问题的,所以我们还要在外层包裹一个""
//因为favicon.ico打包是打包在build文件夹下面的index.html也是,所以我们的路径是./
BASE_URL: "'./'"
})
]
我们项目中的icos是在public和index.html同级的,那么怎么把他打包到build文件夹中去呢?
我们可以去使用另外一个插件
CopyWebpackPlugin
安装
npm i copy-webpack-plugin
他是有非常多参数的 webpack 中文文档 (docschina.org)
配置使用
//1.引入 const CopyWebpackPlugin = require('copy-webpack-plugin') //2.使用 plugins: [ new CopyWebpackPlugin({ //匹配到哪些东西复制到哪去 patterns: [ { from: 'public', // to是可以省略的,他是会根据output查找路径的 // to:"build" //那个文件是需要忽略的 globOptions: { ignore: [ //不这样写是会有问题的 "**/index.html" ] } } ] }) ]