使用Rollup for Angular 2的AoT编译器并导入Moment.js

时间:2016-09-15 20:28:52

标签: angular typescript momentjs rollupjs angular2-aot

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

import * as moment from 'moment';

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

  

无法调用命名空间('时刻')

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

import moment from 'moment'

我收到编译错误

  

外部模块'''''没有默认导出

8 个答案:

答案 0 :(得分:20)

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

  

无法调用命名空间('时刻')

您需要使用:

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()
]

答案 1 :(得分:7)

以下是我用打字稿(2.1.6)和汇总(0.41.4)来完成工作的时间。

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

    import * as moment from 'moment';

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

    1. 在打字稿中使用时刻与任意时刻一样,并调用default函数:

      var momentFunc = (moment as any).default ? (moment as any).default : moment;
      var newFormat = momentFunc(value).format( format );
      
    2. moment(value).format(format)会在汇总树震动时导致错误:Cannot call a namespace ('moment')

答案 2 :(得分:4)

我们在ng-packagr中遇到了类似的问题,该问题使用汇总来生成可以在npm repo中发布的模块。 我们的项目是使用@ angular-cli(使用webpack)构建的。

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

public static BufferedReader createInputStream (Socket socket) throws IOException {

    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    return br;
}

public static PrintWriter createOutputStream (Socket socket) throws IOException {

    PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);

    return pw;
}   

工作正常,用作:

 import * as dataUrl from 'dataurl';

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

 dataUrl.parse(url)

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

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

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

版本:     ng-packagr:1.4.1     汇总:0.50.0     打字稿:2.3.5     @ angular / cli:1.4.8     webpack:3.7.1

希望得到这个帮助,

罗布

答案 3 :(得分:3)

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

import * as moment from 'moment'; - 在通过systemjs开发和加载时工作,但在汇总时没有。

import moment from '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);
}

要在其他课程中使用片刻,我只需导入该函数并将其调用,就像我直接导入片刻一样:

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添加到页面某处,因为它不幸地不会包含在汇总构建文件中。

答案 4 :(得分:0)

自版本2.13.0起,

import * as moment from 'moment';

答案 5 :(得分:0)

经过this threadwindow()应该有效。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

在我的Angular 5(5.2.9)项目(从Ng2升级)中,使用Gulp和Rollup(0.58.0)创建产品时,momentJs(2.24)的使用也存在相同的问题。

就像前面在这里提到的人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';与汇总工具一起使用的原因

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

和ES6模块导入。

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

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