Client sul nodo: Riferimento non rilevato Errore: requisito non definito


322

Quindi, sto scrivendo un'applicazione con la combinazione node / express + jade.

Ho client.js, che viene caricato sul client. In quel file ho il codice che chiama le funzioni da altri file JavaScript. Il mio tentativo era di usare

var m = require('./messages');

per caricare il contenuto di messages.js(proprio come faccio sul lato server) e successivamente le funzioni di chiamata da quel file. Tuttavia, requirenon è definito sul lato client e genera un errore del modulo Uncaught ReferenceError: require is not defined.

Questi altri file JS vengono inoltre caricati in fase di esecuzione sul client perché inserisco i collegamenti nell'intestazione della pagina Web. Quindi il client conosce tutte le funzioni che vengono esportate da questi altri file.

Come posso chiamare queste funzioni da questi altri file JS (come messages.js) nel client.jsfile principale che apre il socket al server?


4
Perché non <script src="messages.js"></script>li chiami e poi li chiami dopo?
Sterling Archer,

1
Forse questa può essere una soluzione, ma c'è un'altra cosa che mi riguarda. Ho anche un file chiamato "Representation.js" per astrarre la rappresentazione comune al client e al server. In quel file ho anche delle istruzioni obbligatorie e sul lato server dovrebbe essere ok perché sto eseguendo il nodo. Tuttavia, sul lato client questo sarà un problema. Cosa ne pensi?
MightyMouse,

2
Per i neofiti come me (che non sono stati in grado di scrivere "npm" una settimana fa! :-), può essere utile capire che l' --requireopzione di browserify provoca la require()definizione sul lato client. Vedi: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Efesto,

2
@Sterling Archer ... Se ci sono 100 file di questo tipo ... non possiamo continuare a caricare, in HTML, giusto .........
Baradwaj Aryasomayajula,

Risposte:


436

Questo perché require()non esiste nel browser / lato client JavaScript.

Ora dovrai fare alcune scelte sulla gestione degli script JavaScript sul lato client.

Hai tre opzioni:

  1. Usa <script>tag.
  2. Utilizzare un'implementazione CommonJS . Dipendenze sincrone come Node.js
  3. Utilizzare un'implementazione AMD .

Le implementazioni lato client di CommonJS includono:

(la maggior parte di essi richiede un passaggio di compilazione prima della distribuzione)

  1. Browserify : è possibile utilizzare la maggior parte dei moduli Node.js nel browser. Questo è il mio preferito.
  2. Webpack : fa tutto (bundle JS, CSS, ecc.). Reso popolare dall'ondata di React.js. Famoso per la sua difficile curva di apprendimento.
  3. Rollup - Nuovo concorrente. Sfrutta i moduli ES6. Include abilità di agitazione degli alberi (rimuove il codice inutilizzato).

Puoi leggere di più sul mio confronto di Browserify vs (obsoleto) Componente .

Le implementazioni AMD includono:

  1. RequireJS : molto popolare tra gli sviluppatori JavaScript sul lato client. Non è un mio gusto a causa della sua natura asincrona.

Nota, nella tua ricerca per scegliere con quale andare, leggerai di Bower . Bower è solo per le dipendenze dei pacchetti ed è non adottato su definizioni di moduli come CommonJS e AMD.

Spero che questo aiuti alcuni.


1
Grazie mille. Ho fatto un mini test separatamente, ecco perché mi ci è voluto un po 'di tempo per rispondere. Potrei tornare con alcune domande in pochi minuti solo per essere sicuro di aver capito come funzionava questa magia. Voglio solo mettere tutto insieme. Grazie ancora. Browserify sembra oscillare! :)
MightyMouse,

6
Penso che JSPM debba essere aggiunto all'elenco.
Martijn,

19
Potrei ottenere un esempio dell'uso del <script>tag per importare una classe React senza l'uso di un gestore pacchetti nodeJs?
Louie Bertoncin,

2
SystemJS e JSPM sono omissioni notevoli.
Aluan Haddad,

4
Si. Il componente è ora obsoleto github.com/componentjs/component
i_emmanuel

43

Vengo da un ambiente elettronico, dove ho bisogno della comunicazione IPC tra un processo di rendering e il processo principale. Il processo di rendering si trova in un file HTML tra i tag di script e genera lo stesso errore. La linea

const {ipcRenderer} = require('electron')

genera l' errore di riferimento non rilevato: il requisito non è definito

Sono stato in grado di aggirare il problema specificando l'integrazione del nodo come vera quando la finestra del browser (in cui è incorporato questo file HTML) è stata originariamente creata nel processo principale.

function createAddItemWindow() {
//Create new window
addItemWindown = new BrowserWindow({
    width: 300,
    height: 200,
    title: 'Add Item',

    //The lines below solved the issue
    webPreferences: {
        nodeIntegration: true
    }
})}

Ciò ha risolto il problema per me. La soluzione è stata proposta qui . Spero che questo aiuti qualcun altro. Saluti.


Grazie mille. Immagino di venire dallo stesso video dell'app della Lista della spesa da YouTube hahaha
Luiscri,

Fantastico: è bello trovare risposte come questa invece di fare affidamento sui principianti per magicamente mettere tutto insieme per te.
GhostBytes

Ottima risposta per gli utenti Electron!
thoni56

sorprendente. funziona abbastanza bene per me. vengo anche dal video dell'app della Lista della spesa o /
adahox_

26

ES6: in html includere il file js principale usando l'attributo type="module"( supporto del browser ):

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

E nel script.jsfile includere un altro file del genere:

import { hello } from './module.js';
...
// alert(hello());

All'interno del file incluso ( module.js) è necessario esportare la funzione / classe che verrà importata

export function hello() {
    return "Hello World";
}

Esempio di lavoro qui .


1
@Curse Qui stackoverflow.com/a/44591205/860099 è scritto "modulo crea un ambito per evitare collisioni di nomi." puoi "mettere" manualmente l' valoggetto finestra window.val = val. Ecco il plunker: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - questa soluzione funziona
Kamil Kiełczewski

1

Nel mio caso ho usato un'altra soluzione.

Dato che il progetto non richiede CommonJs e deve avere la compatibilità ES3 (moduli non supportati) tutto ciò di cui hai bisogno è semplicemente rimuovere tutte le istruzioni di esportazione e importazione dal tuo codice , perché tsconfig non contiene

"module": "commonjs"

Ma usa le istruzioni di importazione ed esportazione nei tuoi file di riferimento

import { Utils } from "./utils"
export interface Actions {}

Il codice generato finale avrà sempre (almeno per dattiloscritto 3.0) tali righe

"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();

1

Anche usando questo non funzionerà, penso che la soluzione migliore sia browserify:

module.exports = {
  func1: function () {
   console.log("I am function 1");
  },
  func2: function () {
    console.log("I am function 2");
  }
};

-getFunc1.js-
var common = require('./common');
common.func1();

0

Questo ha funzionato per me

  1. salva questo file https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. carica nel tuo HTML in questo modo
    <script data-main="your-Scrpt.js" src="require.js"></script>
    Nota!
    usa: -> require (['moudle-name']) in "your-script.js"
    non richiesto ('moudle-name')
    const {ipcRenderer} = require (['electron'])
    Not: const {ipcRenderer} = require ('electron')

3
Mai, mai raccomandare un "clicca qui", mai. Nel migliore dei casi, è un RickRoll, ma non abbiamo idea di cosa ci aspetti alla fine di quel link.
ggdx,
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.