Client sur le noeud: Uncaught ReferenceError: require n'est pas défini

322

Donc, j'écris une application avec le combo node / express + jade.

J'ai client.js, qui est chargé sur le client. Dans ce fichier, j'ai du code qui appelle des fonctions d'autres fichiers JavaScript. Ma tentative était d'utiliser

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

afin de charger le contenu de messages.js(comme je le fais du côté serveur) et plus tard les fonctions d'appel à partir de ce fichier. Cependant, requiren'est pas défini du côté client, et il génère une erreur de formulaire Uncaught ReferenceError: require is not defined.

Ces autres fichiers JS sont également chargés lors de l'exécution sur le client, car je place les liens dans l'en-tête de la page Web. Le client connaît donc toutes les fonctions qui sont exportées à partir de ces autres fichiers.

Comment puis-je appeler ces fonctions à partir de ces autres fichiers JS (tels que messages.js) dans le client.jsfichier principal qui ouvre le socket au serveur?

MightyMouse
la source
4
Pourquoi tu ne les appelles pas juste <script src="messages.js"></script>après ça?
Sterling Archer
1
Cela peut peut-être être une solution, mais il y a une autre chose qui me préoccupe. J'ai également un fichier appelé "representation.js" pour résumer la représentation qui est commune au client et au serveur. Dans ce fichier, j'ai également des instructions require et côté serveur, cela devrait être correct car j'exécute le nœud. Cependant, du côté client, ce sera un problème. Qu'est-ce que tu penses?
MightyMouse
2
Pour les débutants comme moi (qui ne pouvaient même pas épeler "npm" il y a une semaine! :-), il peut être utile de comprendre que l' --requireoption de browserify require()doit être définie côté client. Voir: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Hephaestus
2
@Sterling Archer ... S'il y a 100 fichiers de ce type ... nous ne pouvons pas continuer à charger le, en HTML à droite .........
Baradwaj Aryasomayajula

Réponses:

436

En effet, require()n'existe pas dans le JavaScript côté navigateur / client.

Vous allez maintenant devoir faire des choix concernant la gestion de vos scripts JavaScript côté client.

Vous avez trois options:

  1. Utilisez la <script>balise.
  2. Utilisez une implémentation CommonJS . Dépendances synchrones comme Node.js
  3. Utilisez une implémentation AMD .

Les implémentations côté client CommonJS incluent:

(la plupart d'entre eux nécessitent une étape de génération avant le déploiement)

  1. Browserify - Vous pouvez utiliser la plupart des modules Node.js dans le navigateur. Ceci est mon préféré.
  2. Webpack - fait tout (bundles JS, CSS, etc.). Rendu populaire par la vague de React.js. Réputé pour sa courbe d'apprentissage difficile.
  3. Rollup - Nouveau candidat. Exploite les modules ES6. Comprend des capacités de tremblement d'arbre (supprime le code inutilisé).

Vous pouvez en savoir plus sur ma comparaison du composant Browserify vs (obsolète) .

Les implémentations AMD incluent:

  1. RequireJS - Très populaire parmi les développeurs JavaScript côté client. Pas mon goût à cause de sa nature asynchrone.

Notez que dans votre recherche pour choisir lequel choisir, vous en apprendrez plus sur Bower . Bower est uniquement pour les dépendances de package et n'est pas d'avis sur les définitions de module comme CommonJS et AMD.

J'espère que cela aide certains.

JP Richardson
la source
1
Merci beaucoup. J'ai fait un mini test séparément, c'est pourquoi il m'a fallu un certain temps pour répondre. Je reviendrai peut-être avec quelques questions dans quelques minutes juste pour m'assurer que je comprends comment cette magie a fonctionné. Je veux juste tout mettre ensemble. Merci encore. Browserify semble basculer! :)
MightyMouse
6
Je pense que JSPM devrait être ajouté à la liste.
Martijn
19
Puis-je obtenir un exemple d'utilisation de la <script>balise pour importer une classe React sans utiliser de gestionnaire de packages nodeJs?
Louie Bertoncin
2
SystemJS et JSPM sont des omissions très notables.
Aluan Haddad
4
Ouais. Le composant est désormais obsolète github.com/componentjs/component
i_emmanuel
43

Je viens d'un environnement électronique, où j'ai besoin d'une communication IPC entre un processus de rendu et le processus principal. Le processus de rendu se trouve dans un fichier HTML entre les balises de script et génère la même erreur. La ligne

const {ipcRenderer} = require('electron')

jette le UnCaught ReferenceError: require n'est pas défini

J'ai pu contourner cela en spécifiant l'intégration du nœud comme vraie lorsque la fenêtre du navigateur (où ce fichier HTML est incorporé) a été créée à l'origine dans le processus principal.

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

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

Cela a résolu le problème pour moi. La solution a été proposée ici . Espère que cela aide quelqu'un d'autre. À votre santé.

Kibonge Murphy
la source
Merci beaucoup. Je suppose que je viens de la même vidéo d'application Shopping List de YouTube hahaha
Luiscri
Brillant - agréable de trouver des réponses comme celle-ci au lieu de s'appuyer sur des entrées pour magiquement mettre tout cela ensemble pour vous.
GhostBytes
Excellente réponse pour les utilisateurs d'Electron!
thoni56
incroyable. fonctionne très bien pour moi. aussi, je viens aussi de la vidéo de l'application Liste d'achats o /
adahox_
26

ES6: en html, incluez le fichier js principal en utilisant l'attribut type="module"( prise en charge du navigateur ):

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

Et dans le script.jsfichier, inclure un autre fichier comme celui-ci:

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

Dans le fichier inclus ( module.js), vous devez exporter la fonction / classe que vous importerez

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

Exemple de travail ici .

Kamil Kiełczewski
la source
1
@Curse Ici stackoverflow.com/a/44591205/860099 est écrit "Le module crée une portée pour éviter les collisions de noms." sou vous pouvez mettre "manuellement" valà l'objet fenêtre window.val = val. Voici plunker: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - cette solution fonctionne
Kamil Kiełczewski
1

Dans mon cas, j'ai utilisé une autre solution.

Comme le projet ne nécessite pas de CommonJs et qu'il doit être compatible avec ES3 (modules non pris en charge), il vous suffit de supprimer toutes les instructions d' exportation et d' importation de votre code , car votre tsconfig ne contient pas

"module": "commonjs"

Mais utilisez les instructions d'importation et d'exportation dans vos fichiers référencés

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

Le code généré final aura toujours (au moins pour dactylographié 3.0) de telles lignes

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

Même en utilisant cela ne fonctionnera pas, je pense que la meilleure solution est la navigation par navigateur:

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();
Wael Chorfan
la source
0

Cela a fonctionné pour moi

  1. enregistrez ce fichier https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. charger dans votre HTML comme cette
    <script data-main="your-Scrpt.js" src="require.js"></script>
    note!
    utilisez: -> require (['moudle-name']) dans "your-script.js"
    pas besoin ('moudle-name')
    const {ipcRenderer} = require (['electron'])
    Pas: const {ipcRenderer} = require ('electron')
eaithy
la source
3
Jamais, jamais recommander un "cliquez ici", jamais. Dans le meilleur des cas, c'est un RickRoll, mais nous n'avons aucune idée de ce qui nous attend à la fin de ce lien.
ggdx