【问题标题】:Using Rollup for Angular 2's AoT compiler and importing Moment.js使用 Rollup for Angular 2 的 AoT 编译器并导入 Moment.js
【发布时间】:2017-01-23 23:51:45
【问题描述】:

我正在尝试关注 Angular 2 的 official AoT guide,并且我在我的应用程序中使用 Moment.js。 Moment.js 在我的 packages.json 文件中,我使用的是 2.15.0 版本。到目前为止,我一直是这样导入它的:

import * as moment from 'moment';

但是当我到达我必须运行汇总的部分时,我最终会遇到以下错误:

不能调用命名空间('moment')

这似乎与我根据this 导入时刻的方式有关。那么,我该怎么做呢? 我似乎无法以任何其他方式导入时刻。如果我使用

import moment from 'moment'

我得到编译错误

外部模块“moment”没有默认导出

【问题讨论】:

  • 你能解决这个问题吗?
  • +1 与import * as HighchartsMore from "highcharts/highcharts-more"; HighChartsMore(Highcharts)有同样的问题
  • 我也遇到了同样的错误。 1 个月后你那边有什么进展吗?
  • 我在加载时刻也遇到了问题。看看这个答案,也许它可以帮助:stackoverflow.com/a/35350484/1354222

标签: angular typescript momentjs rollupjs angular2-aot


【解决方案1】:

我终于设法摆脱了这两个错误。确实要避免:

不能调用命名空间('moment')

你需要使用:

import moment from 'moment'

然后避免

“时刻”没有默认导出

你必须添加到你的 tsconfig.json (compilerOptions):

"allowSyntheticDefaultImports": true

2016 年 11 月 17 日编辑

我还必须将以下内容添加到我的 rollup-config.js 文件中:

plugins: [
  nodeResolve({jsnext: true, module: true}),
  commonjs({
    include: [
        'node_modules/rxjs/**',
        'node_modules/moment/**'
      ]
    }
  }),
  uglify()
]

【讨论】:

  • 这适用于 AoT 汇总配置,但不适用于在调试/开发构建模式下使用 systemjs。
  • @MarkPerry 是的,我仍在尝试使用 SystemJS 和 Webpack。但是这个线程是关于汇总的。如果我找到 SystemJS 的东西,我会告诉你的。
  • 将此标记为已接受的答案,因为它修复了 AoT,但我确实需要一个无需修改即可同时适用于 AoT 和 JIT 的解决方案...
  • 它不起作用:import moment from 'moment' 将给出错误 moment_1.default is not a function at runtime with typescript 2.1.6。
  • 对于 AoT,我最终得到了两个不同的汇总配置文件;一个用于 JIT,另一个用于 AoT。我也不使用 SystemJS,它对我来说很好。
【解决方案2】:

我为手头的问题找到了一个很好的解决方案:

Npm-install 附加包moment-es6 提供默认导出。 然后从 'moment-es6' 导入,而不是从 'moment' 导入:

import moment from 'moment-es6';

  • 要与 systemjs 一起使用,请将以下内容添加到 systemjs.config.js 映射部分:
    'moment-es6': 'npm:moment-es6/index.js'

  • 'node_modules/moment-es6/**' 添加到汇总配置 commonjs 部分 (rollup-plugin-commonjs) 的 include

【讨论】:

  • 有趣,这适用于系统 js 和打字稿(没有额外的编译器标志),但汇总给我一个错误:? 'default' is not exported by node_modules\moment-es6\index.js
  • 我想我只需要指定named export - 对吧?
【解决方案3】:

这是我为使用 typescript(2.1.6 版本)和 rollup(0.41.4)制作工作时刻所做的。

  1. 导入时刻,保持标准方式:

    import * as moment from 'moment';

import moment from 'moment'; 对于没有默认导出的包来说是非标准的,它会在运行时导致错误:moment_1.default is not a function

  1. 在 typescript 中通过将 moment 转换为 any 来使用 moment,并调用 default 函数:

    var momentFunc = (moment as any).default ? (moment as any).default : moment;
    var newFormat = momentFunc(value).format( format );
    

moment(value).format(format) 将在汇总树摇动时导致错误:Cannot call a namespace ('moment')

【讨论】:

  • 谢谢!这对我有用。 import * as momentLib from "moment";const moment = (momentLib as any).default ? (momentLib as any).default : momentLib;
【解决方案4】:

ng-packagr 也有类似的问题,它使用 rollup 生成可以在 npm 存储库中发布的模块。 我们的项目是使用 @angular-cli(使用 webpack)构建的。

我们有 2 个使用 asteriks 方法导入的依赖项:

 import * as dataUrl from 'dataurl';

工作正常,使用如下:

 dataUrl.parse(url)

另一个导入出现错误(无法调用命名空间),因为导出的对象将用作函数:

 import * as svgPanZoom from 'svg-pan-zoom';
 svgPanZoom(element); <== error: Cannot call a namespace

