¿Qué es este Javascript "requiere"?

506

Estoy tratando de hacer que Javascript lea / escriba en una base de datos PostgreSQL. Encontré este proyecto en github. Pude obtener el siguiente código de muestra para ejecutar en el nodo.

var pg = require('pg'); //native libpq bindings = `var pg = require('pg').native`
var conString = "tcp://postgres:1234@localhost/postgres";

var client = new pg.Client(conString);
client.connect();

//queries are queued and executed one after another once the connection becomes available
client.query("CREATE TEMP TABLE beatles(name varchar(10), height integer, birthday timestamptz)");
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['Ringo', 67, new Date(1945, 11, 2)]);
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['John', 68, new Date(1944, 10, 13)]);

//queries can be executed either via text/parameter values passed as individual arguments
//or by passing an options object containing text, (optional) parameter values, and (optional) query name
client.query({
  name: 'insert beatle',
  text: "INSERT INTO beatles(name, height, birthday) values($1, $2, $3)",
  values: ['George', 70, new Date(1946, 02, 14)]
});

//subsequent queries with the same name will be executed without re-parsing the query plan by postgres
client.query({
  name: 'insert beatle',
  values: ['Paul', 63, new Date(1945, 04, 03)]
});
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['John']);

//can stream row results back 1 at a time
query.on('row', function(row) {
  console.log(row);
  console.log("Beatle name: %s", row.name); //Beatle name: John
  console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
  console.log("Beatle height: %d' %d\"", Math.floor(row.height/12), row.height%12); //integers are returned as javascript ints
});

//fired after last row is emitted
query.on('end', function() { 
  client.end();
});

Luego traté de que se ejecutara en una página web, pero nada parecía suceder. Revisé la consola de Javascript y solo dice "no se requiere definir".

Entonces, ¿qué es esto "requiere"? ¿Por qué funciona en el nodo pero no en una página web?

Además, antes de hacerlo funcionar en el nodo, tenía que hacerlo npm install pg. ¿De qué trata eso? Miré en el directorio y no encontré un archivo pág. ¿Dónde lo puso y cómo lo encuentra Javascript?

neuromante
fuente
46
require no es parte de javascript, es una palabra clave utilizada en nodejs. nodejs no es el DOM que usa del lado del cliente, por lo que un script que puede funcionar con nodejs podría no funcionar en el navegador. ¿Puedes llamar a window o document en nodejs? no, bueno lo mismo para requerir con el navegador.
mpm
8
¿Cómo cambio el código anterior para que funcione en un navegador?
neuromancer
8
No puede hablar con Pg directamente desde una página web; necesitaría poder abrir un socket tcp / ip simple a través del cual podría enviar y recibir datos binarios, y ningún navegador web le permitirá hacerlo. La biblioteca a la que se refiere es una extensión para node.js y no funcionará en JavaScript del cliente. Le recomiendo que hable con su servidor PostgreSQL desde el cliente a través de su servidor web y solicitudes / respuestas JSON.
Craig Ringer
1
Estoy ejecutando PostgreSQL localmente. ¿Qué necesito instalar para un servidor web?
neuromancer
1
¿Nodo? Es un servidor web bastante bueno, o puede ser uno, para instalar localmente.
Timothy Meade

Respuestas:

872

Entonces, ¿qué es esto "requiere"?

require()no forma parte de la API JavaScript estándar. Pero en Node.js, es una función incorporada con un propósito especial: cargar módulos .

Los módulos son una forma de dividir una aplicación en archivos separados en lugar de tener toda su aplicación en un solo archivo. Este concepto también está presente en otros lenguajes con pequeñas diferencias en la sintaxis y el comportamiento, como C include, Python import, etc.

Una gran diferencia entre los módulos Node.js y el navegador JavaScript es cómo se accede al código de un script desde el código de otro script.

  • En JavaScript del navegador, los scripts se agregan a través del <script>elemento. Cuando se ejecutan, todos tienen acceso directo al ámbito global, un "espacio compartido" entre todos los scripts. Cualquier script puede definir / modificar / eliminar / llamar libremente cualquier cosa en el ámbito global.

  • En Node.js, cada módulo tiene su propio alcance. Un módulo no puede acceder directamente a las cosas definidas en otro módulo a menos que elija exponerlas. Para exponer cosas de un módulo, deben asignarse a exportso module.exports. Para que un módulo acceda a otro módulo exportso module.exports, debe usarlorequire() .

En su código, var pg = require('pg');carga el pgmódulo, un cliente PostgreSQL para Node.js. Esto permite que su código acceda a la funcionalidad de las API del cliente PostgreSQL a través de la pgvariable.

¿Por qué funciona en el nodo pero no en una página web?

require(), module.exportsy exportsson API de un sistema de módulos que es específico de Node.js. Los navegadores no implementan este sistema de módulos.

Además, antes de hacerlo funcionar en el nodo, tenía que hacerlo npm install pg. ¿De qué trata eso?

