Typescript ReferenceError: le esportazioni non sono definite


105

Cercando di implementare un modulo seguendo il manuale ufficiale , ottengo questo messaggio di errore:

Errore di riferimento non rilevato: le esportazioni non sono definite

su app.js: 2

Ma da nessuna parte nel mio codice uso mai il nome exports.

Come posso risolvere questo problema?


File

app.ts

let a = 2;
let b:number = 3;

import Person = require ('./mods/module-1');

modulo-1.t

 export class Person {
  constructor(){
    console.log('Person Class');
  }
}
export default Person;

tsconfig.json

{
   "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true,
        "outDir": "scripts/"
    },
    "exclude": [
        "node_modules"
    ]
}

Copia e incolla il testo dell'errore nella domanda invece di utilizzare schermate.
Igor

Sei sicuro di non aver digitato exportscon una s alla fine invece di export? Ciò spiegherebbe il messaggio di errore poiché con s è sbagliato.
Igor

digito export non export
George C.

qualsiasi esempio da repositorie che gona funziona al 10000%
George C.

Dove viene eseguito? In una pagina web? Su un server node.js? Avrai bisogno di un caricatore di moduli nell'ambiente run-time in cui gira finalmente il javascript. Dai flag del compilatore stai usando commonjs. Non ho molta familiarità con commonjs, ma dovrai configurare commonjs prima che i moduli Typescript funzionino o dovrai passare a un altro caricatore di moduli (come require.js) e configurarlo.
Mike Wodarczyk

Risposte:


41

MODIFICARE:

Questa risposta potrebbe non funzionare a seconda se non stai es5più prendendo di mira , cercherò di rendere la risposta più completa.

Risposta originale

Se CommonJS non è installato ( che definisceexports ), devi rimuovere questa riga dal tuo tsconfig.json:

 "module": "commonjs",

Secondo i commenti, questo da solo potrebbe non funzionare con le versioni successive di tsc. In tal caso, è possibile installare un caricatore di moduli come CommonJS, SystemJS o RequireJS e quindi specificarlo.

Nota:

Guarda il tuo main.jsfile che ha tscgenerato. Troverai questo in alto:

Object.defineProperty(exports, "__esModule", { value: true });

È la radice del messaggio di errore e, dopo la rimozione "module": "commonjs",, svanirà.


3
Sì, ho ricompilato il mio file .ts e l'errore esiste ancora dopo aver commentato "module": "commonJs",:(
Acidic9

2
Se l'installazione di CommonJS farà scomparire questo errore, come si installa effettivamente CommonJS? Ho passato la maggior parte di un'ora a cercare su Google e non riesco a trovare alcuna istruzione su come farlo. Qualcuno può spiegare per favore ?
Sturm

1
@Sturm La mia risposta potrebbe essere formulata in modo confuso. CommonJS è solo una specifica. Puoi trovare un elenco (non necessariamente esaustivo) di implementazioni qui: en.wikipedia.org/wiki/CommonJS
iFreilicht

1
Ho module: amd, non module: commonjs, e ho questa riga nel mio file .js traspilato.
pabrams

2
Se hai target come ES3 o ES5 nel tuo tsconfig.json, il typescript imposterà automaticamente il tuo modulo su CommonJS se non è definito. La rimozione del modulo non è sufficiente, è necessario impostare qualcos'altro invece - vedere typescriptlang.org/docs/handbook/compiler-options.html
Jake

51

Poche altre soluzioni per questo problema

  • Aggiungere la riga seguente prima di altri riferimenti a Javascript. Questo è un bel trucco.
   <script>var exports = {};</script>
  • Questo problema si verifica con l'ultima versione di TypeScript, questo errore può essere eliminato facendo riferimento alla versione 2.1.6 del dattiloscritto

3
@ChuckLeButt Spero che questo aiuti stackoverflow.com/questions/19059580/...
Venkatesh Muniyandi

3
Odio che funzioni! E sicuramente funziona. Non c'è un modo per far transpilare TypeScript in qualcosa che Node si aspetta? È anche Node che si lamenta? O è il browser? Non sopporto di non capire quale sia effettivamente il problema.
skillit zimberg il

