Plugin
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可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;
CleanWebpackPlugin
每次修改了一些配置,重新打包时,都需要手动删除dist文件夹:
可以借助于一个插件来完成:CleanWebpackPlugin;npm install clean-webpack-plugin -D
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [new CleanWebpackPlugin()],
}
配置上述内容后,就可以自动删除打包目录了。
HtmlWebpackPlugin
另外还有一个不太规范的地方:
- HTML文件是编写在根目录下的,而最终打包的dist文件夹中是没有index.html文件的。
- 在进行项目部署的时,必然也是需要有对应的入口文件index.html;
- 所以我们也需要对index.html进行打包处理;
npm install html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
title: 'Hello cos..', // 这里的配置可以修改网页的titile
}),
],
}
默认情况下这个index.html文件是根据ejs模板来生成的;
- 在html-webpack-plugin的源码中,有一个default_index.ejs模块;
自定义HTML模板
- 如果想在自己的模块中加入一些比较特别的内容:
- 比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;
- 比如在开发vue或者react项目时,需要一个可以挂载后续组件的根标签 ;
- 这样我们就会需要一个属于自己的index.html模块: ```html <!DOCTYPE html>
<a name="uyGI9"></a>
### 自定义模板数据填充
- 上面的代码中,会有一些类似这样的语法**<% 变量 %>**,这个是**EJS模块填充数据**的方式。
- 在配置HtmlWebpackPlugin时,我们可以添加如下配置:
- template:指定我们要使用的模块所在的路径;``
- title:在进行htmlWebpackPlugin.options.title读取时,就会读到该信息;
```javascript
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
...
new HtmlWebpackPlugin({
title: 'Hello cos..',
template: './public/index.html',
}),
],
}
DefinePlugin
- 但是,这个时候编译还是会报错,因为在我们的模块中还使用到一个BASE_URL的常量:
- 这是因为在编译template模块时,有一个BASE_URL:
- ;
- 但是我们并没有设置过这个常量值,所以会出现没有定义的错误;
- 这个时候我们可以使用DefinePlugin插件;
DefinePlugin的使用
DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装) ```javascript const { DefinePlugin } = require(‘webpack’);
modle.exports = { … plugins: [ new DefinePlugin({ BASE_URL: ‘“./“‘, // 这里的./表示的就是打包文件的根目录 }), ], }
这个时候,编译template就可以正确的编译了,会读取到BASE_URL的值;
<a name="i2IZb"></a>
## CopyWebpackPlugin
在vue的打包过程中,我们会将一些文件放到public的目录下,希望这个目录会被复制到dist文件夹中。<br />这个复制的功能,我们可以使用CopyWebpackPlugin来完成;<br />`npm install copy-webpack-plugin -D`
<a name="EjlWF"></a>
### 配置CopyWebpackPlugin即可
- 复制的规则在patterns中设置;
- from:设置从哪一个源中开始复制;
- to:复制到的位置,可以省略,会默认复制到打包的目录下;
- globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:
- .DS_Store:mac目录下会自动生成的一个文件;
- index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;
```javascript
const CopyWebpackPlugin = require('copy-webpack-plugin');
medule.exports = {
plugins: [
new CopyWebpackPlugin({
// 这里如果要复制多个文件夹,可以再patterns里面传入多个对象
patterns: [
{
from: 'public',
to: './',
globOptions: {
ignore: ['**/index.html'],
},
},
],
}),
]
}
glob 模式匹配简明教程:https://juejin.cn/post/6844904077801816077
Mode配置
- Mode配置选项,可以告知webpack使用响应模式的内置优化:
- 默认值是production(什么都不设置的情况下);
- 可选值有:’none’ | ‘development’ | ‘production’;
- 这几个选项有什么样的区别呢?
如果mode为 production,那么我们出现了报错是很难定位到源码的位置的:
当mode设置为 development的时候,其实就可以看到出错的是element.js文件的第33行代码了。
不过我们设置development之后,bundler.js中的代码中还是可以看到大量的eval(),
可以设置devtool: 'source-map'
,生成sourcemap文件。·
Mode代表了更多的配置
这些配置是webpack根据我们设置的mode,来自动配置的: