happypack两次报错的问题

卢植
• 阅读 5589

happypack有点问题

happypack4.0.0@beta1版本以及以前的版本,并不能很好的兼容webpack2以上的版本。

这个问题并不大,但是目前来说比较影响观瞻。

这个问题实际反映在哪里呢?

当我使用webpack3的时候,经常发现happypack报两个重复的错误。

./static/client/js/tool/app.js
(Emitted value instead of an instance of Error)
/Users/lipenghui/works/qietv-mobile/static/client/js/tool/app.js
   6:5   warning  'downloadbtn' is never reassigned. Use 'const' instead  prefer-const
   8:5   warning  'url' is never reassigned. Use 'const' instead          prefer-const
  10:5   warning  'mask' is never reassigned. Use 'const' instead         prefer-const
  15:14  error    Missing semicolon                                       semi
  24:7   error    Missing semicolon                                       semi

✖ 5 problems (2 errors, 3 warnings)
  2 errors, 3 warnings potentially fixable with the `--fix` option.

NonErrorEmittedError: (Emitted value instead of an instance of Error)
/Users/lipenghui/works/qietv-mobile/static/client/js/tool/app.js
   6:5   warning  'downloadbtn' is never reassigned. Use 'const' instead  prefer-const
   8:5   warning  'url' is never reassigned. Use 'const' instead          prefer-const
  10:5   warning  'mask' is never reassigned. Use 'const' instead         prefer-const
  15:14  error    Missing semicolon                                       semi
  24:7   error    Missing semicolon                                       semi

✖ 5 problems (2 errors, 3 warnings)
  2 errors, 3 warnings potentially fixable with the `--fix` option.

    at Object.emitError (/Users/lipenghui/works/qietv-mobile/node_modules/webpack/lib/NormalModule.js:120:14)
    at Object.emitError (/Users/lipenghui/works/qietv-mobile/node_modules/happypack/lib/HappyRPCHandler.js:85:12)
    at HappyRPCHandler.execute (/Users/lipenghui/works/qietv-mobile/node_modules/happypack/lib/HappyRPCHandler.js:58:22)
    at ChildProcess.acceptMessageFromWorker (/Users/lipenghui/works/qietv-mobile/node_modules/happypack/lib/HappyThread.js:80:27)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at handleMessage (internal/child_process.js:753:14)
    at Pipe.channel.onread (internal/child_process.js:472:11)

从报错分析,我们的其中一个错误是经过Object.emitError时报出的NonErrorEmittedError: (Emitted value instead of an instance of Error)。 查阅webpack/lib/NormalModule.js的源代码可知,在webpack2及以上的版本中,emitError和emitWarning在接受到的消息不是一个错误的时候,会重新生成一条错误记录,扔进errorStack里。。。。

emitWarning: (warning) => {
    if(!(warning instanceof Error))
        warning = new NonErrorEmittedError(warning);
    this.warnings.push(new ModuleWarning(this, warning));
},
emitError: (error) => {
    if(!(error instanceof Error))
        error = new NonErrorEmittedError(error);
    this.errors.push(new ModuleError(this, error));
},

在现有loader的代码中,很多对LoaderContext版本进行了处理,或者干脆新版本里传过去的错误消息就是继承于Error,比如eslint-loader,源代码中有一句

// 注,该webpack为LoaderContext实例,非webpack实例
emitter(webpack.version === 2 ? new ESLintError(messages) : messages)

如果LoaderContext的版本是2,就扔出一个继承自Error的消息

// webpack/lib/NormalModule.js中创建loaderContext的方法
// version === 2
createLoaderContext(resolver, options, compilation, fs) {
        const loaderContext = {
            version: 2,
            emitWarning: (warning) => {
                if(!(warning instanceof Error))
                    warning = new NonErrorEmittedError(warning);
                this.warnings.push(new ModuleWarning(this, warning));
            },
            emitError: (error) => {
                if(!(error instanceof Error))
                    error = new NonErrorEmittedError(error);
                this.errors.push(new ModuleError(this, error));
            },
            exec: (code, filename) => {
                const module = new NativeModule(filename, this);
                module.paths = NativeModule._nodeModulePaths(this.context);
                module.filename = filename;
                module._compile(code, filename);
                return module.exports;
            },
                。。。

高潮来了。

happypack本身会建立一个假的loaderContext用以分线程处理任务,这个loaderContext的version是1。。。

unction HappyFakeLoaderContext(initialValues) {
  var loader = {};

  // for compiler RPCs, like this.resolve()
  loader._compiler = null;

  // for loader RPCs, like this.emitWarning()
  loader._remoteLoaderId = null;

  loader.version = 1; // https://webpack.github.io/docs/loaders.html#version
  loader.webpack = false;
  loader.request = null;
  loader.query = null;

  loader.context = null;
  loader.resource = null;
  loader.resourcePath = null;
  loader.resourceQuery = null

于是在接洽真正的loader并获得errorMessage抛给主进程的时候,我们的happypack就跪了,于是我们有了两个报错。。。

然后,就有人修复了是不是~

对,有人修复了并给作者push了一下。兼容方案如下

 HappyRPCHandler.prototype.execute = function(type, payload, done) {
    var compiler, loader;
  
     if (payload.message.happyPackIsError) {
         var oldMessage = payload.message;
         payload.message = new Error(oldMessage.message);
         delete payload.message.stack;
         for (var i in oldMessage) {
             if (i !== 'message' && i !== 'happyPackIsError') {
                 payload.message[i] = oldMessage[i];
             }
         }
     }

完全无视了version,这样也好。。也好,毕竟我们npm是可以指定模块版本的。。

然鹅。。在本篇文章发表12小时前。。。

happypack两次报错的问题

修复代码没有通过ci的构建,并没有解决该问题。。。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Stella981 Stella981
3年前
DevOps世界中的软件开发
!(https://oscimg.oschina.net/oscnet/f40e68cbfe8148deb00f040b4e917a0a.jpg)在整个软件开发过程中,开发人员通常需要花费大量时间来修复错误和漏洞,以便一切按计划进行交付。但是,通过DevOps实践,可以更轻松地管理和保护这些问题。这是由于以下事实:使用DevOps实践的软
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(