【问题标题】:Angular AOT/Rollup with modules which have no default export (like immutable.js, moment.js)Angular AOT/Rollup 与没有默认导出的模块(如 immutable.js、moment.js)
【发布时间】:2017-07-05 04:02:12
【问题描述】:

我尝试调整我的 Angular 应用程序,以便为 AOT 编译和 Tree Shaking(汇总)做好准备。但是我在使用没有默认导出的模块(immutable.js、moment.js、...)时遇到了问题。根据 typscript(看 here),只能通过以下语句使用此类模块:import x = require('x')import * as x from 'x' 但是这两个语句在汇总期间都会导致问题。在某些情况下,我在汇总期间收到错误:Cannot call a namespace ('x'),在某些情况下,我收到运行时错误:x is undefined

在这里你可以找到我的 rollup-config.js 和 tsconfig-aot.json tsconfig-aot_rollup-config.zip

我需要一种在 AOT 编译和汇总期间使用 immutable.js、moment.js 等包的方法。有没有办法做到这一点?

谢谢!

【问题讨论】:

    标签: angular typescript momentjs immutable.js angular2-aot


    【解决方案1】:

    Rollup 仅适用于 es6。尝试在 tsconfig 中更改目标:

    "target": "es6"
    

    当汇总完成时,您可以使用 typescript 将包编译为 es5,并带有选项 allowJs: true。

    附言require 是一种 Webpack 方式,Rollup 使用 es6 导入语法。

    【讨论】:

    • 您的方法不起作用。我尝试以下操作: - tsconfig-aot.json:将目标更新为 ES6 - 运行编译:ngc -p tsconfig-aot.json - 成功完成 - 运行汇总:rollup -c rollup-config.js - 完成以下错误:? Cannot call a namespace ('moment') 在代码中我用这个语句导入时刻:import * as moment from "moment"; 有什么问题吗?谢谢!
    • ngc 不会编译你的打字稿。您应该更新的不是 tsconfig-aot.json,而是您的主要 tsconfig.json(或 tsconfig-prod.json,对于生产构建来说仍然是特殊的)。无论如何,请提供您编译的 js 文件。
    【解决方案2】:

    我发现在 rollup-config.js 中,在 ts 食谱中,他们确实将 rxjs 专门放在了 commonJs 包含中。 如果您从仅包含 rxjs 更改,它也将处理 3rd 方模块。

    比如我用的是angular2-materialize,所以:

    commonjs({
      include: [
        'node_modules/rxjs/**',
        'node_modules/angular2-materialize/**'
      ],
    

    或简单地包括所有(发现更好,测试 build.js,相同大小):

    commonjs({
      include: 'node_modules/**'
    })
    

    【讨论】:

    • 我已经尝试过了,但是对 moment.js 和 immutable.js 没有帮助
    • 请您在 AOT/Rollup 构建中提供一个 angular2-materialize 的工作示例 - 我真的在与此作斗争
    • @P.Moloney 幸运的是,我有一个为自己创建的入门项目..(自述文件适用于 vsCode)..自述文件对我来说有点它不是很详细......它主要用于 scss 编译器github.com/Blazzze/Angular2CustomQuickstart
    【解决方案3】:

    更新

    我之前的回答遇到了问题。这是我在 SystemJs 和使用 AoT/rollup 时得出的解决方案。

    我的导入语句如下:

    import * as moment from 'moment';
    const momentJs = (moment as any).default ? (moment as any).default : moment;
    

    然后,在您的代码中,像这样使用它:

    const startDateString = momentJs(startDate).format('YYYY-MM-DD');
    

    这是由于 SystemJs 和 Rollup 使用两种不同的方法来解析没有默认导出的导入模块。

    我有两个 TypeScript 配置文件,一个用于 systemJs,一个用于运行 AoT 构建。他们俩都在compilerOptions中设置了这个标志

    "allowSyntheticDefaultImports": true
    

    (上一个答案)

    我遇到了这个确切的问题。我能够让它与以下内容一起工作:

    var moment = require('moment'); //works
    

    相对

    import moment from "moment"; // won't work
    

    import moment = require('moment'); //won't work
    

    在我的汇总配置中,我还有:

    commonjs({
            include: [
                'node_modules/rxjs/**', 
                'node_modules/moment/**', 
                'node_modules/hammerjs/**'
            ]
        }),
    

    指出我正确方向的事情是this SO answer 提出了类似的问题。

    上述解决方案适用于 SystemJs 和 Angular 的 AoT/Rollup 流程。感觉有点 hack-ish,因为它不是导入模块的“典型”打字稿方式,但它让我解决了这个问题。

    【讨论】:

    • 它也对我有用(更新答案)。谢谢一百万!
    猜你喜欢
    • 2017-01-23
    • 2021-12-22
    • 2019-12-29
    • 1970-01-01
    • 2017-10-26
    • 2016-05-15
    • 2021-11-24
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多