javascript - Hur fixar man "ReferenceError: exports is not defined" i ett rent TypeScript-projekt?


Om jag skriver en .ts med någon typ av import- eller exportinstruktion kommer den resulterande .js-filen att generera följande fel när den laddas i en HTML-sida: "ReferenceError: exports är inte definierad"

Hur man reproducerar:

  1. Skapa ett tomt Node.js-webbapplikationsprojekt i VS
  2. Lägg till en .ts med en import- eller exportrad
  3. Lägg till lite HTML som anropar den resulterande .js
  4. Starta en HTTP-server (http-server -g [port]) och nå din HTML

Jag försökte:

  • Riktar in sig på ES5
  • Ta bort raden "module": "commonjs" från tsconfig.json
  • Installera CommonJS och SystemJS
  • Kompilera .ts med tsc
  • Någon annan lösning som Stack Overflow har på liknande frågor
  • Alla möjliga permuteringar av ovanstående.

Min .ts (kan vara vad som helst om det har en importinstruktion):

import { setTimeout } from "timers";
setTimeout(() => console.log("asdf"), 1000);

HTML:en har bara en enkel body som hänvisar till skriptet

package.json

{
  "name": "nodejs-web-app4",
  "version": "0.0.0",
  "description": "NodejsWebApp4",
  "main": "server.js",
  "author": {
    "name": ""
  },
  "devDependencies": {
    "@types/node": "^8.0.14"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "lib": ["es6"],
    "sourceMap": true
  },
  "exclude": [
    "node_modules"
  ]
}

Resulterande .js:

Från VS-build (resulterar i ReferenceError: exports is not defined):

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const timers_1 = require("timers");
timers_1.setTimeout(() => console.log("asdf"), 1000);
//# sourceMappingURL=home-script.js.map

Från kommandot tsc [filename].ts (resulterar i ReferenceError: exports är inte definierad):

"use strict";
exports.__esModule = true;
var timers_1 = require("timers");
timers_1.setTimeout(function () { return console.log("asdf"); }, 1000);

Från VS Build men tar bort "module": "commonjs" från tsconfig (resulterar i SyntaxError: import declarations may only appear at top level of a module):

import { setTimeout } from "timers";
setTimeout(() => console.log("asdf"), 1000);
//# sourceMappingURL=asdf.js.map

All HTML och ts kommer att kallas för "statisk" (ingen MVC)

Är det fel att använda http-server för att se statisk HTML från mitt VS-projekt? Är det det problemet?

Ska bygga på något annat sätt? Använda en annan uppsättning?

Jag har en lösning (dvs. hålla allt jag behöver i samma TypeScript-fil), men det förvirrar mig att jag inte kan skapa och visualisera ett enkelt projekt med Node/TS.

Svar #1

Webbläsare stödjer inte commonjs-moduler. Du kommer att behöva använda något verktyg (webpack, rollup, browserify) för att bunta dina moduler efter kompilering.

Om du tar bort module-alternativet i tsconfig.json eller om du sätter det till es2015 eller esnext, kommer import- och export-satserna att förbli som de var i den ursprungliga filen.

import { foo } from './bar.js';

export default class Baz {}

Det kan fungera eftersom vissa webbläsare redan stöder inbyggda ES-moduler men det är nödvändigt att lägga till ett type-attribut i script-taggen och sätta det till module.

<script type="module" src="foo.js"></script>

Om du inte gör det, kommer du att få ett fel som 'SyntaxError: import-deklarationer får endast förekomma på toppnivå i en modul'.

Relaterade artiklar