Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

192
Views
¿Por qué Webpack no emite fragmentos cuando se usa webpackMode: "débil"?

Estoy haciendo la transición de una aplicación heredada a Webpack. Estoy usando Webpack 5.56 (último en el momento de escribir este artículo).

Mi aplicación está localizada y tengo una carpeta con varios archivos de configuración regional,

 locales - locale.en.ts - locale.de.ts - etc

Cada uno de estos archivos de configuración regional es un módulo ES y todos exportan (diferentes implementaciones de) las mismas funciones: getText , printNumber , etc. Tengo un módulo contenedor que import dinámicamente la configuración regional correcta para el usuario actual:

 // localization.ts interface LocaleModule { getText(text: string): string; // etc } let module: LocaleModule; import(`locales/locale.${currentUser.language}`).then(m => { module = m; }); export function getText(text: string): string { return module.getText(text); }

Conozco el idioma del usuario actual cuando se muestra la página. Quiero incluir el script locale.*.js correcto como fragmento inicial, de modo que:

  • El navegador no tiene que esperar a que se cargue el fragmento principal antes de que pueda comenzar a descargar el archivo de configuración regional.
  • Las funciones en localization.ts pueden ser síncronas.

Parecía que encajaría bien conwebpackMode: "weak" , ya que me gustaría obtener un error en la consola si falta el archivo de locale por cualquier motivo (en lugar de degradar silenciosamente el rendimiento). Los documentos parecen llamar explícitamente mi caso de uso:

Esto es útil para la representación universal cuando los fragmentos requeridos siempre se entregan manualmente en las solicitudes iniciales (incrustados en la página).

Aquí está mi código:

 let module: LocaleModule; import( /* webpackMode: "weak" */ /* webpackChunkName: "locales/[request]" */ `./locales/locale.${currentUser.language}` ).then(m => { module = m; });

Sin embargo, parece que webpackMode: "weak" hace que Webpack no emita fragmentos para los módulos a los que se hace referencia . No hay ningún archivo de locale en la carpeta de salida de Webpack. ¡No puedo incluir un fragmento en el HTML si nunca se emitió!

¿Cuál es la razón de este comportamiento? ¿Hay una manera limpia de hacer que Webpack emita fragmentos para import módulos de edición dinámicamente pero no descargarlos de forma asíncrona? (Sé que podría usar webpackMode: "lazy" y simplemente incluir el fragmento por adelantado en una etiqueta de secuencia de comandos, pero me gustaría obtener un error si falta el archivo de configuración regional). ¿O tengo un problema XY y hay ¿Alguna forma mejor de hacer esto que desconozco?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Para usar weak , ya debe servir manualmente los fragmentos como se indica en los documentos. Esto significa que agregarlo en una importación dinámica como comentario no crea ningún fragmento (en contradicción con lazy y lazy-once ).

¿Existe una forma limpia de hacer que Webpack emita fragmentos para módulos importados dinámicamente pero no los descargue de forma asíncrona?

Para carga síncrona:

Tu también puedes:

  1. Use webpackMode: "lazy" e incluya el fragmento por adelantado en una etiqueta de secuencia de comandos como indicó (la Promise devuelta se rechaza en caso de que falte un fragmento).
  2. Puede definir los archivos de configuración regional js como puntos de entrada dinámicos y cargarlos manualmente usted mismo.

Para su ejemplo, crear un punto de entrada para cada configuración regional podría ser algo como:

 const glob = require('glob') module.exports = { devtool: false, entry: { ...glob.sync('./src/locales/*').reduce((acc, module) => { const name = module.replace('./src/locales/', '').replace('.js', '') acc[name] = module return acc }, {}) } };

Esto emitiría locale.de.js y locale.en.js y luego debería cargar manualmente un <script defer src="locale.<locale>.js"></script> , pero eso depende de cómo sirva tu aplicación

Para carga asíncrona:

Puede usar webpackMode: "lazy" junto con webpackPreload: true para desacoplar las solicitudes de fragmentos main y locale . Como se indica en los documentos

Un fragmento precargado comienza a cargarse en paralelo al fragmento principal.

about 4 years ago · Juan Pablo Isaza Report

0

No puedo publicar un comentario tan largo, así que tiene que ser una respuesta...

Entonces parece que no hay un vínculo real entre los módulos y el paquete no puede resolverlos en tiempo de compilación para que no se emitan. Lo único que cambié en su código es cómo se importan los módulos y funcionó de inmediato:

 const langCode = getLangCode(); let mod; import("./locales/locale.en") switch (langCode) { case "en": import(`./locales/locale.en.js`).then(m => { mod = m; console.log("loaded locale"); }) break; case "de": import(`./locales/locale.de.js`).then(m => { mod = m; console.log("loaded locale"); }) break; default: } export function getText(text) { return mod.getText(text); } function getLangCode() { return "de"; }

Sé que el cambio de caso no es ideal, pero el paquete no puede adivinar automáticamente ese patrón: ./locales/locale.${langCode}.js y agregar todos los archivos en el directorio que coincidan con .js .

El documento dice lo siguiente:

'débil': intenta cargar el módulo si la función del módulo ya se ha cargado de alguna otra manera (por ejemplo, otro fragmento lo importó o se cargó un script que contiene el módulo). Todavía se devuelve una Promesa, pero solo se resuelve correctamente si los fragmentos ya están en el cliente. Si el módulo no está disponible, se rechaza la Promesa. Nunca se realizará una solicitud de red. Esto es útil para la representación universal cuando los fragmentos requeridos siempre se entregan manualmente en las solicitudes iniciales (incrustados en la página), pero no en los casos en que la navegación de la aplicación activará una importación que no se realizó inicialmente.

Por lo que entiendo, esto significa que se espera que los fragmentos ya estén en la página y se generen a través de otros medios.

Espero que eso te ayude a resolver tu problema.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!