Hvordan får jeg TypeScript til å behandle filen min som et modul?
Fra https://www.typescriptlang.org/docs/handbook/modules.html:
I TypeScript, akkurat som i ECMAScript 2015, blir enhver fil som inneholder en toppnivå
importellerexportbetraktet som et modul. Omvendt blir en fil uten noen toppnivåimportellerexport-deklarasjoner behandlet som et skript hvis innhold er tilgjengelig i det globale området (og derfor også for moduler).
Denne oppførselen er overraskende og uønsket, hvordan kan jeg forhindre det?
Vurder en TypeScript-modul skrevet for sine sideeffekter, lib.ts,
var myglobal = 3;
console.log(`lib.ts: myglobal = ${myglobal}`);
Tenk så på main.ts, en fil som importerer lib.ts for dens bivirkninger:
import './lib.js';
console.log(`main.ts: myglobal = ${myglobal}`);
For fullstendighetens skyld, jeg gir en tsconfig.json:
{
"compilerOptions": {
"lib": ["ES2015", "DOM"],
"module": "ES2015",
"strict": true
},
"files": ["main.ts", "lib.ts"]
}
Det ser ut som dette bør feile ved kompilering, men tsc lykkes, til min store skuffelse. Jeg pakker deretter resultatet med rollup.js,
export default {
input: "main.js",
output: {
file: "bundle.js",
format: "module",
},
};
Det resulterende outputet viser at Rollup og TypeScript tydelig er uenige om hvorvidt myglobal i lib.ts er synlig fra main.ts, siden Rollup legger merke til at myglobal er en fri variabel i main og konkluderer med at den bør omdøpes i lib.
var myglobal$1 = 3;
console.log("lib.ts: myglobal = " + myglobal$1);
console.log("main.ts: myglobal = " + myglobal);
Når jeg kjører det, mislykkes det.
node bundle.js
lib.ts: myglobal = 3
/redacted/bundle.js:4
console.log("main.ts: myglobal = " + myglobal);
^
ReferenceError: myglobal is not defined
at Object. (/redacted/bundle.js:4:38)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47
Det som skulle ha vært en kompileringstid-feil i TypeScript er nå en kjøretidsfeil. Hvordan konfigurerer jeg TypeScript for å behandle lib.js som et modul, slik jeg har til hensikt?
(Når jeg søker i ES2015-spesifikasjonen, kan jeg ikke finne støtte for påstanden om at "enhver fil som inneholder et topplag import eller export betraktes som et modul". Faktisk ser det ut til at hvorvidt en fil er et modul, bestemmes før selve parsing starter, siden det påvirker hva som er målsymbolet for en JavaScript-parser. Så, gir denne delen av TypeScript-dokumentasjonen noen mening?)
Svar #1
Om en fil er en modul eller ikke avhenger av konteksten den lastes i, noe TS ikke har mulighet til å vite, så det trengs et hint basert på filinnholdet. Siden filer som ikke importerer eller eksporterer noe er veldig sjeldne, brukes import- og export-deklarasjoner for å avgjøre om en fil er en modul eller ikke.
Du kan legge til export { } i en fil for å gjøre den til et modul.
Svar #2
Forsøk på å kompilere med '--isolatedModules' vil umiddelbart gi feil på hvilken som helst fil Typescript ikke oppfatter som et modul. Det begrenser også bruken av noen Typescript-funksjoner.