Saltar al contenido

Webpack style-loader / css-loader: la resolución de la ruta url () no funciona

Después de de nuestra larga recopilación de información resolvimos este conflicto que presentan algunos de nuestros lectores. Te compartimos la solución y nuestro deseo es resultarte de mucha apoyo.

Solución:

Me tomó alrededor de 5 días de trabajo entender cómo funciona este lío de paquetes web. Tengo que ser honesto puedo decir que esta es una de esas cosas que realmente no entiendo por qué son herramientas “defacto” del momento. No puedo entender lo difícil que puede ser hacer que los archivos de configuración funcionen como deberían, en trago me tomó 1 hora hacer lo mismo.

Mi problema fue que css-loader estaba cargando todas las reglas de url () (incluidas las fuentes y las imágenes) como [object Module], y fueron exportados por el cargador de archivos pero nunca cargados, así que si agregué? url =false al css-loader nunca copió los archivos y los exportó. Tengo que decir que esto fue totalmente un PITA, pero lo hice funcionar, y espero que funcione para alguien más en el mundo, esto se hizo con el paquete web 4.

const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const CopyPlugin = require('copy-webpack-plugin');
module.exports = 
    entry: "./src/index.js",
    mode: "development",
    module: 
        rules: [
        jsx)$/,
            exclude: /(node_modules,
        png,
        
            test: /.(woff(2)?,
        
            test: /.s[ac]ss$/i,
            use: [
            MiniCssExtractPlugin.loader,
             loader: 'css-loader?url=false',
             loader: 'sass-loader', options:  sourceMap: true  
            ],
        ,
        ]
    ,
    resolve:  extensions: ["*", ".js", ".jsx"] ,
    output: 
        path: path.resolve(__dirname, "dist/"),
        publicPath: "",
        filename: "bundle.js"
    ,
    devServer: 
        contentBase: path.join(__dirname, "dist/"),
        port: 3000,
        publicPath: "http://localhost:3000/dist/",
        hotOnly: true
    ,
    plugins: [ new MiniCssExtractPlugin(),
    new CopyPlugin([ from: 'src/images/', to: 'images/' ]),
    new CopyPlugin([ from: 'src/fonts/', to: 'fonts/' ]),
    new ImageminPlugin(svg)$/i ),
    new HtmlWebpackPlugin(
        hash: true,
        template: './src/index.html',
            filename: './index.html' //relative to root of the application
        ),
    ]
;

Pude resolver el problema yo mismo. En caso de que pueda ayudar a otros en el futuro, encuentre la solución a continuación.


  1. En primer lugar, si está utilizando ambos postcss-loader con el postcss-import complemento, Y css-loader, apague / elimine el postcss-import enchufar. No necesitas más de una herramienta que resuelva @import normas. Esto no es realmente un problema si el orden de los cargadores es correcto, pero también puede eliminarlo.
  2. En los documentos de sass-loader, puede leer lo siguiente:

Dado que Sass / libsass no proporciona reescritura de URL, todos los activos vinculados deben ser relativos a la salida.

  • Si solo está generando CSS sin pasarlo al cargador de CSS, debe ser relativo a la raíz de su web.

  • Si pasa el CSS generado al cargador de CSS, todas las URL deben ser relativas al archivo de entrada (por ejemplo, main.scss).

Lo más probable es que este segundo problema lo perturbe. Es natural esperar que las referencias relativas se resuelvan en el archivo .scss en el que se especifican (como en los archivos .css normales). Afortunadamente, hay dos soluciones a este problema:

  • Agregue la reescritura de la URL que falta con resolve-url-loader. Colóquelo antes del sass-loader en la cadena del cargador.

  • Los autores de bibliotecas suelen proporcionar una variable para modificar la ruta del activo. bootstrap-sass, por ejemplo, tiene un $ icon-font-path. Echa un vistazo a este ejemplo de arranque funcional.

Decidí seguir la viñeta dos y agregar resolve-url-loader encima sass-loader en el Webpack config. Ahora funciona como se esperaba.

Mi configuración final de Webpack (por ahora) se ve así:

    
      test: /.s?[ac]ss$/,
      exclude: /node_modules/,
      use: [
        isProduction
          ? MiniCssExtractPlugin.loader
          : 
              // creates style nodes from JS strings
              loader: 'style-loader',
              options: 
                sourceMap: true,
                // convertToAbsoluteUrls: true
              
            ,
        
          // CSS to CommonJS (resolves CSS imports into exported CSS strings)
          loader: 'css-loader',
          options: 
            sourceMap: true,
            importLoaders: 2
            // url: false,
            // import: false
          
        ,
        
          loader: 'postcss-loader',
          options: 
            config: 
              ctx: 
                cssnext: ,
                cssnano: ,
                autoprefixer: 
              
            ,
            sourceMap: true
          
        ,
        
          loader: 'resolve-url-loader',
          options: 
            attempts: 1,
            sourceMap: true
          
        ,
        
          // compiles Sass to CSS
          loader: 'sass-loader',
          options:  sourceMap: true 
        
      ]
    ,

Notas al margen

  1. Noté que se repiten las rutas del mapa de origen en “sin dominio” en el depurador de Chrome. Si alguien descubre por qué, por favor comparta
  2. Recuerde incluir los siguientes efectos secundarios en package.json, por lo que la sacudida de árboles, que ocurre en el modo de producción, no elimina el CSS extraído

    “efectos secundarios”: [
    .css”,
    .scss”
    ],

Puede desactivar el procesamiento de url() reglas, por cierto. No tengo idea de por qué este es un comportamiento predeterminado.


  loader: 'css-loader',
  options: 
    ...
    url: false,
  
,

valoraciones y comentarios

Si te ha sido de utilidad este post, sería de mucha ayuda si lo compartes con más desarrolladores y nos ayudes a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *