LingYanSi / blog

博客
https://github.com/LingYanSi/blog/issues
9 stars 0 forks source link

webpack-dev-middleware wait until bundle finished bug fix/问题修复 #114

Open LingYanSi opened 5 years ago

LingYanSi commented 5 years ago

相关标签: webpack-dev-middleware/webpack/tapable

问题

98% after emitting WebpackDevMiddlewareℹ 「wdm」: wait until bundle finished: /webApp/dist/manifest.f8954906d.js ℹ 「wdm」: wait until bundle finished: /webApp/dist/vendor.530ff861e.js ℹ 「wdm」: wait until bundle finished: /webApp/dist/main.b0b9dd087.js ℹ 「wdm」: wait until bundle finished: /webApp/dist/manifest.f8954906d.js ℹ 「wdm」: wait until bundle finished: /webApp/dist/vendor.530ff861e.js ℹ 「wdm」: wait until bundle finished: /webApp/dist/main.b0b9dd087.js

文件 webpack-dev-middleware/lib/util.js

function ready(context, fn, req) {
  if (context.state) {
    return fn(context.webpackStats);
  }

  context.log.info(`wait until bundle finished: ${req.url || fn.name}`);
  context.callbacks.push(fn);
}

webpack-dev-middleware image image 看起来就是webpack-dev-middleware监听webpack complier.hooks.done的事件没有被执行 为什么呢? 中间log来log去也不明所以然,complier.hooks.done.taps下的数组里是有WDM注册的事件的,也就是说极大概率是因为webpack的某些执行策略导致事件队列没有被完全执行

看看webpack的代码

webapck执行接受两个参数webpack(option, callback)如果存在callback,会执行complier.run complier.run方法内会调用complier.hooks.done.callAsync,哎哟,这不就是我想要找的吗?并不是,因为看看devServer内的代码,调用webpack的使用并没有传递callback。又想到wait until bundle finished总是是因为文件改变才导致输出的。于是继续搜索,发现Watching文件内也有complier.hooks.done.callAsync的调用,好像离真相又近了异步

complier.hooks.done是tapable包内一个class的实例 image

tapable 看起来这个库用很复杂的操作再做很简单的业务逻辑 image

hooks.done.callAsync执行的方法是一下代码new Fnnction 打印一下的function,大概意思就是: 函数按队列执行,如果有一个出错了就不往下执行

[fn1, fn2, fn3, fn4].some(fn => { 
       try { fn1() } catch(err) { callback(err); return true}
})

那应该是哪个监听回调执行失败了,正好hooks.done.callAsync(stat, callback)的第二个参数就可以接受错误参数,打印一下。

我擦,是express报的一个错误:大概说的是如果一个请求res.send()已经被send,就不能再设置响应头。 那大概是因为响应函数被重复执行了,用一个高阶函数包装一下,保证函数只被执行一次

run一下,bug修复了

总结