javascript - Ungefangener ReferenceError: process ist nicht definiert
Ich verwende Node.js, um eine Webanwendung zu erstellen. Wenn ich die Anwendung ausführe (entweder indem ich index.html im Browser öffne oder den Befehl „npm start“ im Terminal verwende), erhalte ich zwei Fehler:
Ungefangener ReferenceError: process ist nicht definiert
Ungefangener ReferenceError: require ist nicht definiert
Ich habe den Fehler „require is not defined“ gelöst, indem ich speziell in meinem index.html-Head-Tag den Link zu diesem Skript eingefügt habe, in dem die require-Funktion definiert ist. Allerdings kann ich nichts Vergleichbares für die process-Funktion finden.
Meine Frage ist zweifach:
Warum müssen eingebaute Node.js-Module neu definiert werden? Warum werden sie nicht so erkannt, wie sie sind, also als „eingebaute Module“? Bedeutet der Begriff „eingebautes Modul“ nicht, dass ein Modul nicht extern/zweithändig neu definiert werden muss?
Gibt es eine Möglichkeit, dieses Problem zu lösen? Mein Skript ist sehr einfach, ich versuche nur, eine grundlegende Funktion von Node.js zu verwenden, deshalb kann ich nicht herausfinden, welche Fehler ich gemacht haben könnte.
Wenn jemand auf dieses Problem gestoßen ist und einen Weg gefunden hat, es zu umgehen oder einen Grund dafür kennt, warum dies passiert, wäre das eine große Hilfe.
Antwort #1
Untenstehende Lösung für Uncaught ReferenceError: process is not defined:
- Wenn Sie CRA (Create React App) verwenden, benutzen Sie
process.env. - wenn Sie ViteJS verwenden, nutzen Sie
import.meta.env.
Lies hier mehr darüber, wie man den env-Prozess in Vite importiert: https://vitejs.dev/guide/env-and-mode.html
Beispiele:
CRA: process.env.API_BASE_URL
Vite: import.meta.env.VITE_API_BASE_URL
Antwort #2
Webpack kann Umgebungsvariablen in den "Client-Seiten" .js-Code einfügen (sehr nützlich im Fall von SPA/PWA). Sie sollten sie als Plugins in webpack.config.js definieren
webpack.config.js
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.MY_ENV': JSON.stringify(process.env.MY_ENV),
... and so on ...
})
],
}
Jetzt können Sie darauf auf der Client-Seite zugreifen:
app.js
// Something like that
if(process.env.NODE_ENV === 'debug'){
setDebugLevel(1)
}
Antwort #3
Node.js-Code muss vom Node-Prozess ausgeführt werden, nicht vom Browser (der Code muss auf dem Server ausgeführt werden).
Um den Code auszuführen, müssen Sie den Befehl ausführen:
node server.js
Und dann können Sie von einem Browser aus auf Ihren Server zugreifen, indem Sie zum Beispiel "http://localhost:8080" eingeben. Sie müssen eine Datei server.js (oder wie auch immer) mit dem Server-Code haben, den Sie möchten (in diesem Fall einen Webserver auf Port 8080 erstellen).
Sie können diesem einfachen Beispiel folgen, bei dem Express als HTTP-Servermodul verwendet wird: http://expressjs.com/starter/hello-world.html
Antwort #4
Wenn Sie auf dieses Problem stoßen und Webpack verwenden, können Sie die gewünschten process-Daten in das Client-Bundle einfügen, indem Sie DefinePlugin in Ihrer webpack.config.js verwenden.
Im folgenden Beispiel zeige ich, wie man mehrere Dinge dem process.env-Objekt hinzufügt, um sie im Browser verfügbar zu machen:
- alle Umgebungsvariablen innerhalb von
.envunter Verwendung der Bibliothek dotenv - der Wert von
NODE_ENV, der entweder'development'oder'production'ist
Funktionierendes Beispiel
.env
API_KEY=taco-tues-123
API_SECRET=secret_tacos
// webpack.config.js
const dotenv = require('dotenv').config({ path: __dirname + '/.env' })
const isDevelopment = process.env.NODE_ENV !== 'production'
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.parsed),
'process.env.NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production'),
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // {API_KEY: "taco-tues-123", API_SECRET: "secret_tacos"}
console.log(process.env.NODE_ENV) // development
Beachten Sie, dass console.log(process.env) nur die Werte aus der .env-Datei enthält und dass NODE_ENV kein Teil des process.env-Objekts ist.
Im Beispiel unten zeige ich, wie ich versucht habe, das process.env-Objekt zu injizieren, was mich zu diesem Stack Overflow führte. Ich füge auch eine Hervorhebung aus der Webpack-Dokumentation bei, die erklärt, warum der untenstehende Code nicht funktionierte.
Kaputtes Beispiel
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
...dotenv.parsed,
'NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production')
}
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // Uncaught ReferenceError: taco is not defined
console.log(process.env.NODE_ENV) // development
Aus der Dokumentation des webpack DefinePlugin:
Warnung Beim Festlegen von Werten für den Prozess bevorzugen
'process.env.NODE_ENV': JSON.stringify('production')über
process: { env: { NODE_ENV: JSON.stringify('production') } }Die Verwendung des Letzteren wird das Prozessobjekt überschreiben, was die Kompatibilität mit einigen Modulen, die erwarten, dass andere Werte im Prozessobjekt definiert sind, beeinträchtigen kann.
!Warnung!
Das Injizieren von dotenv.parsed in das Client-Bundle wie beschrieben wird diese Geheimnisse für den Client sichtbar machen. Für Entwicklungszwecke kein großes Problem, aber in einer bereitgestellten Produktionsumgebung werden alle Passwörter oder privaten API-Schlüssel für jeden sichtbar sein, der danach sucht.