NPM es un servicio de repositorio de paquetes que aloja módulos JavaScript publicados. npm installes un comando que le permite descargar paquetes de su repositorio.

¿Dónde lo puso y cómo lo encuentra Javascript?

El npm cli coloca todos los módulos descargados en un node_modulesdirectorio donde lo ejecutó npm install. Node.js tiene documentación muy detallada sobre cómo los módulos encuentran otros módulos, lo que incluye encontrar un node_modulesdirectorio.

José
fuente
13
¿Creo que WebPack también tiene su propio requiresoporte ?
Benny Bottema
2
¿Por qué Node.js necesitaría esta funcionalidad?
Melab
24
@Melab Porque la modularización es necesaria tan pronto como el código se convierte en algo más grande que un ejercicio de codificación de la universidad y comienza a involucrar a más de 1 persona. Es por eso que los hemos estado usando desde, como, para siempre .
David Tonhofer
3
El equivalente en PHP sería include/require[_once]( enlace php.net ), no use, que es una palabra clave de alias .
nevvermind
107

Bien, primero comencemos por hacer la distinción entre Javascript en un navegador web y Javascript en un servidor (CommonJS y Node).

Javascript es un lenguaje tradicionalmente limitado a un navegador web con un contexto global limitado definido principalmente por lo que se conoce como el Nivel 0 del Modelo de Objetos del Documento (DOM) (la API Javascript Netscape Navigator).

El Javascript del lado del servidor elimina esa restricción y permite que Javascript invoque varias piezas de código nativo (como la biblioteca Postgres) y abra sockets.

Ahora require()es una llamada de función especial definida como parte de la especificación CommonJS. En el nodo, resuelve bibliotecas y módulos en la ruta de búsqueda de Nodo, ahora generalmente definida como node_modulesen el mismo directorio (o el directorio del archivo JavaScript invocado) o la ruta de búsqueda de todo el sistema.

Para intentar responder el resto de su pregunta, necesitamos usar un proxy entre el código que se ejecuta en el navegador y el servidor de la base de datos.

Dado que estamos discutiendo Node y ya está familiarizado con cómo ejecutar una consulta desde allí, tendría sentido usar Node como ese proxy.

Como un simple ejemplo, vamos a hacer una URL que devuelva algunos datos sobre un Beatle, dado un nombre, como JSON.

/* your connection code */

var express = require('express');
var app = express.createServer();
app.get('/beatles/:name', function(req, res) {
    var name = req.params.name || '';
    name = name.replace(/[^a-zA_Z]/, '');
    if (!name.length) {
        res.send({});
    } else {
        var query = client.query('SELECT * FROM BEATLES WHERE name =\''+name+'\' LIMIT 1');
        var data = {};
        query.on('row', function(row) {
            data = row;
            res.send(data);
        });
    };
});
app.listen(80, '127.0.0.1');
Timothy Meade
fuente
2
es confuso ... el método createServeres confuso ... sugiere que puedo simplemente crear servidores todo el tiempo, cuando quiera ... contrastar eso con mi paradigma WAMP: hace aproximadamente 5 años instalé (por ejemplo, 'creado ') un servidor en mi computadora portátil windowsXP, y nunca he' creado 'otro servidor desde ... ahora, de repente, puedo comenzar a crear servidores ... es confuso ...
dsdsdsdsd
y lo que es 'expresar' ... cuando la búsqueda de C:\Program Files\nodejs\ un archivo o directorio llamado express, no consigo un partido ... así que ¿de dónde viene desde ...
dsdsdsdsd
1
Express es una colección de middleware y framework que facilita la creación de un servidor web en node.js, necesitará instalarlo con npm. Puede encontrar más información aquí: expressjs.com
Timothy Meade
Esa es una muy buena explicación. Tengo una pregunta, ¿requiere trabajar con rutas dinámicas tanto en el entorno NodeJS como en el navegador?
M.Abulsoud
29

Se usa para cargar módulos. Usemos un ejemplo simple.

En archivo circle_object.js:

var Circle = function (radius) {
    this.radius = radius
}
Circle.PI = 3.14

Circle.prototype = {
    area: function () {
        return Circle.PI * this.radius * this.radius;
    }
}

Podemos usar esto a través de require, como:

node> require('circle_object')
{}
node> Circle
{ [Function] PI: 3.14 }
node> var c = new Circle(3)
{ radius: 3 }
node> c.area()

El require()método se utiliza para cargar y almacenar en caché los módulos JavaScript. Entonces, si desea cargar un módulo JavaScript relativo local en una aplicación Node.js, simplemente puede usar elrequire() método.

Ejemplo:

var yourModule = require( "your_module_name" ); //.js file extension is optional
Sudhir Bastakoti
fuente
99
¿Qué pasa si estás tratando de usarlo en una página web?
neuromancer
1
Estoy tratando de cargar lo anterior en una página web.
neuromancer
77
¿Se supone que el primer bloque de código está en un archivo llamado circle_object.js?
user1416227
24

