Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with Angular 8 - 'allowSyntheticDefaultImports' flag #67

Closed
MiselKING opened this issue Aug 13, 2019 · 17 comments
Closed

Error with Angular 8 - 'allowSyntheticDefaultImports' flag #67

MiselKING opened this issue Aug 13, 2019 · 17 comments
Labels
question Further information is requested

Comments

@MiselKING
Copy link

MiselKING commented Aug 13, 2019

I just updated from vis to vis-network (I only need vis-network since I only use graph in my app) while updating to Angular 8. When I try and compile the app, I get an error:

This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

in ../node_modules/vis-network/dist/types/index.d.ts:18:25.
Complete error:

ERROR in ../node_modules/vis-network/dist/types/index.d.ts:18:25 - error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

18 import * as moment from './module/moment';

../node_modules/vis-network/dist/types/module/moment.d.ts:1:8 - error TS1259: Module '"%LOCATION%/angular/node_modules/moment/moment"' can only be default-imported using the 'allowSyntheticDefaultImports' flag

1 import moment from 'moment'

../node_modules/moment/moment.d.ts:736:1
736 export = moment;

This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.

vis-network version: 5.2.1
Browser: Chrome 76.0.3809.100, Windows 10

My tsconfig.json:

"downlevelIteration": true,
"outDir": "./dist/out-tsc",
"baseUrl": "src",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2015",
"typeRoots": [
    "node_modules/@types"
],
"lib": [
    "es2016",
    "dom"
],
"paths": {
    "core-js/es7/reflect": ["../node_modules/core-js/proposals/reflect-metadata"],
    "core-js/es6/*": ["../node_modules/core-js/es/*"],
    "core-js/es7/*": ["../node_modules/core-js/es/*"]
}

My package.json (omitted Angular stuff):

--- Angular stuff 8.2.2
"core-js": "3.2.1",
"file-saver": "2.0.2",
"ng2-pdf-viewer": "5.3.3",
"ngx-moment": "3.4.0",
"node-sass": "4.12.0",
"numbro": "2.1.2",
"rxjs": "6.5.2",
"typescript": "3.5.3",
"vis-network": "5.2.1",
"web-animations-js": "2.3.2",
"xlsx": "0.15.0",
"zone.js": "0.9.1"
@mojoaxel mojoaxel added the bug Something isn't working label Aug 13, 2019
@Thomaash
Copy link
Member

I just don't see any solution here. Moment is UMD and therefore doesn't work without synthetic default import. I'm open to suggestions though.

@mojoaxel mojoaxel added the help wanted Extra attention is needed label Aug 19, 2019
@mojoaxel
Copy link
Member

This should help:

try adding "allowSyntheticDefaultImports": true in compilerOptions in your tsconfig.json file and then use the syntax

via moment/moment#4397

Or try setting the esModuleInterop flag to true.

With flag esModuleInterop we can import CommonJS modules in compliance with es6 modules spec

via https://stackoverflow.com/a/56348146/722162

@mojoaxel mojoaxel added question Further information is requested and removed bug Something isn't working help wanted Extra attention is needed labels Aug 19, 2019
@MiselKING
Copy link
Author

Ok, so after testing I can confirm that adding any of allowSyntheticDefaultImports or esModuleInterop to true works. I figured any of those would work, but I didn't want to add them because of moment (which I kinda don't care about)...
I guess we can wait a bit more and see if someone has a different approach, if not then I will close this issue since this fixes it...

@JKostov
Copy link

JKostov commented Sep 3, 2019

Can the es6 export/import syntax be used in the moment type module file? @Thomaash

import * as moment from 'moment';
export default moment;

@Thomaash
Copy link
Member

Thomaash commented Sep 3, 2019

Hi @JKostov,

no this doesn't work. In the end you are still importing UMD module and that just doesn't work without allowSyntheticDefaultImports.

@slavede
Copy link

slavede commented Sep 30, 2019

