SyntaxError: Importanweisung kann nicht außerhalb eines Moduls verwendet werden

53

Ich habe ein ApolloServer-Projekt, das mir Probleme bereitet. Daher dachte ich, ich könnte es aktualisieren und stieß bei der Verwendung des neuesten Babel auf Probleme. Meine "index.js" ist:

require('dotenv').config()
import {startServer} from './server'
startServer()

Und wenn ich es ausführe, erhalte ich den Fehler "SyntaxError: Importanweisung kann nicht außerhalb eines Moduls verwendet werden". Zuerst habe ich versucht, TPTB * davon zu überzeugen, dass dies ein Modul ist (ohne Erfolg). Also habe ich den "Import" in "Require" geändert und das hat funktioniert.

Aber jetzt habe ich ungefähr zwei Dutzend "Importe" in andere Dateien, die mir den gleichen Fehler geben.

* Ich bin sicher, die Wurzel meines Problems ist, dass ich nicht einmal sicher bin, was sich über das Problem beschwert. Ich nahm an, dass es Babel 7 war (da ich von Babel 6 komme und die Voreinstellungen ändern musste), bin mir aber nicht 100% sicher.

Das meiste, was ich für Lösungen gefunden habe, scheint nicht auf Straight Node zuzutreffen. Wie dieser hier:

ES6-Modul Import mit "Ungefangener SyntaxError: Unerwarteter Bezeichner"

Sagt, es wurde durch Hinzufügen von "type = module" behoben, aber dies würde normalerweise in den HTML-Code gehen, von dem ich keinen habe. Ich habe auch versucht, die alten Voreinstellungen meines Projekts zu verwenden:

"presets": ["es2015", "stage-2"],
"plugins": []

Aber das bringt mir einen weiteren Fehler: "Fehler: Plugin / Preset-Dateien dürfen keine Objekte exportieren, sondern nur Funktionen."

UPDATE: Hier sind die Abhängigkeiten, mit denen ich begonnen habe:

"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",
user3810626
quelle
1
Hallo, ich habe gerade das gleiche Problem. Könnten Sie auch Ihre Abhängigkeiten teilen? Vielleicht sogar ein Unterschied vor und nach Ihrem Update. Ich könnte gegen meine prüfen, ob wir ähnliche Pakete finden können, die den Ärger verursachen könnten.
Luchs
Ich habe gerade alle "Importe" durch "erfordert" ersetzt und jetzt ist alles in Ordnung. Dumm, aber es war die Mühe nicht wert, es jetzt herauszufinden. Ich werde das Original jedoch mit Abhängigkeiten aktualisieren. Wenn Sie Hinweise erhalten, überprüfe ich diese anhand meines ursprünglichen Codes.
user3810626
1
CommonJS-Syntax (require und module.exports) war das ursprüngliche Format für Node und Webpack unterstützt es ebenfalls, aber ES6-Modulsyntax (Export, Import) ist die neuere Methode und wird jetzt von Node und Webpack unterstützt. Ich habe gelesen, dass der Knoten jetzt den Import unterstützt, aber so viele Tutorials zeigen, dass reines Knotenmaterial erforderlich ist, dass es wahrscheinlich besser ist, diese Syntax für den Knoten zu verwenden.
Ted Fitzpatrick
1
Schließlich schien der Weg für mich folgender zu sein: github.com/vuejs/vue-jest/issues/134#issuecomment-461755061 Einstellen der Voreinstellung jest.config.jsauf 'ts-jest/presets/js-with-ts'- noch einige andere Probleme, aber dies löste das große Problem. ..... äh ja, mein Problem war das Testen im Zusammenhang ... die normalen Builds waren in Ordnung
Luchs
Luchs, interessant. Ich benutze Jest nicht. Ted, interessant. OK, ich werde es nicht schwitzen.
user3810626

Antworten:

50

Update 2020 (Knoten 13.2.0+)

Stellen Sie sicher, dass Sie die neueste Version von Node installiert haben. Die --experimental-modulesFlagge ist nicht mehr erforderlich. Führen Sie einfach einen der folgenden Schritte aus :

  • In "type": "module"zum nächstgelegenen Eltern package.json. Damit werden alle .jsund .mjsDateien als ES-Module interpretiert. Sie können einzelne Dateien mithilfe der .cjsErweiterung als CommonJS interpretieren .

ODER

  • Benennen Sie Dateien explizit mit der .mjsErweiterung. Alle anderen Dateien, z. B. .jswerden als CommonJS interpretiert. Dies ist die Standardeinstellung, wenn sie typenicht in definiert ist package.json.
Jabacchetta
quelle
Wenn ich dies verwende, ändern Sie den Pfad so, dass er das "js" für die erforderliche Datei enthält, ändern Sie dann das Format der Exportanweisungen in der erforderlichen Datei und nehmen Sie dann alle "require" -Anweisungen, die ich von "import" geändert habe, weil Jetzt ist "erfordern" unbekannt - dies wird funktionieren, daher werde ich diese Antwort akzeptieren.
user3810626
2
Dies ist nicht wirklich eine Option, wenn das Problem unter node_modules / richtig ist? Irgendwelche Ideen, wie man das in diesem Fall behebt?
Trent Bing
18

