Javascript的错误原因有时并不是直接导致错误的原因。因此收集一下这些开发中碰到的有些绕弯的错误。
-
TypeError: Something is not a constructor
TypeError: Something is not a constructor
at Object.<anonymous> (file:///main.js:179:12)
at Generator.next (<anonymous>)这个错误可能常见到MDN甚至有专门一个文档讲这个错误。然而这份文档中没有提到的是,如果你以
import aclass from 'a.js'
引用了另一个js文件,而这个文件没有默认导出,也会得到同样的错误。编写于2020年4月25日
-
TypeError: Super expression must either be null or a function, not undefined
在补引擎大坑的时候碰到了这个bug......特别巧的是,第二个错误也是一个TypeError。但是与第一个不同,它是在使用parcel.js时有可能被抛出的。堆栈跟踪:
Uncaught TypeError: Super expression must either be null or a function at _inherits (src.f69400ca.js:441) at src.f69400ca.js:501 at Object.parcelRequire.Engine/Resource/BlobBasedHeavyResource.ts../ResourceControl (src.f69400ca.js:593) at newRequire (src.f69400ca.js:47) at localRequire (src.f69400ca.js:53) at Object.parcelRequire.Engine/Resource/Image.ts../BlobBasedHeavyResource (src.f69400ca.js:621) at newRequire (src.f69400ca.js:47) at localRequire (src.f69400ca.js:53) at Object.parcelRequire.Engine/Resource/ResourceControl.ts.../Exception/ResIdNotFoundException (src.f69400ca.js:1269) at newRequire (src.f69400ca.js:47)
堆栈跟踪最后帮助我们定位到了这段代码:function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
观察可知,错误是亲类(或者说,父类)没有在子类之前加载导致的。道理很简单,但是该怎么解决呢?parcel的repo上也有个老哥碰到了应该是一样的问题(issue),结果开发者好像根本没理他,issue直接给Github Action关掉了......
那就只能自己解决问题了。
先来分析一下原因是什么。因为parcel会把所有的Javascript打包到一个bundle里,每个类又会转换成
var <className>=...
的格式,所以变量声明的顺序导致子类可能在父类前加载。先是考虑了下代码分割这一个解决方案,毕竟目标环境Chrome还是支持esmodule的(一応.....),但是parcel的代码分割要求用
import()
,动态加载又会导致很多问题,然后出问题的类又不适合动态加载,那就算了吧。那么有没有可能改变变量声明顺序呢?当然,手动移动是可以解决的,但我们要的是自动化的解决方案,要不也没有用parcel的必要了是吧。然后看了下亲类(A字开头)是在R开头的ts里声明的,子类是在B开头的ts里声明的,如果更改文件名字的话或许可以吧。就这样抱着试一试的想法把某A字亲类独立成一个文件,毕竟A是字母表打头的,这还不能第一个加载的话就没辙了。
然后就解决了,啊这...原来还想发个issue,想想算了。并且项目又有了新的bug,暂时还不知道是怎么回事就不讲了。
parcel虽然集成度高所以用起来特别方便,但是细致的需求可能还是webpack舒服些。但是webpack的入门门槛属实劝退(相比于parcel的开箱即用)就像Wordpress的编辑器和VSCode写文章的区别一样。Wordpress虽然通过高集成帮你免去写一般博文要学HTML或者要写HTML的烦恼,但是一旦有更复杂的应用就还是得回归HTML。集成与可拓展性的矛盾是一直存在呢。
编写于2020年5月1日,距离bcr n3还有三个小时
Comments 1 条评论
博主 雪
就就就就是说啊