Подтвердить что ты не робот

Использование Rollup для Angular 2 компилятора AoT и импорта Moment.js

Я пытаюсь следовать официальному руководству AoT для Angular 2, и я использую Moment.js в своем приложении. Moment.js находится в моем файле packages.json, и я использую версию 2.15.0. Я импортировал его так:

import * as moment from 'moment';

Но когда я добираюсь до той части, где мне нужно запустить rollup, я получаю следующую ошибку:

Невозможно вызвать пространство имен ( "момент" )

Как представляется, это связано с тем, как я импортирую момент в соответствии с этим. Итак, как я должен это делать? Кажется, я не могу импортировать момент другим способом. Если я использую

import moment from 'moment'

Я получаю ошибку компиляции

Внешний модуль '' moment '' не имеет экспорта по умолчанию

4b9b3361

Ответ 1

Мне наконец удалось избавиться от обеих ошибок. Чтобы избежать:

Невозможно вызвать пространство имен ( "момент" )

Вам нужно использовать:

import moment from 'moment'

Тогда, чтобы избежать

"момент" не имеет экспорта по умолчанию

Вы должны добавить в свой tsconfig.json(compilerOptions):

"allowSyntheticDefaultImports": true

РЕДАКТИРОВАТЬ 17/11/2016

Мне также пришлось добавить в файл rollup-config.js следующее:

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

Ответ 2

Я нашел хорошее решение проблемы:

Npm-install дополнительный пакет moment-es6, который предоставляет экспорт по умолчанию. Затем импортируйте из "момента-es6" вместо "момента":

import moment from 'moment-es6';

  • Для использования с systemjs добавьте следующее в раздел systemjs.config.js:
    'moment-es6': 'npm:moment-es6/index.js'

  • добавьте 'node_modules/moment-es6/**' в include вашего сводного конфигурационного раздела commonjs (rollup-plugin-commonjs)

Ответ 3

Вот что я сделал, чтобы сделать рабочий момент с typescript (на 2.1.6) и свернуть (0.41.4).

  • Чтобы импортировать момент, сохраните стандартный способ:

    import * as moment from 'moment';

import moment from 'moment'; является нестандартным для пакета без экспорта по умолчанию, это приведет к ошибке во время выполнения: moment_1.default is not a function

  1. В typescript используйте момент с помощью момента каста как любой и вызовите функцию 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')

Ответ 4

У меня были те же проблемы, которые были описаны выше.

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");

Чтобы система загружала ее как глобальную, я просто выполнил следующие шаги. http://momentjs.com/docs/#/use-it/system-js/

В моем случае момент config для 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');

Для сборки накопителя вам нужно будет убедиться, что момент .js добавлен на страницу где-то через тег script, так как он не будет включен в файл сборки накопительного файла к сожалению.

Ответ 5

У нас была аналогичная проблема с 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

Мы могли бы обойти это, назначив экспортированную функцию инициализации другому константе и используем ее в коде:

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

 svgPanZoom(element);

Мы также изменили конфигурацию tsconfig.json, как описано выше.

Версия:   ng-packagr: 1.4.1   свертывание: 0.50.0    typescript: 2.3.5   @angular/cli: 1.4.8   webpack: 3.7.1

Надеюсь на эту помощь,

Rob

Ответ 6

Начиная с версии 2.13.0,

import * as moment from 'moment';

Ответ 7

Переход этот поток, import moment from 'moment'; должен работать.

Ответ 8

Я попробовал все решения выше, но никто не работал у меня. Что работало

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

Ответ 9

У меня была такая же проблема с использованием momentJs (2.24) в моем проекте Angular 5 (5.2.9) (обновленном с Ng2) с Gulp и Rollup (0.58.0) для сборки prod.

Как уже упоминалось ранее, парни import * as moment from 'moment'; работает только для разработки (через SystemJS) со ссылкой на momentJs в списке пакетов:

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

Другой случай - использование объединения (производственная сборка) - моментальные коды имеют код ES6 (в момент /src), но экспортируются другим способом (тогда обычный экспорт). Вот почему import moment from 'moment'; работает с Rollup's

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\';'))
     ...;