No puedo entender qué está pasando aquí. Uso el cargador de archivos para cargar las fuentes de mi aplicación:
{ test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'assets/fonts/', publicPath: '../fonts/' } }] }, Las fuentes también se generan en la estructura que especifiqué: dist/assets/fonts. outputPath: 'assets/fonts/' ... parece funcionar correctamente.
Pero: Webpack también empaqueta las fuentes con un hash como nombre en /dist y establece la ruta en el archivo CSS a estos archivos.
@font-face{font-family:"PaulGrotesk";font-style:normal;font-weight:400;src:url(../../d9bc4e30281429c0cddd.eot);¿Que está sucediendo aquí? ¿Cómo puedo evitar que los archivos adicionales se generen y utilicen como ruta?
estoy usando
Mi webpack.config:
const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'assets/js/bundle_v1.0.0.js' }, module: { rules: [ { test: /\.js?$/, exclude: /node_modules/, loader: 'babel-loader', include: path.join(__dirname, 'index'), options: { presets: ['@babel/preset-env'] } }, { test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'assets/fonts/', publicPath: '../fonts/' } }] }, { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader' }, { loader: 'sass-loader', options: { sourceMap: true, } } ] }, { test: /\.css$/i, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ] }, resolve: { alias: { '@': path.resolve(__dirname, 'node_modules'), /* https://webpack.js.org/configuration/resolve/ */ }, }, plugins: [ new MiniCssExtractPlugin({ filename: 'assets/css/bundle_v1.0.0.css' }), new HtmlWebpackPlugin({ inject: 'body', template: './src/index.html', filename: 'index.html', }) ] };Tuve exactamente el mismo problema que OP (@toge) después de haber migrado de Webpack 4 a 5. Mientras buscaba implementar la solución publicada por @seanbun, encontré la siguiente configuración para la nueva configuración de módulos de activos Webpack 5 que permitía para obtener mis svgs anteriores file-loader archivos y los archivos de fuentes para generar correctamente sin duplicación en la carpeta de salida raíz:
{ test: /\.(woff(2)?|ttf|eot)$/, type: 'asset/resource', generator: { filename: './fonts/[name][ext]', }, }, Esto le dice a webpack que lo maneje a través de la configuración de los módulos de activos, pero que genere una ruta de archivo personalizada, similar a cómo solía funcionar la configuración file-loader .
Esta configuración también eliminó mi necesidad de degradar css-loader lo cual fue un beneficio adicional
Ya tenía mis archivos de fuentes en una ubicación útil, por lo que no necesitaba copiar los recursos. (Estoy confundido por qué webpack hizo esto de forma predeterminada). Mi solución fue ignorar esos archivos por:
new webpack.IgnorePlugin({ resourceRegExp: /\.(woff(2)?|ttf|eot|svg)$/ }),Los cargadores se aplican de último a primero. Entonces, supongo que colocar el cargador de archivos debajo de los cargadores css/sass podría solucionar el problema.
Es posible que las fuentes no se registren de esta manera cuando el cargador css las necesite y, por lo tanto, se carguen dos veces.
Aparentemente, Webpack 5 tiene una función de Asset Modules que permite usar archivos de activos (fuentes, íconos, etc.) sin configurar cargadores adicionales, es decir, cargador file-loader de url-loader , etc. Los Asset Modules proporcionan cuatro tipos para manejar diferentes tipos de activos. . Puede encontrar más detalles en https://webpack.js.org/guides/asset-modules/ .
Por lo tanto, cuando agrega la siguiente regla para los archivos de fuentes, los Asset Modules y el file-loader archivos manejan los archivos de manera precisa.
{ test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'assets/fonts/', publicPath: '../fonts/' } }] } En este caso, queremos usar nuestro propio file-loader y deshabilitar el Asset Module . Podemos establecer el tipo en 'javascript/auto'. Esto seguiría la configuración de su ruta y mantendría los archivos de fuentes en la carpeta de assets/fonts .
{ test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, **type: "javascript/auto",** use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'assets/fonts/', publicPath: '../fonts/' } }] } PD: estaba usando css-loader 6.2.0 y tuve un error: url.replace is not a function . Bajé a css-loader 5.2.7 para resolver el problema.