# webpack 常用的配置

By [Murraya](https://paragraph.com/@murraya) · 2022-05-11

---

clean-webpack-plugin
--------------------

作用：打包之前清除output的文件夹，避免存在之前的打包结果；

    var path = require("path");
    var { CleanWebpackPlugin } = require("clean-webpack-plugin");
    
    module.exports = {
      //...
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "main[contenthash: 5].js"
      },
      plugin: [
        new CleanWebpackPlugin()
      ]
    }
    

Html-webpack-plugin
-------------------

作用：自动生成html文件

    var path = require("path");
    var { CleanWebpackPlugin } = require("clean-webpack-plugin");
    var HtmlWebpackPlugin = require("html-webpack-plugin");
    
    module.exports = function(env){
        return {
            output: {
                path: path.resolve(__dirname, 'dist'),
                filename: 'main[contenthash:5].js'
            },
            plugins: [
                new HtmlWebpackPlugin({
                    template: './public/index.html',
                    title: 'my app',
                    scriptLoading: 'blocking',
                    // chunks: 入口配置的key
                    filename: 'home.html'
                })
            ]
        }
    }
    

Copy-webpack-plugin
-------------------

复制静态资源，通常处理assets里的图片、pdf等资源的迁移

    var path = require("path");
    var CopyWebpackPlugin = require("copy-webpack-plugin");
    
    module.exports = function(env){
        return {
            output: {
                path: path.resolve(__dirname, 'dist'),
                filename: 'main[contenthash:5].js'
            },
            plugins: [
                new CopyWebpackPlugin({
                    patterns: [
                        { from: './public', to: './' }
                    ]
                })
            ]
        }
    }
    

开发服务器
-----

在**开发阶段**，目前遇到的问题是打包、运行、调试过程过于繁琐，回顾一下我们的操作流程：

1.  编写代码
    
2.  控制台运行命令完成打包
    
3.  打开页面查看效果
    
4.  继续编写代码，回到步骤2
    

并且，我们往往希望把最终生成的代码和页面部署到服务器上，来模拟真实环境

为了解决这些问题，webpack官方制作了一个单独的库：**webpack-dev-server**

它**既不是plugin也不是loader**

先来看看它怎么用

1.  安装
    
2.  执行`webpack-dev-server`命令
    

`webpack-dev-server`命令几乎支持所有的webpack命令参数，如`--config`、`-env`等等，你可以把它当作webpack命令使用

这个命令是专门为开发阶段服务的，真正部署的时候还是得使用webpack命令

当我们执行`webpack-dev-server`命令后，它做了以下操作：

1.  内部执行webpack命令，传递命令参数
    
2.  开启watch
    
3.  注册hooks：类似于plugin，webpack-dev-server会向webpack中注册一些钩子函数，主要功能如下：
    
    1.  将资源列表（aseets）保存起来
        
    2.  禁止webpack输出文件
        
4.  用express开启一个服务器，监听某个端口，当请求到达后，根据请求的路径，给予相应的资源内容
    

**配置**

针对webpack-dev-server的配置，参考：[https://www.webpackjs.com/configuration/dev-server/](https://www.webpackjs.com/configuration/dev-server/)

常见配置有：

*   port：配置监听端口
    
*   proxy：配置代理，常用于跨域访问
    
*   stats：配置控制台输出内容
    

普通文件处理
------

file-loader: 生成依赖的文件到输出目录，然后将模块文件设置为：导出一个路径\\

    //file-loader
    function loader(source){
        // source：文件内容（图片内容 buffer）
        // 1. 生成一个具有相同文件内容的文件到输出目录
        // 2. 返回一段代码   export default "文件名"
    }
    

url-loader：将依赖的文件转换为：导出一个base64格式的字符串

    //url-loader
    function loader(source){
        // source：文件内容（图片内容 buffer）
        // 1. 根据buffer生成一个base64编码
        // 2. 返回一段代码   export default "base64编码"
    }
    

解决路径问题
------

在使用file-loader或url-loader时，可能会遇到一个非常有趣的问题

比如，通过webpack打包的目录结构如下：

    dist
        |—— img
            |—— a.png  #file-loader生成的文件
        |—— scripts
            |—— main.js  #export default "img/a.png"
        |—— html
            |—— index.html #<script src="../scripts/main.js" ></script>
    

这种问题发生的根本原因：模块中的路径来自于某个loader或plugin，当产生路径时，loader或plugin只有相对于dist目录的路径，并不知道该路径将在哪个资源中使用，从而无法确定最终正确的路径

面对这种情况，需要依靠webpack的配置publicPath解决

注意⚠️：

*   publicPath配置，会生成一个简单的字符串，有些loader或者插件会使用这个字符串（例如：在生成路径的时候将这个字符串放到路径的最前面），一般会把这个配置位'/'
    
*   有些loader或者插件自己也会带有一个publicPath，用来做单独的配置；
    

内置插件
----

所有的webpack内置插件都作为webpack的静态属性存在的，使用下面的方式即可创建一个插件对象

    const webpack = require("webpack")
    
    new webpack.插件名(options)
    

DefinePlugin
------------

全局常量定义插件，使用该插件通常定义一些常量值，例如：

    new webpack.DefinePlugin({
        PI: `Math.PI`, // PI = Math.PI
        VERSION: `"1.0.0"`, // VERSION = "1.0.0"
        DOMAIN: JSON.stringify("duyi.com")
    })
    

这样一来，在源码中，我们可以直接使用插件中提供的常量，当webpack编译完成后，会自动替换为常量的值

BannerPlugin
------------

它可以为每个chunk生成的文件头部添加一行注释，一般用于添加作者、公司、版权等信息

    new webpack.BannerPlugin({
      banner: `
      hash:[hash]
      chunkhash:[chunkhash]
      name:[name]
      author:yuanjin
      corporation:duyi
      `
    })
    

ProvidePlugin
-------------

自动加载模块，而不必到处 import 或 require

    new webpack.ProvidePlugin({
      $: 'jquery',
      _: 'lodash'
    })
    

然后在我们任意源码中：

    $('#item'); // <= 起作用
    _.drop([1, 2, 3], 2); // <= 起作用

---

*Originally published on [Murraya](https://paragraph.com/@murraya/webpack-2)*