我们可以通过将导出的初始化函数分配给另一个 const 并在代码中使用它来解决这个问题:

 import * as svgPanZoomImport from 'svg-pan-zoom';
 const svgPanZoom = svgPanZoomImport;

 svgPanZoom(element);

我们还如上所述对 tsconfig.json 配置进行了更改。

版本: ng-packagr:1.4.1 汇总:0.50.0 打字稿:2.3.5 @角/cli:1.4.8 网络包:3.7.1

希望对您有所帮助,

罗伯

【讨论】:

  • 即使没有 tsconfig.json 更改,别名也很神奇。谢谢!
【解决方案5】:

我遇到了与上述相同的问题。

import * as moment from 'moment'; - 在通过 systemjs 开发和加载时有效,但在汇总期间无效。

import moment from 'moment'; - 在汇总构建中工作,但在开发期间没有工作。

为了避免必须根据构建类型更改代码,我只是将 moment 作为全局添加并创建了一个辅助函数,我可以在需要使用它的任何地方导入它,而不是导入 moment。

这意味着相同的代码适用于两种场景。虽然不是特别漂亮,如果有更好的方法请告诉我/我们!

这是辅助函数,添加到它自己的文件momentLoader.ts

import { default as mom } from 'moment';
export default function moment(args?: any): mom.Moment {
    let m = window["moment"];
    if (!m) { 
        console.error("moment does not exist globally.");
        return undefined;
    }
    return m(args);
}

要在其他类中使用 moment,我只需导入函数并像直接导入 moment 一样调用它:

import moment from '../../momentLoader';

let d = moment().utc("1995-12-25");

let m = moment("1995-12-25");

要让 systemjs 将其作为全局加载,我只是按照这些步骤操作。 http://momentjs.com/docs/#/use-it/system-js/

就我而言,systemjs 的时刻配置如下所示:

let meta = {
    'lib:moment/moment.js': { format: 'global' }
};

System.config({
    paths: paths,
    map: map,
    packages: packages,
    meta: meta
});

System.import('lib:moment/moment.js');

对于汇总构建,您必须确保通过脚本标记将 moment.js 添加到页面的某个位置,因为不幸的是它不会包含在汇总构建文件中。

【讨论】:

  • 我和你有同样的问题,我真的不明白为什么每个人都没有抱怨这个......创建一个额外的加载功能是一个荒谬的要求,特别是当我们已经使用了大量的不同的装载机!
  • 刚刚浪费了整个晚上试图汇总我的网站,直到现在我才解决了这个问题,感谢您的宝贵帖子。我对 lodash 做了同样的事情: // lodash-loader.ts import { default as lodash } from "lodash";将默认窗口[""] 导出为 _lodash.LoDashStatic;
  • 好主意,但我发现必须使用它是完全不可接受的。看在上帝的份上,我只想使用一个外部库。 *叹息,像这样的时刻(不是双关语)让我后悔使用 Angular 2...
  • 完全同意这不是理想的和绝对的 PI​​TA。只是需要一些东西让我继续工作,直到有更好的选择。它仍然是“相当”新的,所以我相信这最终会得到排序......无论如何希望:)。
【解决方案6】:

通过this threadimport moment from 'moment'; 应该可以工作。

【讨论】:

  • 这对我来说效果很好,我唯一需要添加的是 tsconfig.json 下的 compilerOptions "allowSyntheticDefaultImports": true
【解决方案7】:

从 2.13.0 版开始,

import * as moment from 'moment';

【讨论】:

  • 这使得 Module [...] 没有导出的成员 'default'。
【解决方案8】:

我尝试了上述所有解决方案,但没有一个对我有用。有效的是

import moment from 'moment-with-locales-es6';

【讨论】:

    【解决方案9】:

    在我的 Angular 5 (5.2.9) 项目(从 Ng2 升级)中使用 Gulp 和 Rollup (0.58.0) 构建产品时遇到了同样的问题。

    正如前面提到的import * as moment from 'moment'; 仅适用于在包列表中引用 momentJs 的开发(通过 SystemJS):

    {
      name: 'moment',
      path: 'node_modules/moment/min/moment.min.js'
    }
    

    其他情况是汇总使用(生产构建)-momentJs 将其代码作为 ES6 模块(在 moment/src 中),但它以不同的方式导出(然后是通常的导出)。 这就是import moment from 'moment'; 与 Rollup 合作的原因

    include: [
      'node_modules/rxjs/**',
    ]
    

    和 ES6 模块导入。

    是的,使用 ES6 包装器(例如moment-es6 左右)是简单的解决方案。但它总是需要momentJs。 同时对于这个问题还有一个更简单的解决方案 - 将您的导入行从 Dev 替换为 Prod。 例如,Gulp 可以在某个步骤使用gulp-replace

    return gulp.src([
         ...
        ])
        .pipe(replace('import * as moment from \'moment\';', 'import moment from \'moment\';'))
         ...;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2017-01-13
      • 2017-01-10
      • 2018-02-14
      • 2017-08-20
      相关资源
      最近更新 更多