Cliente no nó: Uncaught ReferenceError: require não está definido

322

Então, eu estou escrevendo um aplicativo com o nó / express + jade combo.

Eu tenho client.js, que é carregado no cliente. Nesse arquivo, eu tenho um código que chama funções de outros arquivos JavaScript. Minha tentativa foi usar

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

para carregar o conteúdo de messages.js(como eu faço no lado do servidor) e, posteriormente, chamar funções desse arquivo. No entanto, requirenão está definido no lado do cliente e gera um erro no formulário Uncaught ReferenceError: require is not defined.

Esses outros arquivos JS também são carregados em tempo de execução no cliente porque eu coloco os links no cabeçalho da página da web. Portanto, o cliente conhece todas as funções que são exportadas desses outros arquivos.

Como chamo essas funções desses outros arquivos JS (como messages.js) no client.jsarquivo principal que abre o soquete para o servidor?

Rato poderoso
fonte
4
Por que você simplesmente não <script src="messages.js"></script>liga para eles depois disso?
Sterling Archer
1
Talvez isso possa ser uma solução, mas há outra coisa que me preocupa. Eu também tenho um arquivo chamado "representação.js" para abstrair a representação que é comum ao cliente e ao servidor. Nesse arquivo, eu também tenho instruções de solicitação e, no lado do servidor, deve estar ok porque estou executando o nó. No entanto, no lado do cliente, isso será um problema. O que você acha?
MightyMouse 27/09/13
2
Para iniciantes como eu (que nem sabia soletrar "npm" há uma semana! :-), pode ser útil entender que a --requireopção do browserify faz require()com que seja definida no lado do cliente. Veja: lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Hefesto
2
@Sterling Archer ... Se existem 100 desses arquivos ... não podemos continuar a carregar o, em certo HTML .........
Baradwaj Aryasomayajula

Respostas:

436

Isso ocorre porque require()não existe no JavaScript do navegador / lado do cliente.

Agora você terá que fazer algumas escolhas sobre o gerenciamento de scripts JavaScript do lado do cliente.

Você tem três opções:

  1. Use <script>tag.
  2. Use uma implementação CommonJS . Dependências síncronas como Node.js
  3. Use uma implementação da AMD .

Commonjs cliente colaterais implementações incluem:

(a maioria deles exige uma etapa de construção antes da implantação)

  1. Browserify - Você pode usar a maioria dos módulos Node.js. no navegador. Este é o meu favorito.
  2. Webpack - Faz de tudo (pacotes JS, CSS, etc). Tornado popular pelo aumento do React.js. Notório por sua difícil curva de aprendizado.
  3. Rollup - Novo candidato. Aproveita os módulos ES6. Inclui habilidades de abanar árvores (remove o código não utilizado).

Você pode ler mais sobre minha comparação entre o Browserify e o componente (obsoleto) .

As implementações da AMD incluem:

  1. RequireJS - Muito popular entre os desenvolvedores de JavaScript do lado do cliente. Não é o meu gosto por causa de sua natureza assíncrona.

Observe que, em sua pesquisa para escolher qual deles, você lerá sobre o Bower . O Bower é apenas para dependências de pacotes e não é pioneiro em definições de módulos como CommonJS e AMD.

Espero que isso ajude alguns.

JP Richardson
fonte
1
Muito obrigado. Fiz um mini teste separadamente, por isso demorei um pouco para responder. Posso voltar com algumas perguntas em alguns minutos apenas para ter certeza de que entendi como essa mágica funcionou. Eu só quero juntar tudo. Obrigado novamente. Browserify parece balançar! :)
mightymouse
6
Eu acho que o JSPM deve ser adicionado à lista.
Martijn
19
Eu poderia obter um exemplo de uso da <script>tag para importar uma classe React sem o uso de um gerenciador de pacotes nodeJs?
Louie Bertoncin
2
SystemJS e JSPM são omissões muito notáveis.
Aluan Haddad
4
Sim. O componente está agora descontinuado github.com/componentjs/component
i_emmanuel 17/07/07
43

Eu sou proveniente de um ambiente de elétrons, onde preciso da comunicação IPC entre um processo de renderizador e o processo principal. O processo do renderizador fica em um arquivo HTML entre as tags de script e gera o mesmo erro. A linha

const {ipcRenderer} = require('electron')

lança o Uncaught ReferenceError: require não está definido

Consegui contornar isso especificando a integração do nó como verdadeira quando a janela do navegador (onde esse arquivo HTML está incorporado) foi criada originalmente no processo 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
    }
})}

Isso resolveu o problema para mim. A solução foi proposta aqui . Espera que isso ajude outra pessoa. Felicidades.

Kibonge Murphy
fonte
Muito obrigado. Acho que vêm da mesma lista de compras aplicativo de vídeo do YouTube hahaha
Luiscri
Brilhante - é bom encontrar respostas como essa, em vez de contar com entradas para magicamente juntar tudo para você.
precisa saber é
Excelente resposta para usuários de elétrons!
Thiago56
surpreendente. funciona muito bem para mim. também, eu venho do vídeo do aplicativo Lista de Compras também o /
adahox_ 30/03
26

ES6: No html, inclua o arquivo js principal usando o atributo type="module"( suporte ao navegador ):

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

E no script.jsarquivo inclua outro arquivo como esse:

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

Dentro do arquivo incluído ( module.js), você deve exportar a função / classe que você importará

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

Exemplo de trabalho aqui .

Kamil Kiełczewski
fonte
1
@Curso Aqui está stackoverflow.com/a/44591205/860099 "O módulo cria um escopo para evitar colisões de nomes". sou você pode "manualmente" colocar valno objeto janela window.val = val. Aqui está Plunker: Plunker: plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - Esta solução funciona
Kamil Kiełczewski
1

No meu caso, usei outra solução.

Como o projeto não requer CommonJs e deve ter compatibilidade com ES3 (módulos não suportados), basta remover todas as instruções de exportação e importação do seu código , porque o seu tsconfig não contém

"module": "commonjs"

Mas use instruções de importação e exportação em seus arquivos referenciados

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

O código final gerado sempre terá (pelo menos para o texto datilografado 3.0) essas linhas

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

Mesmo usando isso não funcionará, acho que a melhor solução é o 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();
Wael Chorfan
fonte
0

Isso funcionou para mim

  1. salve este arquivo https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. carregue no seu HTML como esta
    <script data-main="your-Scrpt.js" src="require.js"></script>
    Nota!
    use: -> require (['moudle-name']) em "your-script.js"
    não requer ('moudle-name')
    const {ipcRenderer} = require (['electron'])
    Não: const {ipcRenderer} = require ('electron')
eaithy
fonte
3
Nunca, nunca recomende um "clique aqui", nunca. Na melhor das hipóteses, é um RickRoll, mas não temos idéia do que nos espera no final desse link.
Ggdx 26/10/19