rollup/rollup-plugin-typescript

moment conflict

tamascsaba opened this issue ยท 9 comments

When I use moment with rollup-plugin-typescript, throw an error:

import * as moment from "moment";
moment();
bundle dev started ...
Error: Cannot call a namespace ('moment')

I finded a workaround, but is is not compatible with my editor, underline with red line
https://forum.ionicframework.com/t/error-from-rollup-when-importing-moment-js-with-rc0/64902

import  moment from "moment";

moment

Module moment has no default export.

My current workaround is using a custom replace plugin like so :

plugins: [
  {
    name: 'replace moment imports',
    transform: code =>
      ({
        code: code.replace(/import\s*\*\s*as\s*moment/g, 'import moment'),
        map: { mappings: '' }
      })
  },
  typescript()
]

@tamascsaba That is because the namespace import form, import * as namespace does not import the call signatures of the target.
If the following works at runtime, but gives you language service errors, such as in an IDE,

import  moment from "moment";

Then add "allowSyntheticDefaultImports": true to your tsconfig.json "compilerOptions"

@ghetolay 's rollup plugin worked for me to resolve the issues I was getting.

@aluanhaddad

import moment from "moment";

solves the issue but it breaks SystemJS which results in the following message:

moment_1.default is not a function

Do you know how to configure SystemJS to work with this kind of import?

Yes but which reversion of SystemJS are you running? it should be working by default no pun intended. Mapping module.exports onto exports.default is the standard SystemJS behavior aligning with the ES Module spec and the Node.js plans for adopting a subset of it. I'm curious what your workflow is using SystemJS with rollup-plugin-typescript.

SystemJS.config({
  packages: {
    "npm:moment": {
      format: "cjs"
    }
   }
  } 
});

For those interested, TypeScript now provides the default synthesis, similar to Babel, not just the interop awareness that is enabled by --allowSyntheticDefaultImports, but the generation of interop code for legacy module formats.

It is behind a new flag --esModuleInterop and is available in typescript@next.

Yogu commented

That is because the namespace import form, import * as namespace does not import the call signatures of the target.

Why is this workaround working, then? Seems like a bug in rollup. TypeScript allows to merge function declarations with namespaces, and webpack/ts-node don't have a problem with this. I don't like enabling --allowSyntheticDefaultImports just to be able to use these modules with rollup.

It feels like having to change the codebase which would then break validation in order to accommodate post-processing is a bit of a let-down. Perhaps this can be reconsidered and @ghetolay's workaround could perhaps be added as part of this plugin? -If that's possible at all
As of now, I believe that's the only solution that looks clean enough and doesn't interfere with the development process to something other than what you would expect when compiling typescript.