css - node_modules - webpack font loader
Webpack "Error de anĂ¡lisis OTS" cargando fuentes (10)
La configuración de mi paquete web especifica que las fuentes se deben cargar con
url-loader
, y cuando intento ver la página con Chrome aparece el siguiente error:
OTS parsing error: invalid version tag
Failed to decode downloaded font: [My local URL]
Las partes relevantes de mi configuración se ven así:
{
module: {
loaders: [
// ...
{
test: //.scss$/,
loaders: [''style'', ''css?sourceMap'', ''autoprefixer'', ''sass?sourceMap''],
},
{
test: /images//.*/.(png|jpg|svg|gif)$/,
loader: ''url-loader?limit=10000&name="[name]-[hash].[ext]"'',
},
{
test: /fonts//.*/.(woff|woff2|eot|ttf|svg)$/,
loader: ''file-loader?name="[name]-[hash].[ext]"'',
}
],
},
}
No sucede en Safari, y no he probado Firefox.
En desarrollo, estoy sirviendo archivos a través de
webpack-dev-server
, en producción se escriben en el disco y se copian en S3;
en ambos casos obtengo el mismo comportamiento en Chrome.
Esto también sucede con imágenes más grandes (mayores que el límite de 10kB en la configuración del cargador de imágenes).
A partir de 2018,
use MiniCssExtractPlugin
para Webpack (> 4.0) resolverá este problema.
https://github.com/webpack-contrib/mini-css-extract-plugin
El uso de
extract-text-webpack-plugin
en la respuesta aceptada
NO se
recomienda para Webpack 4.0+.
Al igual que con @ user3006381 anterior, mi problema no era solo las URL relativas, sino que el paquete web estaba colocando los archivos como si fueran archivos javascript. Sus contenidos eran básicamente todos:
module.exports = __webpack_public_path__ + "7410dd7fd1616d9a61625679285ff5d4.eot";
en el directorio de fuentes en lugar de las fuentes reales y los archivos de fuentes estaban en la carpeta de salida bajo códigos hash. Para solucionar esto, tuve que cambiar la prueba en mi cargador de URL (en mi caso, mi procesador de imágenes) para no cargar la carpeta de fuentes. Todavía tenía que configurar output.publicPath en webpack.config.js como @ will-madden notes en su excelente respuesta.
Como respondió here @mcortesi si elimina los sourceMaps de la consulta del cargador css, el css se generará sin el uso de blob y las URL de datos se analizarán correctamente
Como usa
url-loader
:
El cargador de URL funciona como el cargador de archivos, pero puede devolver un DataURL si el archivo es más pequeño que un límite de bytes.
Entonces, otra solución a este problema sería aumentar el límite lo suficiente como para que los archivos de fuentes se incluyan como DataURL, por ejemplo, a
100000
que son más o menos
100Kb
:
{
module: {
loaders: [
// ...
{
test: //.scss$/,
loaders: [''style'', ''css?sourceMap'', ''autoprefixer'', ''sass?sourceMap''],
},
{
test: /images//.*/.(png|jpg|svg|gif)$/,
loader: ''url-loader?limit=10000&name="[name]-[hash].[ext]"'',
},
{
test: //.woff(/?v=/d+/./d+/./d+)?$/,
use: ''url-loader?limit=100000&mimetype=application/font-woff'',
},
{
test: //.woff2(/?v=/d+/./d+/./d+)?$/,
use: ''url-loader?limit=100000&mimetype=application/font-woff'',
},
{
test: //.ttf(/?v=/d+/./d+/./d+)?$/,
use: ''url-loader?limit=100000&mimetype=application/octet-stream'',
},
{
test: //.eot(/?v=/d+/./d+/./d+)?$/,
use: ''file-loader'',
},
{
test: //.svg(/?v=/d+/./d+/./d+)?$/,
use: ''url-loader?limit=100000&mimetype=image/svg+xml'',
},
],
},
}
Siempre teniendo en cuenta lo que representa el número límite:
Límite de bytes para archivos en línea como URL de datos
De esta manera, no necesita especificar la URL completa de los activos. Lo que puede ser difícil cuando desea que Webpack no solo responda desde localhost.
Solo una última consideración, esta configuración NO SE RECOMIENDA para la producción. Esto es solo para facilitar el desarrollo.
El método mejor y más fácil es codificar en base64 el archivo de fuente. Y úsalo en font-face. Para codificar, vaya a la carpeta que tiene el archivo de fuente y use el comando en la terminal:
base64 Roboto.ttf > basecodedtext.txt
Obtendrá un archivo de salida llamado basecodedtext.txt. Abre ese archivo. Elimine los espacios en blanco en eso.
Copie ese código y agregue la siguiente línea al archivo CSS:
@font-face {
font-family: "font-name";
src: url(data:application/x-font-woff;charset=utf-8;base64,<<paste your code here>>) format(''woff'');
}
Luego puede usar la
font-family: "font-name"
en su CSS.
Experimenté el mismo problema, pero por diferentes razones.
Después de que la solución de Will Madden no me ayudó, probé todas las soluciones alternativas que pude encontrar a través de Intertubes, pero fue en vano. Al explorar más, acabo de abrir uno de los archivos de fuente en cuestión. El contenido original del archivo había sido sobrescrito de alguna manera por Webpack para incluir algún tipo de información de configuración, probablemente de ajustes previos con el cargador de archivos. Reemplacé los archivos corruptos con los originales, y voilà, los errores desaparecieron (tanto para Chrome como para Firefox).
Para mí, el problema era mi expresión regex. El siguiente hizo el truco para que Bootstrap funcionara:
{
test: //.(woff|ttf|eot|svg)(/?v=[a-z0-9]/.[a-z0-9]/.[a-z0-9])?$/,
loader: ''url-loader?limit=100000''
},
Sé que esto no responde la pregunta exacta de los OP, pero vine aquí con el mismo síntoma pero con una causa diferente:
Tenía los archivos .scss de Slick Slider incluidos así:
@import "../../../node_modules/slick-carousel/slick/slick.scss";
En una inspección más cercana, resultó que estaba tratando de cargar la fuente desde una ubicación no válida (
<host>/assets/css/fonts/slick.woff
), la forma en que se hizo referencia desde la hoja de estilo.
Terminé simplemente copiando
/font/
a mis
assets/css/
y el problema se resolvió por mí.
Si está utilizando Angular , debe verificar para asegurarse de que su
<base href="/">
la etiqueta viene antes de su paquete de hojas de estilo. Cambié mi código de esto:
<script src="~/bundles/style.bundle.js"></script>
<base href="~/" />
a esto:
<base href="~/" />
<script src="~/bundles/style.bundle.js"></script>
y se solucionó el problema. Gracias a este post por abrir mis ojos.
TL; DR
Utilice rutas absolutas a sus activos (incluido su nombre de host completo) configurando su
output.publicPath
para, por ejemplo, "
http://example.com/assets/
".
El problema
El problema es la forma en que Chrome resuelve las URL cuando se analizan desde un blob CSS cargado dinámicamente.
Cuando carga la página, el navegador carga su archivo JavaScript de entrada de paquete Webpack, que (cuando usa el
style-loader
) también contiene una copia codificada en Base64 de su CSS, que se carga en la página.
Eso está bien para todas las imágenes o fuentes que están codificadas en el CSS como URI de datos (es decir, el contenido del archivo está incrustado en el CSS), pero para los activos a los que hace referencia la URL , el navegador tiene que buscar y buscar el archivo.
Ahora, de manera predeterminada, el
file-loader
(al que delega el
url-loader
para archivos grandes) usará URL
relativas
para hacer referencia a los activos, ¡y
ese es el problema!
Estas son las URL generadas por
file-loader
de forma predeterminada: URL relativas
Cuando usa URL relativas, Chrome las resolverá en relación con el archivo CSS que contiene.
Por lo general, está bien, pero en este caso el archivo que contiene está en
blob://...
y cualquier URL relativa se referencia de la misma manera.
El resultado final es que Chrome intenta cargarlos desde el archivo HTML principal y termina tratando de analizar el archivo HTML como el contenido de la fuente, lo que obviamente no funcionará.
La solución
file-loader
al
file-loader
a utilizar rutas absolutas, incluido el protocolo ("http" o "https").
Cambie la configuración de su paquete web para incluir algo equivalente a:
{
output: {
publicPath: "http://localhost:8080/", // Development Server
// publicPath: "http://example.com/", // Production Server
}
}
Ahora las URL que genera se verán así:
Chrome y todos los demás navegadores analizarán correctamente estas URL.
Usando
extract-text-webpack-plugin
Vale la pena señalar que si está extrayendo su CSS a un archivo separado, no tendrá este problema porque su CSS estará en un archivo adecuado y las URL se resolverán correctamente.