Bottom line, is there a way to use it with Angular8 without losing some of the Angular 8 benefits (by updating tsconfig)?

@Thomaash
Copy link
Member

What benefits do you lose by enabling synthetic default import? I thought Angular is bundled by Webpack which should handle this transparently without causing any issues.

But if you really don't want to enable it the problem is only in the types (if you use the ESM bundle the code is already converted into ESM). You can convert /…/node_modules/moment/moment.d.ts into ESM format if you want (since I've never tried to do anything like this there's probably a better way to achieve the same result than editing a file that will be repeatedly overwritten by npm).

@MiselKING
Copy link
Author

Since this issue seems to occur only for moment module, if (and when) it is removed then this should work without need for allowSyntheticDefaultImports. There is an issue already created for removing moment (#97) so you can track the progress there.
I will also close this issue since I don't see a reason for not using any of the allowSyntheticDefaultImports or esModuleInterop options.

@ricardomga
Copy link

I am having this problem and I have tried the solutions above but none worked for me. Any idea of what I am doing wrong. It's an angular 8 project.

ERROR in node_modules/vis-network/dist/types/index-legacy.d.ts(18,25): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

Any sugestion can help, thanks.

@Thomaash
Copy link
Member

Thomaash commented Jan 8, 2020

Hi @ricardomga,

do you really need the legacy build? The peer and standalone builds don't reexport Moment at all. Maybe that would help. Also check that you set allowSyntheticDefaultImport in the tsconfig that is actually being used. I don't know much about Angular so this is pretty much all I can say.

@ricardomga
Copy link

ricardomga commented Jan 8, 2020

Hi @Thomaash thanks for the reply. The allowSyntheticDefaultImport didn't work for me. I am using the package ngx-vis in my angular app. I don't need the legacy build, but how can I ignore it?

@Thomaash
Copy link
Member

Thomaash commented Jan 8, 2020

In case your using ngx-vis you should create an issue at https://github.com/visjs/ngx-vis/issues/new/choose. I don't have much of an insight into that.

@hassan-kassim
Copy link

hassan-kassim commented Mar 12, 2020

you have to add allowSyntheticDefaultImports "true" in the tsconfig.json like tis
"compilerOptions": { "allowSyntheticDefaultImports":true, }
it gives me the solution

luiseduardo123 pushed a commit to luiseduardo123/vis-network that referenced this issue May 11, 2020
* Fixed unnecessary reset with hidden edge

* fix visjs#67

* fix visjs#67

* chore: move hidden_edge_test to examples folder
@tonix-tuft
Copy link

As of today, is this still an issue? I mean, if I have a .d.ts TypeScript file referencing the Moment type of moment, do I need to add "allowSyntheticDefaultImports": true to my tsconfig.json? E.g.:

// index.d.ts
import moment from "moment"; // Import moment typings

declare module "my-package" {
  type Dictionary<K extends string, T> = { [P in K]?: T };

  type Moment = moment.Moment; // Reference the Moment type from moment
  
  // ...
}

Is the only option I have to add "allowSyntheticDefaultImports": true to tsconfig.json or are there any alternatives (perhaps, which would not involve editing tsconfig.json)?

Thank you!

@Thomaash
Copy link
Member

Thomaash commented Aug 2, 2020

Hi @tonix-tuft and anybody else still tracking this,

we're removing Moment from everything except Vis Timeline (where it's actually used, there were deprecation warning for quite a long time) right now, so this won't be necessary anymore (also, since Moment wasn't actually used at all, less bloat in the bundle).

@pauvel
Copy link

pauvel commented Apr 26, 2021

allowSyntheticDefaultImports

Its works.

@slavede
Copy link

slavede commented Jun 15, 2021

This helped us:

Create some file moment.constant.ts and put this inside:

import * as moment_ from 'moment';
export const moment = moment_;

And then you can use through your app.

import { moment } from 'moment.constant';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

9 participants