javascript - syntaxerror - El uso de Node.js requiere vs. ES6 importación/exportación
node js export modules (8)
¿Hay 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 la
import/export
desde el estándar ES6.
Algunos cuadros comparativos
http://kangax.github.io/compat-table/es6/
no tienen esto en cuenta, así que cuando vea casi todos los verdes para Chrome, tenga cuidado.
import
palabra clave de
import
de ES6 no se ha tenido en cuenta.
En otras palabras, los motores de navegador actuales, incluido V8, no pueden importar archivos JavaScript nuevos desde el archivo JavaScript principal a través de ninguna directiva JavaScript.
(Es posible que aún nos falten algunos errores o que falten años para que V8 lo implemente de acuerdo con la especificación ES6).
Este document es lo que necesitamos, y este document es lo que debemos obedecer.
Y el estándar ES6 decía que las dependencias del módulo deberían estar allí antes de leer el módulo, como en el lenguaje de programación C, donde teníamos (encabezados) archivos
.h
.
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 cuenta.
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 casos tenemos dependencias perfectas, esto nunca sucederá.
Necesitará algo de tiempo hasta que se
import/export
soporte nativo de
import/export
, y la palabra clave
require
no irá a ningún lado durante mucho tiempo.
¿Qué se
require
?
Esta es la forma de
node.js
para cargar módulos.
(
https://github.com/nodejs/node
)
El nodo utiliza métodos de nivel de sistema para leer archivos.
Básicamente confías en eso cuando usas
require
.
require
terminará en alguna llamada al sistema como
uv_fs_open
(depende del sistema final, Linux, Mac, Windows) para cargar el archivo / módulo de JavaScript.
Para verificar que esto sea cierto, intente usar Babel.js, y verá que la palabra clave de
import
se convertirá en
require
.
En un proyecto en el que estoy colaborando, tenemos dos opciones sobre qué sistema de módulos podemos usar:
-
Importar módulos usando
require
y exportar usandomodule.exports
andmodule.exports
. -
Importar módulos con ES6
import
y exportar con ES6export
¿Hay algún beneficio de rendimiento al usar uno sobre el otro? ¿Hay algo más que deberíamos saber si tuviéramos que usar módulos ES6 sobre nodos?
¿Hay algún beneficio de rendimiento al usar uno sobre el otro?
Tenga en cuenta que todavía no hay un motor de JavaScript que admita de forma nativa los módulos ES6.
Tú mismo dijiste que estás usando Babel.
Babel convierte
export
declaración de
import
y
export
a CommonJS (
require
/
module.exports
) de forma predeterminada de todos modos.
Entonces, incluso si usa la sintaxis del módulo ES6, usará CommonJS debajo del capó si ejecuta el código en Node.
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.
Cuando se trata de una carga asincrónica o quizás lenta, entonces
import ()
es mucho más poderoso.
Vea cuándo requerimos el componente de forma asincrónica, luego usamos
import
manera asíncrona como en la variable
const
usando
await
.
const module = await import(''./module.js'');
O si quieres usar
require()
entonces,
const converter = require(''./converter'');
La cosa es
import()
realidad es de naturaleza asíncrona.
Como lo menciona neehar venugopal en
ReactConf
, puede usarlo para cargar dinámicamente componentes de reacción para la arquitectura del lado del cliente.
También es mucho mejor cuando se trata de enrutamiento. Esa es la única cosa especial que hace que el registro de red descargue una parte necesaria cuando el usuario se conecta a un sitio web específico a su componente específico. por ejemplo, la página de inicio de sesión antes del tablero no descargará todos los componentes del tablero. Porque lo que se necesita actual es decir, el componente de inicio de sesión, que solo se descargará.
Lo mismo ocurre con la
export
: la
export
ES6 es exactamente la misma que para el módulo
module.exports
.
NOTA
- Si está desarrollando un proyecto node.js, debe usar estrictamente
require()
ya que el nodo arrojará un error de excepción como
invalid token ''import''
si va a usar
import
.
Por lo tanto, el nodo no admite declaraciones de importación.
ACTUALIZACIÓN: según lo sugerido por
Dan Dascalescu
: desde v8.5.0 (lanzado en septiembre de 2017), el
node --experimental-modules index.mjs
permite usar la
import
sin Babel.
También puede (y debe)
publicar sus paquetes npm como ESModule nativo, con compatibilidad con versiones anteriores
de la antigua forma
require
.
Consulte esto para obtener más autorización sobre dónde usar las importaciones asíncronas: ReactConf
El uso de módulos ES6 puede ser útil para ''sacudir árboles''; es decir, habilitar Webpack 2, Rollup (u otros paquetes) para identificar rutas de código que no se usan / importan y, por lo tanto, no se incluyen en el paquete resultante. Esto puede reducir significativamente el tamaño de su archivo al eliminar el código que nunca necesitará, pero con CommonJS se incluye de forma predeterminada porque Webpack et al no tienen forma de saber si es necesario.
Esto se realiza mediante análisis estático de la ruta del código.
Por ejemplo, usando:
import { somePart } ''of/a/package'';
... le da al paquete una pista de que
package.anotherPart
no es necesario (si no se importa, no se puede usar, ¿verdad?), por lo que no se molestará en agruparlo.
Para habilitar esto para Webpack 2, debe asegurarse de que su transpiler no esté escupiendo módulos CommonJS.
Si está utilizando el complemento
es2015
con babel, puede deshabilitarlo en su
.babelrc
la
.babelrc
manera:
{
"presets": [
["es2015", { modules: false }],
]
}
Rollup y otros pueden funcionar de manera diferente: vea los documentos si está interesado.
Hay varios usos / capacidades que puede considerar:
Exigir:
- 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 múltiples
require
, se cargan y procesan uno por uno.
Importaciones ES6:
- Puede usar 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 actual ES6 Module Loader, de hecho lo es) y puede funcionar un poco mejor.
Además, el sistema del módulo Requerir no está basado en estándares. Es muy poco probable que se convierta en estándar ahora que existen 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.
Las principales ventajas son sintácticas:
- Más sintaxis declarativa / compacta
- Los módulos ES6 básicamente harán que UMD (Universal Module Definition) quede obsoleto, esencialmente elimina el cisma entre CommonJS y AMD (servidor vs 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 haya compatibilidad total con las funciones de ES6 en el navegador.
Lo más importante que debe saber es que los módulos ES6 son, de hecho, un estándar oficial, mientras que los módulos CommonJS (Node.js) no lo son.
En 2019, los módulos ES6 son compatibles con el 84% de los navegadores. Si bien Node.js los coloca detrás de un --experimental-modules , también hay un conveniente paquete de nodos llamado esm , que hace que la integración sea fluida.
Otro problema que es probable que encuentre entre estos sistemas de módulos es la ubicación del código.
Node.js asume que la fuente se mantiene en un directorio
node_modules
, mientras que la mayoría de los módulos ES6 se implementan en una estructura de directorio plana.
No es fácil conciliarlos, pero se puede hacer pirateando su archivo
package.json
con scripts de instalación previos y posteriores.
Aquí hay un
módulo isomórfico de
ejemplo y un
article
explica cómo funciona.
Personalmente uso la importación porque, podemos importar los métodos requeridos, miembros, usando la importación.
import {foo, bar} from "dep";
FileName: dep.js
export foo function(){};
export const bar = 22
El crédito va a Paul Shan. Más información