扩展 HTMLElement:使用 webpack 时构造函数失败 [英] extending HTMLElement: Constructor fails when webpack was used

查看:32
本文介绍了扩展 HTMLElement:使用 webpack 时构造函数失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将以下 TypeScript 程序转译为 ES5:

I got the following TypeScript program transpiled to ES5:

文件 1:

class BaseElement extends HTMLElement {
    constructor() {
        super();
    }
}

文件 2:

import {BaseElement} from './BaseElement';

class MyElement extends BaseElement {
    constructor() {
        super();
    }
}

var el = new MyElement();

手动将所有内容放入文件中,代码运行良好并在浏览器中执行,HTMLElement 构建没有问题.但是,一旦我通过 webpack 打包,就会收到以下错误消息:

Putting everything manually within a file, the code works fine and executes in the browser, the HTMLElement is constructed without problems. However, as soon as I pack it via webpack, I get the following error message:

Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

没有webpack,构造如下JS代码:

Without webpack, the following JS code is constructed:

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var BaseElement = (function (_super) {
    __extends(BaseElement, _super);
    function BaseElement() {
        _super.call(this);
    }
    return BaseElement;
}(HTMLElement));
var MyElement = (function (_super) {
    __extends(MyElement, _super);
    function MyElement() {
        _super.call(this);
    }
    MyElement.prototype.createdCallback = function () {
        this.innerHTML = "lol";
    };
    return MyElement;
}(BaseElement));
var el = new MyElement();

使用webpack,构造如下代码:

Using webpack, the following code is constructed:

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }


/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";

/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    __webpack_require__(1);
    __webpack_require__(2);

/***/ },
/* 1 */
/***/ function(module, exports) {

    "use strict";
    var BaseElement = (function (_super) {
        __extends(BaseElement, _super);
        function BaseElement() {
            _super.call(this);
        }
        return BaseElement;
    }(HTMLElement));
    exports.BaseElement = BaseElement;


/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

    "use strict";
    var BaseElement_1 = __webpack_require__(1);
    var MyElement = (function (_super) {
        __extends(MyElement, _super);
        function MyElement() {
            _super.call(this);
        }
        MyElement.prototype.createdCallback = function () {
            this.innerHTML = "lol";
        };
        return MyElement;
    }(BaseElement_1.BaseElement));
    exports.MyElement = MyElement;
    // TODO: inject
    var p = new MyElement();
/***/ }
/******/ ]);

基本上,webpack 将任何模块放入一个函数中,并在它们之间维护一个导出变量,但是 HTMLElement 的构建失败了.没有 webpack(上面的代码),它工作正常.

Basically, webpack puts any module into a function and maintains an export variable between them, however the construction of HTMLElement fails. Without webpack (code above), it works fine.

有什么想法吗?

推荐答案

这是转译问题.如果您正在转译或使用 ES5,那么您需要为具有本机 Web 组件支持的浏览器捆绑本机垫片.(https://github.com/webcomponents/custom-elements/blob/master/src/native-shim.js)

It is transpiling issue. If you are transpiling or using ES5 then you need to bundle native-shim for browsers with native Web components support.(https://github.com/webcomponents/custom-elements/blob/master/src/native-shim.js)

ES5 样式的类不适用于本机自定义元素,因为 HTMLElement 构造函数使用 new.target 的值来查找当前调用的构造函数的自定义元素定义.new.target 仅在调用 new 时设置,并且仅通过 super() 调用传播.super() 在 ES5 中是不可模拟的.SuperClass.call(this)``的模式只在扩展其他ES5风格的类时有效,不会传播new.target`.

ES5-style classes don't work with native Custom Elements because the HTMLElement constructor uses the value of new.target to look up the custom element definition for the currently called constructor. new.target is only set when new is called and is only propagated via super() calls. super() is not emulatable in ES5. The pattern of SuperClass.call(this)`` only works when extending other ES5-style classes, and does not propagatenew.target`.

检查问题讨论 https://github.com/webcomponents/custom-elements/问题/29

这篇关于扩展 HTMLElement:使用 webpack 时构造函数失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