El uso de Node.js requiere frente a la importación/exportación de ES6

Resuelto kpimov asked hace 9 años • 11 respuestas

En un proyecto en el que estoy colaborando, tenemos dos opciones sobre qué sistema de módulos podemos usar:

  1. Importar módulos usando requirey exportar usando module.exportsy exports.foo.
  2. Importar módulos usando ES6 import y exportar usando ES6export

¿Existe algún beneficio de rendimiento al usar uno sobre el otro? ¿Hay algo más que debamos saber si usáramos módulos ES6 en lugar de los de Node.js?

kpimov avatar Jul 11 '15 14:07 kpimov
Aceptado
Actualizar

Desde Node.js v12 (abril de 2019), la compatibilidad con módulos ES está habilitada de forma predeterminada y desde Node.js v15 (octubre de 2020) es estable (ver aquí ). Los archivos, incluidos los módulos de Node.js, deben terminar en .mjso el package.jsonarchivo más cercano debe contener "type": "module". La documentación de Node.js tiene mucha más información, también sobre la interoperabilidad entre los módulos CommonJS y ES.

En cuanto al rendimiento, siempre existe la posibilidad de que las funciones más nuevas no estén tan bien optimizadas como las existentes. Sin embargo, dado que los archivos de módulo sólo se evalúan una vez, es probable que se pueda ignorar el aspecto del rendimiento. Al final, de todos modos hay que ejecutar pruebas comparativas para obtener una respuesta definitiva.

Los módulos ES se pueden cargar dinámicamente a través de la import()función. A diferencia de require, esto devuelve una promesa.


Respuesta anterior

¿Existe algún beneficio de rendimiento al usar uno sobre el otro?

Tenga en cuenta que todavía no existe ningún motor JavaScript que admita de forma nativa módulos ES6. Tú mismo dijiste que estás usando Babel . Babel convierte importy exportdeclara a CommonJS ( require/ module.exports) de forma predeterminada de todos modos. Entonces, incluso si usa la sintaxis del módulo ES6, usará CommonJS internamente si ejecuta el código en Node.js.

Existen diferencias técnicas entre los módulos CommonJS y ES6; por ejemplo, CommonJS le permite cargar módulos dinámicamente. ES6 no permite esto, pero hay una API en desarrollo para eso .

Como los módulos ES6 son parte del estándar, los usaría.

Felix Kling avatar Jul 12 '2015 12:07 Felix Kling

Hay varios usos/capacidades que quizás quieras considerar:

Requerir:

  • Puede tener una carga dinámica donde el nombre del módulo cargado no está predefinido/estático, o donde carga condicionalmente un módulo solo si es "realmente necesario" (dependiendo de cierto flujo de código).
  • La carga es sincrónica. Eso significa que si tiene varios requirecorreos electrónicos, se cargan y procesan uno por uno.

Importaciones ES6:

  • Puede utilizar importaciones con nombre para cargar selectivamente solo las piezas que necesita. Eso puede ahorrar memoria.
  • La importación puede ser asíncrona (y en el ES6 Module Loader actual, de hecho lo es) y puede funcionar un poco mejor.

Además, el sistema del módulo Require no está basado en estándares. Es muy poco probable que se convierta en estándar ahora que existen los módulos ES6. En el futuro habrá soporte nativo para los módulos ES6 en varias implementaciones, lo que será ventajoso en términos de rendimiento.

Amit avatar Jul 11 '2015 08:07 Amit

A partir de ahora, la importación de ES6 y la exportación siempre se compilan en CommonJS , por lo que no hay ningún beneficio al usar uno u otro. Aunque se recomienda el uso de ES6, ya que debería ser ventajoso cuando se lance el soporte nativo de los navegadores. La razón es que puede importar parciales desde un archivo, mientras que con CommonJS debe requerir todo el archivo.

ES6 →import, export default, export

JS común →require, module.exports, exports.foo

A continuación se muestra el uso común de ellos.

Exportación predeterminada de ES6

// hello.js
function hello() {
  return 'hello'
}
export default hello

// app.js
import hello from './hello'
hello() // returns hello

ES6 exporta e importa múltiples

// hello.js
function hello1() {
  return 'hello1'
}
function hello2() {
  return 'hello2'
}
export { hello1, hello2 }

// app.js
import { hello1, hello2 } from './hello'
hello1()  // returns hello1
hello2()  // returns hello2

Exportaciones del módulo CommonJS

// hello.js
function hello() {
  return 'hello'
}
module.exports = hello

// app.js
const hello = require('./hello')
hello()   // returns hello

Módulo CommonJS. Exporta múltiples

// hello.js
function hello1() {
  return 'hello1'
}
function hello2() {
  return 'hello2'
}
module.exports = {
  hello1,
  hello2
}

// app.js
const hello = require('./hello')
hello.hello1()   // returns hello1
hello.hello2()   // returns hello2
Hasan Sefa Ozalp avatar Feb 21 '2020 03:02 Hasan Sefa Ozalp

Las principales ventajas son sintácticas:

  • Sintaxis más declarativa/compacta
  • Los módulos ES6 básicamente harán que UMD (Definición de módulo universal) quede obsoleto; esencialmente elimina el cisma entre CommonJS y AMD (servidor versus navegador).

Es poco probable que vea beneficios de rendimiento con los módulos ES6. Aún necesitará una biblioteca adicional para agrupar los módulos, incluso cuando el navegador sea totalmente compatible con las funciones de ES6.

snozza avatar Jul 11 '2015 08:07 snozza

¿Existe algún beneficio de rendimiento al usar uno sobre el otro?

La respuesta actual es no, porque ninguno de los motores de navegador actuales implementa import/exportel estándar ES6.

Algunos cuadros comparativos http://kangax.github.io/compat-table/es6/ no tienen esto en cuenta, así que cuando veas casi todos los verdes para Chrome, ten cuidado. importLa palabra clave de ES6 no se ha tenido en cuenta.

En otras palabras, los motores de navegador actuales, incluido el V8, no pueden importar nuevos archivos JavaScript desde el archivo JavaScript principal mediante ninguna directiva de JavaScript.

(Es posible que todavía falten algunos errores o años hasta que V8 lo implemente de acuerdo con la especificación ES6).

Este documento es lo que necesitamos y este documento es lo que debemos obedecer.

Y el estándar ES6 decía que las dependencias del módulo deberían estar ahí antes de que leamos el módulo como en el lenguaje de programación C, donde teníamos .harchivos (encabezados).

Esta es una estructura buena y bien probada, y estoy seguro de que los expertos que crearon el estándar ES6 lo tenían en mente.

Esto es lo que permite a Webpack u otros paquetes de paquetes optimizar el paquete en algunos casos especiales y reducir algunas dependencias del paquete que no son necesarias. Pero en los casos en que tenemos dependencias perfectas, esto nunca sucederá.

Se necesitará algo de tiempo hasta que import/exportse active el soporte nativo y la requirepalabra clave no desaparecerá durante mucho tiempo.

Qué es require?

Esta es node.jsla forma de cargar módulos. ( https://github.com/nodejs/node )

Node utiliza métodos a nivel de sistema para leer archivos. Básicamente confías en eso cuando lo usas require. requireterminará en alguna llamada al sistema como uv_fs_open(depende del sistema final, Linux, Mac, Windows) para cargar el archivo/módulo JavaScript.

Para comprobar que esto es cierto, intente utilizar Babel.js y verá que la importpalabra clave se convertirá en require.

ingrese la descripción de la imagen aquí

prosti avatar Nov 05 '2016 15:11 prosti