Noté que mientras las otras respuestas explicaban qué es necesario y que se usa para cargar módulos en Node, no dieron una respuesta completa sobre cómo cargar módulos de nodo cuando se trabaja en el Navegador.

Es bastante simple de hacer. Instale su módulo usando npm como lo describe, y el módulo en sí estará ubicado en una carpeta generalmente llamada node_modules.

Ahora, la forma más sencilla de cargarlo en su aplicación es hacer referencia a él desde su html con una etiqueta de script que apunta a este directorio. es decir, si su directorio node_modules está en la raíz del proyecto al mismo nivel que su index.html, escribiría esto en su index.html:

<script src="node_modules/ng"></script>

Todo el script ahora se cargará en la página, para que pueda acceder a sus variables y métodos directamente.

Hay otros enfoques que se usan más ampliamente en proyectos más grandes, como un cargador de módulos como require.js . De los dos, no he utilizado Requerirme a mí mismo, pero creo que muchas personas lo consideran el camino a seguir.

Sam Redway
fuente
Simplemente necesita ir a la raíz de la carpeta de su proyecto y escribir npm install <nombre del módulo>. Por ejemplo, si escribe npm install bootstrap, instalará bootstrap en un directorio llamado node_modules / bootstrap. Y ahora puede cargar bootstrap en su aplicación como se describe anteriormente. Necesitará tener node y npm instalados para poder usarlo obviamente. Si necesita más información, indique el error que está recibiendo.
Sam Redway
<name of module>? Aquí está mi estructura de directorios. La carpeta raíz es xyz. xyz/index.htmlpuntos para xyz/js/scripts.jsusar script tag. xyz/js/scripts.jsTiene código require('./module1.js');require('./module2.js');. module1.js/ module2.jstambién están en la xyz/jscarpeta. Ahora, ¿cómo hago que esté scripts.jsdisponible para el navegador?
intercambio excesivo
16

¿Sabes cómo cuando estás ejecutando JavaScript en el navegador, tienes acceso a variables como "ventana" o matemáticas? No tiene que declarar estas variables, se han escrito para que las use siempre que lo desee.

Bueno, cuando está ejecutando un archivo en el entorno Node.js, hay una variable que puede usar. Se llama "módulo". Es un objeto. Tiene una propiedad llamada "exportaciones". Y funciona así:

En un archivo que llamaremos example.js, escribe:

ejemplo.js

module.exports = "some code";

Ahora, desea esta cadena "algún código" en otro archivo.

Llamaremos al otro archivo otherFile.js

En este archivo, escribes:

otherFile.js

let str = require('./example.js')

Esa declaración require () va al archivo que colocas dentro de él, encuentra los datos almacenados en la propiedad module.exports. La parte let str = ... de su código significa que todo lo que requiera la declaración devuelve se almacena en la variable str.

Entonces, en este ejemplo, el resultado final es que en otherFile.js ahora tiene esto:

let string = "algún código";

  • o -

let str = ('./example.js').module.exports

Nota:

el nombre del archivo que está escrito dentro de la declaración require: si es un archivo local, debería ser la ruta del archivo a example.js. Además, la extensión .js se agrega de manera predeterminada, por lo que no tuve que escribirla.

Hace algo similar cuando necesita bibliotecas de node.js, como Express. En el archivo express.js, hay un objeto llamado 'módulo', con una propiedad llamada 'exportaciones'.

Entonces, se ve algo así en este sentido, debajo del capó (soy un poco principiante, por lo que algunos de estos detalles pueden no ser exactos, pero es para mostrar el concepto:

express.js

module.exports = function() {
    //It returns an object with all of the server methods
    return {
        listen: function(port){},
        get: function(route, function(req, res){}){}
     }
}

Si necesita un módulo, se ve así: const moduleName = require ("module-name");

Si necesita un archivo local, se ve así: const localFile = require ("./ ruta / a / local-file");

(observe el ./ al comienzo del nombre del archivo)


También tenga en cuenta que, de forma predeterminada, la exportación es un objeto ... por ejemplo, module.exports = {} Entonces, puede escribir module.exports.myfunction = () => {} antes de asignar un valor a module.exports. Pero también puede reemplazar el objeto escribiendo module.exports = "Ya no soy un objeto".

Maiya
fuente
6

Dos sabores de module.exports / require:

(ver aquí )


Archivo de exportación de Flavor 1 (misc.js):

var x = 5;
var addX = function(value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

otro archivo:

var misc = require('./misc');
console.log("Adding %d to 10 gives us %d", misc.x, misc.addX(10));


Archivo de exportación de Flavor 2 (user.js):

var User = function(name, email) {
  this.name = name;
  this.email = email;
};
module.exports = User;

otro archivo:

var user = require('./user');
var u = new user();
Mike roedor
fuente