Nuova syntax es6 per l’importazione di moduli commonjs / amd, ad esempio `import foo = require (‘foo’)`

In precedenza potevo fare:

import foo = require('foo'); 

Ma ora che TypeScript (1.5) supporta la syntax del modulo es6, qual è il modo corretto per ottenere lo stesso risultato nella syntax del modulo ES6.

Il modo corretto è continuare a utilizzare la vecchia syntax di importazione. La nuova syntax di importazione è solo per i moduli ES, la vecchia syntax di importazione è per i moduli pre-ES6. I due sono distinti, intenzionalmente. import * as foo from 'foo' importa tutte le proprietà del modulo ‘foo’, non importa il valore di default come foo .

Dal progettista della funzione :

  • Una dichiarazione predefinita di esportazione dichiara sempre un membro esportato denominato default e viene sempre emesso come assegnazione a exports.default. In altre parole, l’ export default ha costantemente la semantica del modulo ES. Per compatibilità con Babel, potremmo opzionalmente emettere un marcatore __esModule quando un modulo ha un’esportazione predefinita, ma in realtà non lo __esModule per nulla.
  • Una dichiarazione export = , che sostituisce una diversa quadro da esportare al posto del modulo stesso, viene sempre emessa come assegnazione a module.exports . È un errore avere altre esportazioni in un modulo che utilizza export = . Questo è il comportamento TypeScript esistente.
  • Un modulo che utilizza export = per esportare un altro modulo (sia esso un modulo interno o esterno) può essere importato usando i nuovi costrutti ES6. In particolare, le convenienti importazioni di destrutturazione possono essere utilizzate con tali moduli. Lo schema di utilizzo export = per esportare un altro modulo è comune nei file .d.ts che forniscono una vista CommonJS / AMD di un modulo interno (ad esempio angular.d.ts).
  • Un modulo che utilizza export = per esportare un’ quadro non modulo al posto del modulo stesso deve essere importato usando la syntax esistente import x = require("foo") come avviene oggi.

Aggiornamento 2016: il compilatore TypeScript a un certo punto ha iniziato a consentire l’ import * as foo from 'legacy-module-foo' per ottenere l’importazione predefinita di un modulo legacy in determinate circostanze. Questa è una violazione delle specifiche ES6 ( §15.2.1.16 , “Il valore” * “indica che la richiesta di importazione è per l’object dello spazio dei nomi del modulo di destinazione.” ).

Quando i moduli legacy importati in questo modo vengono aggiornati ai moduli ES6, le importazioni “predefinite” per tali moduli cesseranno di funzionare (perché * as foo importazioni di * as foo devono importare oggetti dello spazio dei nomi ), il che può essere estremamente confuso se non lo fai sappi che fare questo è un hack TypeScript / SystemJS. È anche ansible che un futuro riallineamento di TypeScript alle specifiche ES causerà la loro rottura.

Di conseguenza, probabilmente si preferisce continuare a utilizzare la syntax di importazione legacy descritta in precedenza per caricare i moduli legacy per evitare di confondere se stessi e altri sviluppatori che lavorano sul codice su come funzionano le importazioni di spazi dei nomi ES6 e per evitare confuse variazioni.

La syntax corrispondente per la syntax del modulo ES6 è:

 import * as foo from 'foo'; 

In pratica importa tutto dal modulo foo in una variabile locale con il nome di foo .

I moduli ES6 sono in effetti moduli esterni TypeScript con una nuova syntax: i moduli ES6 sono file sorgente caricati separatamente che possono importare altri moduli e fornire un numero di esportazioni accessibili dall’esterno. I moduli ES6 presentano diverse nuove dichiarazioni di esportazione e importazione. Si consiglia di aggiornare le librerie e le applicazioni TypeScript per utilizzare la nuova syntax, ma questo non è un requisito.

fonte

Per quanto ne so, ciò significa che sei incoraggiato a migrare i tuoi moduli TypeScript nella nuova syntax, ma continua a usare import foo = require('foo') per importare moduli AMD / CommonJS reali.

A partire da TypeScript 2.7 , è disponibile un nuovo flag esModuleInterop che può essere utilizzato per abilitare le importazioni predefinite con CommonJS / AMD / UMD. Impostando tale flag su true in tsconfig.json , questo dovrebbe funzionare come previsto:

 import foo from 'foo'; 

Un’altra opzione è quella di importarlo usando la syntax commonjs:

 const foo = require("foo"); 

TypeScript e Bable sono entrambi d’accordo su cosa fare con questo. Inoltre, se stai compilando comunque fino a ES5 o meno, allora questo non sarà troppo lontano dalla sua forma finale.