当前位置: 首页 > news >正文

happypack两次报错的问题

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小时前。。。

clipboard.png

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

相关文章:

  • 【yueyan科普系列】XSS跨站脚本攻击.rar
  • 如何阻止a链接的默认行为并获得href属性
  • 关于Oracle误操作--数据被Commit后的数据回退(闪回)
  • 阿里云配置ssl证书服务遇到的几个问题和解决方法
  • JSTL总结摘要
  • javascript 一些注意事项
  • XSS学习分支图
  • springCloud(10):使用Feign实现声明式REST调用-构造多参数请求
  • leetcode 228: Summary Ranges
  • Tomcat访问日志详细配置(转)
  • Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点
  • Windows下使用VNC连接CentOS7远程桌面
  • Linux CentOS 7 下 JDK 1.7 安装与配置
  • “业务为王”时代下,DevOps怎么玩?
  • Java中的Filter过滤器
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • Angularjs之国际化
  • crontab执行失败的多种原因
  • CSS 专业技巧
  • CSS实用技巧干货
  • Java IO学习笔记一
  • JS变量作用域
  • Objective-C 中关联引用的概念
  • spring + angular 实现导出excel
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 分类模型——Logistics Regression
  • 解析 Webpack中import、require、按需加载的执行过程
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 深入 Nginx 之配置篇
  • 手写双向链表LinkedList的几个常用功能
  • 一天一个设计模式之JS实现——适配器模式
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​secrets --- 生成管理密码的安全随机数​
  • # Apache SeaTunnel 究竟是什么?
  • #define用法
  • #include<初见C语言之指针(5)>
  • #Linux(make工具和makefile文件以及makefile语法)
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • $refs 、$nextTic、动态组件、name的使用
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (13):Silverlight 2 数据与通信之WebRequest
  • (4)Elastix图像配准:3D图像
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (五)关系数据库标准语言SQL
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .NET Micro Framework初体验
  • @ModelAttribute 注解
  • [@Controller]4 详解@ModelAttribute
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [C++]C++类基本语法
  • [C++]拼图游戏
  • [CLickhouse] 学习小计