Laut dem offiziellen Dokument ( https://nodejs.org/api/esm.html#esm_code_import_code_statements ):

Importanweisungen sind nur in ES-Modulen zulässig. Ähnliche Funktionen in CommonJS finden Sie unter import ().

Damit Node Ihre Datei als ES-Modul behandelt, müssen Sie Folgendes tun ( https://nodejs.org/api/esm.html#esm_enabling ):

  • Fügen Sie "type": "module" zu package.json hinzu
  • Fügen Sie dem Knotenaufruf das Flag "--experimental-modules" hinzu
shmekor
quelle
6

Ich hatte das gleiche Problem und das Folgende hat es behoben (unter Verwendung von Knoten 12.13.1):

  • Ändern Sie die Dateierweiterung .js in .mjs
  • Fügen Sie beim Ausführen Ihrer App das Flag --experimental-modules hinzu.
  • Optional: Fügen Sie "type": "module" in Ihre package.json ein

Weitere Informationen: https://nodejs.org/api/esm.html

iseenoob
quelle
0

Ich hatte dieses Problem in einem jungen Express-API-Projekt.

Der fehlerhafte Servercode in src/server/server.js:

import express from 'express';
import {initialDonationItems, initialExpenditureItems} from "./DemoData";

const server = express();

server.get('/api/expenditures', (req, res) => {
  res.type('json');
  res.send(initialExpenditureItems);
});

server.get('/api/donations', (req, res) => {
  res.type('json');
  res.send(initialDonationItems);
});

server.listen(4242, () => console.log('Server is running...'));

Hier waren meine Abhängigkeiten:

{
  "name": "contributor-api",
  "version": "0.0.1",
  "description": "A Node backend to provide storage services",
  "scripts": {
    "dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
    "test": "jest tests"
  },
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.9.6",
    "@babel/node": "^7.8.7",
    "babel-loader": "^8.1.0",
    "express": "^4.17.1",
    "mysql2": "^2.1.0",
    "sequelize": "^5.21.7",
    "sequelize-cli": "^5.5.1"
  },
  "devDependencies": {
    "jest": "^25.5.4",
    "nodemon": "^2.0.3"
  }
}

Und hier war der Läufer, der den Fehler geworfen hat:

nodemon --exec babel-node src/server/server.js --ignore dist

Das war frustrierend, da ich ein ähnliches Express-Projekt hatte, das gut funktionierte.

Die Lösung bestand zunächst darin, diese Abhängigkeit hinzuzufügen:

npm install @babel/preset-env

Und dann, um es mit einem babel.config.jsim Projektstamm zu verdrahten :

module.exports = {
  presets: ['@babel/preset-env'],
};

Ich weiß nicht genau, warum das funktioniert, aber ich habe es aus einer maßgeblichen Quelle kopiert , deshalb bleibe ich gerne dabei.

halfer
quelle
Ja, mein Problem war, dass der Code eine Reihe von Voreinstellungen hatte und ich nie das richtige Gleichgewicht zwischen Dingen, die ich wollte, und Dingen, die ich nicht wollte / die kaputt waren, finden konnte.
user3810626 vor
Ich habe den ganzen Tag verwirrende JS-Abstürze durchgearbeitet @ user3810626 - Ich vermute, mein Problem ist, dass ich in der Sprache und im Ökosystem ziemlich neu bin, und ich muss erst einmal etwas lernen, damit die Dinge funktionieren. :-)
Anreise
1
Viel Glück! Es ist ein Dschungel da draußen! (Ich meine, wörtlich, das JS-Ökosystem ist ein Dschungel ...)
user3810626 vor
-2
  1. Ich hatte das gleiche Problem, als ich anfing, babel zu verwenden ... Aber später hatte ich eine Lösung ... Ich hatte das Problem bisher nicht mehr ... Derzeit Node v12.14.1, "@ babel / node" : "^ 7.8.4", ich benutze Babel-Node und Nodemon zum Ausführen (Node ist auch in Ordnung ..)
  2. package.json: "start": "nodemon --exec babel-node server.js" debug ":" babel-node debug server.js "!! Hinweis: server.js ist meine Eingabedatei, Sie können Ihre verwenden.
  3. launch.json Beim Debuggen müssen Sie auch Ihre launch.json-Datei "runtimeExecutable" konfigurieren: "$ {workspaceRoot} /node_modules/.bin/babel-node" !! Hinweis: plus runtimeExecutable in der Konfiguration.
  4. Natürlich benötigen und bearbeiten Sie mit babel-node normalerweise auch eine andere Datei, z. B. die Datei babel.config.js / .babelrc
MrLetmein
quelle
-2

Meine Lösung bestand darin, den Pfad für den Babel-Knoten beim Ausführen von nodemon wie folgt einzuschließen:

nodemon node_modules/.bin/babel-node index.js

Sie können in Ihrem package.json-Skript Folgendes hinzufügen:

debug: nodemon node_modules/.bin/babel-node index.js

HINWEIS: Meine Eingabedatei lautet index.js. Ersetzen Sie sie durch Ihre Eingabedatei (viele haben app.js / server.js).

ishab acharya
quelle