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> <!-- built files will be auto injected --> </body> </html>
然后在配置文件中进行配置
plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'coderwhy', template: './public/index.html' }) ]
但是这样子运行还是报错,因为我们自定义的模板引擎里面,有引用一个icon图标
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
它不是像<%= htmlWebpackPlugin.options.title %> 这样取一个变量,而是用的全局的
而我们全局中并没有这么一个BASE_URL
那么我们怎么解决这个问题?
一:删除掉 <link rel="icon" href="<%= BASE_URL %>favicon.ico"> 这段代码
二:在webpack定义一个全局BASE_URL常量进行赋值
怎么在全局定义常量?这就要用到DefinePlugin
DefinePlugin
DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装)
当你在js文件中使用了DefinePlugin定义的全局变量时,如:BASE_URL时,经过webpack打包后,它会把BASE_URL替换为:./
也可以区别开发模式和生产模式
那么怎么使用呢?
const { DefinePlugin } = require('webpack') plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'coderwhy', template: './public/index.html' }), new DefinePlugin({ //插件会把值作为js代码来执行,所以跟一个小括号 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" ] } } ] }) ]