Webpack DevServer&&Express 中间件

前言

webpack-dev-server 底层是 express + webpack-dev-middleware

express是基础。
webpack-dev-middleware是中间件,以监听模式启动 webpack,将编译后的文件输出到内存(使用fs-memory),沟通webpackHRM(热替换 Hot Module Replacement)API便于本地开发的实时更新。

以伪代码来看,大致上是这么一个过程。

const express = require('express');
const webpackDevMiddleware= require('webpack-dev-middleware');
const app = express();
const devServer = app.use( webpackDevMiddleware(config) )

看到这个过程,我们很自然的想到,我们是不是可以给express加上更多中间件,来升级整个Webpack DevServer的能力呢?

Webpack devServer提供了这个注册第三方中间件的入口。

注册中间件

官方文档:

webpack.docschina.org/configuration/dev-server/#devserversetupmiddlewares
www.expressjs.com.cn/guide/using-middleware.html

截止今天(2022.10.31),最新版本webpack-dev-server@4.11.1
官方还兼容2个老的接口。
devServer.onAfterSetupMiddleware
devServer.onBeforeSetupMiddleware
不过已经depreciated了。

推荐以后采用devServer.setupMiddlewares

看官方示例:

module.exports = {
  // ...
  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }

      devServer.app.get('/setup-middleware/some/path', (_, response) => {
        response.send('setup-middlewares option GET');
      });

      // 如果你想在所有其他中间件之前运行一个中间件或者当你从 `onBeforeSetupMiddleware` 配置项迁移时,
      // 可以使用 `unshift` 方法
      middlewares.unshift({
        name: 'first-in-array',
        // `path` 是可选的
        path: '/foo/path',
        middleware: (req, res) => {
          res.send('Foo!');
        },
      });

      // 如果你想在所有其他中间件之后运行一个中间件或者当你从 `onAfterSetupMiddleware` 配置项迁移时,
      // 可以使用 `push` 方法
      middlewares.push({
        name: 'hello-world-test-one',
        // `path` 是可选的
        path: '/foo/bar',
        middleware: (req, res) => {
          res.send('Foo Bar!');
        },
      });

      middlewares.push((req, res) => {
        res.send('Hello World!');
      });

      return middlewares;
    },
  },
};

上面这个示例,我们在配置文件中,为setupMiddlewares字段设置了一个function类型的值。
实际调用的是node_modules/webpack-dev-server/lib/Server.js 中 Server类下的成员函数 setupMiddlewares()
在这里插入图片描述
这个函数中,如果检测到传入的配置字段是function类型,就会把内部的middlewares数组和自身的server实例传进去。
返回值是新的middlewares数组。
所以我们在配置文件config.js中用到的签名是 setupMiddlewares: (middlewares, devServer) => {}
下一段就会middlewares.foreach,使用(this.app).use进行真正的注册。

setupMiddlewares支持几种方式注册中间件。

2.1 支持直接操作middlewares数组。

数组元素支持

  • (req,res)=>{} Function格式
  • {path:'', name:'', middleware:(req,res)=>{} } Object格式
const mymiddleware = require('path/to/mymiddleware');
setupMiddlewares: (middlewares, devServer) => { 
	//函数形式
    middlewares.push((req,res)=>{}); // push 最后注册
    middlewares.unshift((req,res)=>{}); // unshift最先注册
    return middlewares; // setupMiddlewares必须返回middlewares数组
}

setupMiddlewares: (middlewares, devServer) => { 
	//对象形式
    middlewares.push({path:'/api',middleware:mymiddleware }); // push 最后注册
    middlewares.unshift({path:'/api',middleware:mymiddleware }); // unshift最先注册
    return middlewares; // setupMiddlewares必须返回middlewares数组
}

2.2 直接操作app注册

const mymiddleware = (req,res)=>{};
setupMiddlewares: (middlewares, devServer) => { 
     // 操作express app注册
     const app = devServer.app;
     app.use(mymiddleware);
     // 或者直接写
     devServer.app.use(mymiddleware);
     // 操作app的形式也支持注册到path
     devServer.app.use('/api',mymiddleware);
     devServer.app.get('/api',mymiddleware);
     return middlewares; // setupMiddlewares必须返回middlewares数组
    }

需要注意的是,app.use( ‘somepath’, middleware )的方式,
和直接app.use(middleware ) 的区别在于,

首先,前者只会在路径匹配到 ‘somepath’ 的时候才执行后面的middleware。
而后者的path默认是 ‘/’ ,所以会对所有请求都依次应用middlewares数组。

其次,前者注册的path会成为baseUrl, 可以在middleware中 通过req.baseUrl获得。
举例, 访问 '/api/aa/bb’时。

const mymiddleware = (req,res)=>{
	console.log('baseUrl:', req.baseUrl); 
	console.log('path:', req.path); 
};
app.use('/api',mymiddleware);  // 会打印 baseUrl: /api,  path: /aa/bb
app.use(mymiddleware); // 会打印 baseUrl: /,  path: /api/aa/bb

Express middleware写法

上一节我们知道了,写出来一个middleware之后怎么注册。
这一节讲一下,怎么写一个express middleware。

https://www.expressjs.com.cn/4x/api.html#req

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值