CoffeeScript创建自定义Web组件在Rails4环境下报错如何解决?
问题原因
你使用的coffee-rails 4.1.1依赖CoffeeScript 1.x版本,该版本的类继承逻辑基于ES3原型链实现,转译后的代码不符合原生自定义Web组件的规范,是触发报错的核心原因:
- 原生
HTMLElement是DOM内置构造函数,禁止通过apply()/call()的方式调用,必须使用new关键字触发构造,这是你前两次报错的直接原因 - 原生自定义元素要求类定义符合ES6类规范,CoffeeScript 1.x转译出的ES3风格构造函数无法被浏览器识别为合法的自定义元素类
- 直接调用
new HTMLElement()不符合规范,HTMLElement只能作为父类被继承,不能单独实例化,所以会触发非法构造函数的报错
解决方案
方案1:升级CoffeeScript到2.x版本(推荐)
CoffeeScript 2.0及以上版本默认会将class语法转译为原生ES6类,完全符合自定义元素的要求:
- 修改Gemfile中的
coffee-rails版本到5.0及以上,该版本默认依赖CoffeeScript 2.x - 执行
bundle update coffee-rails更新依赖 - 原有CoffeeScript代码无需修改,重新编译后即可正常运行
方案2:直接用ES6语法编写自定义元素
如果不想调整CoffeeScript依赖,可以单独用ES6编写自定义元素逻辑:
- 在Gemfile中添加
gem 'sprockets-es6',执行bundle install开启ES6编译支持 - 将自定义元素相关代码单独存放为后缀为
.js.es6的文件,直接使用原生ES6类语法编写:
class ThingDoer extends HTMLElement { constructor() { super(); } } customElements.define("thing-doer", ThingDoer);
方案3:兼容旧版本CoffeeScript的临时方案
如果必须维持当前依赖版本,可以修改构造函数逻辑,手动调用Reflect.construct实现符合规范的构造流程:
class ThingDoer extends HTMLElement constructor: -> return Reflect.construct(HTMLElement, [], @constructor) customElements.define("thing-doer", ThingDoer)
内容的提问来源于stack exchange,提问作者Fred Willmore
相关产品推荐
相关产品推荐