7

npm install @babel/plugin-transform-modules-commonjs

e aggiungere ai plugin .babelrc ha risolto la mia domanda.


7

la mia soluzione è una sintesi di tutto quanto sopra con piccoli accorgimenti che ho aggiunto, in pratica l'ho aggiunto al mio codice html

<script>var exports = {"__esModule": true};</script>
<script src="js/file.js"></script>

questo ti permette anche di usare al importposto di requirese stai usando l'elettrone o qualcosa del genere, e funziona bene con il dattiloscritto 3.5.1, target: es3 -> esnext.


3
qualche progresso qui, l'errore è appena cambiato inapp.js:3 Uncaught ReferenceError: require is not defined
Muhammed Moussa il

questo accade se nodeIntegration è impostato su false durante la creazione della finestra, l'errore si verifica perché hai aggiornato il tuo electronJS o stai seguendo una fonte obsoleta. nodeIntegration era true per impostazione predefinita, ora è false, quindi devi abilitarlo manualmente se vuoi accedere a nodeJS nel processo di rendering. Vedi [Electron require () non è definito] [1] [1]: stackoverflow.com/questions/44391448/…
Hocine Abdellatif

Non sto usando l'elettrone, comunque ho risolto nel mio caso aggiungendo un pacco per creare cose in bundle e rimosso altri modi complicati
Muhammed Moussa


5

Ho avuto lo stesso problema e l'ho risolto aggiungendo la libreria " es5 " a tsconfig.json in questo modo:

{
    "compilerOptions": {
        "target": "es5", //defines what sort of code ts generates, es5 because it's what most browsers currently UNDERSTANDS.
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true, //for angular to be able to use metadata we specify in our components.
        "experimentalDecorators": true, //angular needs decorators like @Component, @Injectable, etc.
        "removeComments": false,
        "noImplicitAny": false,
        "lib": [
            "es2016",
            "dom",
            "es5"
        ]
    }
}

5

Per le persone che hanno ancora questo problema, se l'obiettivo del compilatore è impostato su ES6, è necessario dire a babel di saltare la trasformazione del modulo. Per farlo, aggiungilo al tuo .babelrcfile

{
  "presets": [ ["env", {"modules": false} ]]
}

1
Grazie uomo! Ho provato a lavorare con una vecchia base di codice che scarica tutto in globale e gli script sono inclusi nel browser con il <script>tag. Speravo di utilizzare il modulo insieme al codice precedente e sembra che non sia possibile. Questo almeno mi consente di utilizzare ES6 e mi consente di occuparmi dell'esportazione in seguito.
huggie

2
facendo questo ho ottenuto il seguente errore: Utilizzo dell'opzione Babel 5 rimossa: .modules - Usa il plug-in di trasformazione del modulo corrispondente pluginsnell'opzione. Dai
chharvey

5

Questo viene risolto impostando l' moduleopzione del compilatore su es6:

{
  "compilerOptions": {     
    "module": "es6",
    "target": "es5",    
  }
}

3

Ho avuto anche questo stesso errore. Nel mio caso era perché nel nostro progetto TypeScript AngularJS avevamo una dichiarazione di importazione vecchio stile come questa:

import { IAttributes, IScope } from "angular";

che è stato compilato in JavaScript in questo modo:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

Questo era necessario ai vecchi tempi perché allora IAttributeslo usavamo nel codice e TypeScript non avrebbe saputo cosa farne altrimenti. Ma dopo aver rimosso l'istruzione import e la conversione IAttributesin ng.IAttributesquelle due righe JavaScript è scomparsa, così come il messaggio di errore.


1
Come funzionerebbe per un tipo di dattiloscritto? Devo importarlo, quindi Typescript lo compila.
BluE

Cosa intendi per "tipo di dattiloscritto"? Se si tratta di un tipo intero noto da TypeScript, ad esempio numero o stringa, puoi utilizzarlo immediatamente. Se definisci i tuoi tipi in un modulo, controlla questo: typescriptlang.org/docs/handbook/modules.html
MatX

