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可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

image.png

CleanWebpackPlugin

每次修改了一些配置,重新打包时,都需要手动删除dist文件夹:
可以借助于一个插件来完成:CleanWebpackPlugin;
npm install clean-webpack-plugin -D

  1. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  2. module.exports = {
  3. plugins: [new CleanWebpackPlugin()],
  4. }

配置上述内容后,就可以自动删除打包目录了。

HtmlWebpackPlugin

  • 另外还有一个不太规范的地方:

    • HTML文件是编写在根目录下的,而最终打包的dist文件夹中是没有index.html文件的。
    • 在进行项目部署的时,必然也是需要有对应的入口文件index.html;
    • 所以我们也需要对index.html进行打包处理;
    • npm install html-webpack-plugin -D
      1. const HtmlWebpackPlugin = require('html-webpack-plugin');
      2. module.exports = {
      3. ...
      4. plugins: [
      5. new HtmlWebpackPlugin({
      6. title: 'Hello cos..', // 这里的配置可以修改网页的titile
      7. }),
      8. ],
      9. }
  • 默认情况下这个index.html文件是根据ejs模板来生成的;

  • 在html-webpack-plugin的源码中,有一个default_index.ejs模块;

自定义HTML模板

  • 如果想在自己的模块中加入一些比较特别的内容:
    • 比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;
    • 比如在开发vue或者react项目时,需要一个可以挂载后续组件的根标签
  • 这样我们就会需要一个属于自己的index.html模块: ```html <!DOCTYPE html>
  1. <a name="uyGI9"></a>
  2. ### 自定义模板数据填充
  3. - 上面的代码中,会有一些类似这样的语法**<% 变量 %>**,这个是**EJS模块填充数据**的方式。
  4. - 在配置HtmlWebpackPlugin时,我们可以添加如下配置:
  5. - template:指定我们要使用的模块所在的路径;``
  6. - title:在进行htmlWebpackPlugin.options.title读取时,就会读到该信息;
  7. ```javascript
  8. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  9. module.exports = {
  10. plugins: [
  11. ...
  12. new HtmlWebpackPlugin({
  13. title: 'Hello cos..',
  14. template: './public/index.html',
  15. }),
  16. ],
  17. }

DefinePlugin

  • 但是,这个时候编译还是会报错,因为在我们的模块中还使用到一个BASE_URL的常量:
  • image.png
  • 这是因为在编译template模块时,有一个BASE_URL:
    • 但是我们并没有设置过这个常量值,所以会出现没有定义的错误;
  • 这个时候我们可以使用DefinePlugin插件;

    DefinePlugin的使用

    DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装) ```javascript const { DefinePlugin } = require(‘webpack’);

modle.exports = { … plugins: [ new DefinePlugin({ BASE_URL: ‘“./“‘, // 这里的./表示的就是打包文件的根目录 }), ], }

  1. 这个时候,编译template就可以正确的编译了,会读取到BASE_URL的值;
  2. <a name="i2IZb"></a>
  3. ## CopyWebpackPlugin
  4. vue的打包过程中,我们会将一些文件放到public的目录下,希望这个目录会被复制到dist文件夹中。<br />这个复制的功能,我们可以使用CopyWebpackPlugin来完成;<br />`npm install copy-webpack-plugin -D`
  5. <a name="EjlWF"></a>
  6. ### 配置CopyWebpackPlugin即可
  7. - 复制的规则在patterns中设置;
  8. - from:设置从哪一个源中开始复制;
  9. - to:复制到的位置,可以省略,会默认复制到打包的目录下;
  10. - globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:
  11. - .DS_Storemac目录下会自动生成的一个文件;
  12. - index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;
  13. ```javascript
  14. const CopyWebpackPlugin = require('copy-webpack-plugin');
  15. medule.exports = {
  16. plugins: [
  17. new CopyWebpackPlugin({
  18. // 这里如果要复制多个文件夹,可以再patterns里面传入多个对象
  19. patterns: [
  20. {
  21. from: 'public',
  22. to: './',
  23. globOptions: {
  24. ignore: ['**/index.html'],
  25. },
  26. },
  27. ],
  28. }),
  29. ]
  30. }

glob 模式匹配简明教程:https://juejin.cn/post/6844904077801816077

Mode配置

  • Mode配置选项,可以告知webpack使用响应模式的内置优化:
    • 默认值是production(什么都不设置的情况下);
    • 可选值有:’none’ | ‘development’ | ‘production’;
  • 这几个选项有什么样的区别呢?

image.png
如果mode为 production,那么我们出现了报错是很难定位到源码的位置的:
image.pngimage.png

当mode设置为 development的时候,其实就可以看到出错的是element.js文件的第33行代码了。
image.png
不过我们设置development之后,bundler.js中的代码中还是可以看到大量的eval(),
可以设置devtool: 'source-map',生成sourcemap文件。·

image.png

Mode代表了更多的配置

这些配置是webpack根据我们设置的mode,来自动配置的:
image.png