【问题标题】:How to add a custom polyfill to an angular-cli project?如何将自定义 polyfill 添加到 angular-cli 项目?
【发布时间】:2017-03-31 19:49:08
【问题描述】:

我需要能够轻松地对集合进行排序,并且我选择了扩展 Array 原语。我意识到在大多数情况下这被认为是不好的做法,但这只会在内部使用(而不是共享库)。无论我尝试过哪种方法,即使它按预期工作in the playground,我也没有得到有效的结果。

我尝试在 /src/polyfills.ts 中添加 polyfill 内联,但是当我调用 $sortBy 方法时,控制台中出现“TypeError: Attempted to assign to readonly property”。 .

declare global {
  interface Array<T> {
    $sortBy(sortKey:string): T[];
  }
}

if (!Array.prototype['$sortBy']) {

  Object.defineProperty(Array.prototype, '$sortBy', {
    value: function(sortKey) {
      return this.sort( function(a, b) { // TypeError here???
        if (a[sortKey] < b[sortKey]) { return -1; }
        if (a[sortKey] > b[sortKey]) { return 1; }
        return 0;
      });
    }
  })

}

我还尝试通过 npm 添加纯 JavaScript 版本并导入,但这给了我相同的类型错误。有什么秘诀???

/node_modules/my-polyfills/sortBy.js

if (!Array.prototype.$sortBy) {
  Object.defineProperties(Array.prototype, {
    '$sortBy': {
      value: function (sortKey) {
        return this.sort(function (a, b) {
          if (a[sortKey] < b[sortKey]) {
            return -1;
          }
          if (a[sortKey] > b[sortKey]) {
            return 1;
          }
          return 0;
        });
      }
    }
  });
}

.angular-cli.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": { ... },
  "apps": [
    {
      ...,
      "scripts": [
        "../node_modules/my-polyfills/sortBy.js",
        "../node_modules/moment/moment.js"
      ],
      ...
    }
  ],
  ...
}

【问题讨论】:

  • 谢谢@AhmedMusallam!这解决了我的智能感知错误。我已经更新了我的示例以包含declare global。但是,类型错误仍然存​​在:(
  • 您是否在使用 both /node_modules/my-polyfills/sortBy.js 文件而我假设的第一个文件是 TS?当您尝试将不可写属性分配给某物时,会发生此错误TypeError: Attempted to assign to readonly property。在这种情况下,如果您定义 Arrays.prototype.$sortBy THEN 您尝试通过将其分配给新函数来修改 $sortBy,您将收到该错误。我问是因为当我在浏览器中尝试你的代码时,第一个 sn-p,它工作得很好。

标签: angular typescript angular-cli polyfills


【解决方案1】:

我在 Angular cli 1.0.0 上有一个生成的应用程序。虽然我认为您的问题与版本无关,但我已在下面获取您的代码并将其附加到 src/polyfills.ts 它按预期工作:

declare global {
  interface Array<T> {
    $sortBy(sortKey:string): T[];
  }
}

if (!Array.prototype['$sortBy']) {

  Object.defineProperty(Array.prototype, '$sortBy', {
    value: function(sortKey) {
      return this.sort( function(a, b) { // TypeError here???
        if (a[sortKey] < b[sortKey]) { return -1; }
        if (a[sortKey] > b[sortKey]) { return 1; }
        return 0;
      });
    }
  })
}

在我添加的一个组件中:

var a = [1,2,3];
var b = a.$sortBy('');
console.log(b)

我在控制台中没有看到错误,数组a 打印得很好。

我认为您遇到的问题是因为您在 src/polyfills.ts 中有上面的代码 并且 您在 /node_modules/my-polyfills/sortBy.js 中包含了相同的 polyfill 并将其添加到您的 scripts 部分.angular-cli

您应该添加一个或,而不是两者。我推荐前者,但在它自己的文件中,而不是附加到polyfills.ts

当您尝试将不可写属性分配给其他内容时,会发生此错误TypeError: Attempted to assign to readonly property。通过使用Object.defineProperty,您使$sortBy 不可写。您定义了 Arrays.prototype.$sortBy 然后您尝试通过将 $sortBy 分配给新函数来修改它,因此您会收到错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多