Intendevo le definizioni di tipo di una libreria esterna come @ types / jquery da npmjs.com/package/@types/jquery . Per rendere la $ variabile utilizzabile dall'interno del mio codice Typescript, inserisco questo nel mio codice: import * as $ from "jquery";
BluE

Sto prendendo di mira es5, ho bisogno di un'altra libreria come requirejs per farlo funzionare?
BluE

1

Aggiungi semplicemente libraryTarget: 'umd', in questo modo

const webpackConfig = {
  output: {
    libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
  }
};

module.exports = webpackConfig; // Export all custom Webpack configs.

1

per me, la rimozione "esModuleInterop": trueda tsconfig.json ha funzionato.


0

Per alcuni progetti ASP.NET importe exportpotrebbe non essere utilizzato affatto nei tuoi Typescripts.

L'errore della domanda si è verificato quando ho tentato di farlo e ho scoperto solo in seguito che avevo solo bisogno di aggiungere lo script JS generato alla vista in questo modo:

<script src="~/scripts/js/[GENERATED_FILE].Index.js" asp-append-version="true"></script>

0

Prova ciò che @iFreilicht ha suggerito sopra. Se ciò non ha funzionato dopo aver installato webpack e tutto il resto, potresti aver appena copiato una configurazione webpack da qualche parte online e configurato lì che desideri che l'output supporti CommonJS per errore. Assicurati che non sia così in webpack.config.js:

module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: { 
    index: "./src/js/index.ts"
  },
  ...
  ...
  output: {
    libraryTarget: 'commonjs',         <==== DELETE THIS LINE
    path: path.join(__dirname, 'build'),
    filename: "[name].bundle.js"
  }
};

0

Ha avuto lo stesso problema e l'ho risolto modificando l'ordine di caricamento dei pacchetti JS.

Controlla l'ordine in cui vengono chiamati i pacchetti di cui hai bisogno e caricali nell'ordine appropriato.

Nel mio caso specifico (non utilizzando il bundler di moduli) dovevo caricare Redux, quindi Redux Thunk, quindi React Redux. Il caricamento React Reduxprima Redux Thunkmi avrebbe dato exports is not defined.


0

Nota: questo potrebbe non essere applicabile per la risposta di OP, ma stavo ottenendo questo errore e questo è il modo in cui l'ho risolto.

Quindi il problema che stavo affrontando era che stavo ottenendo questo errore quando ho recuperato una libreria "js" da un particolare CDN.

L'unica cosa sbagliata che stavo facendo era importare dalla cjsdirectory del CDN in questo modo: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js

Notate la dist/cjsparte? Ecco dov'era il problema.

Sono tornato al CDN (jsdelivr) nel mio caso e ho navigato per trovare la umdcartella. E sono riuscito a trovare un altro insieme di popper.min.jsche era il file corretto per l'importazione: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/umd/popper.min.js.


0
  {
    "compileOnSave": false,
    "compilerOptions": {
      "baseUrl": "./",
      "outDir": "./dist",
      "sourceMap": true,
      "declaration": false,
      "module": "esnext",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": ["node_modules/@types"],
      "lib": ["es2018", "dom"]
    }
  }

5
Benvenuto in StackOverflow. Aggiungi un contesto alla tua risposta o una spiegazione in modo che l'utente possa capire cosa è stato fatto. Solo pubblicare un JSON potrebbe non essere così utile ...
Bruno Monteiro

0

Ho avuto lo stesso problema, ma la mia configurazione richiedeva una soluzione diversa.

Sto usando il create-react-app-rewiredpacchetto con un config-overrides.jsfile. In precedenza, stavo utilizzando l' addBabelPresetsimportazione (nel override()metodo) da customize-crae ho deciso di astrarre quei preset in un file separato. Per coincidenza, questo ha risolto il mio problema.

Ho aggiunto useBabelRc()al override()metodo in config-overrides.jse creato un babel.config.jsfile con quanto segue:

module.exports = {
    presets: [
        '@babel/preset-react',
        '@babel/preset-env'
    ],
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.