es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Webpack: hacer que `additionalData` de sass-loader dependa del nombre de la entrada.

Tengo una aplicación de React cuyos componentes importan archivos sass para el estilo. Estoy empaquetando todo con webpack y me gustaría generar diferentes archivos css para diferentes temas.

En mi configuración de webpack he definido dos entradas:

module.exports = {
    entry: {
        "theme1": {
            import: ["./src/index.js?theme1"],
        },
        "theme2": {
            import: ["./src/index.js?theme2"],
        },
    },
}

El cargador sass-loader debería agregar variables de temas a los archivos sass dependiendo del nombre de la entrada:

loader: "sass-loader",
    options: {
        additionalData: (content, loaderContext) => {
             if (CURRENT_ENTRY == 'theme1') return "@use 'theme1.scss' as vars";
             else return "@use 'theme2.scss' as vars";
        },
    },
}

Pero no puedo obtener la entrada actual… ¿alguna idea si esto es posible o alguna sugerencia para soluciones alternativas?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una solución potencial a este problema podría ser usar el DefinePlugin en webpack para definir una variable global basada en el nombre de entrada. Por ejemplo:

    module.exports = {
      entry: {
        "theme1": {
          import: ["./src/index.js?theme1"],
        },
        "theme2": {
          import: ["./src/index.js?theme2"],
        },
      },
      plugins: [
        new webpack.DefinePlugin({
          CURRENT_ENTRY: JSON.stringify(process.env.ENTRY),
        }),
      ],
      module: {
        rules: [
          {
            test: /\.scss$/,
            use: [
              "style-loader",
              "css-loader",
              {
                loader: "sass-loader",
                options: {
                  additionalData: (content, loaderContext) => {
                    if (CURRENT_ENTRY === "theme1") return "@use 'theme1.scss' as vars";
                    else return "@use 'theme2.scss' as vars";
                  },
                },
              },
            ],
          },
        ],
      },
    };
    

    Luego, podrías ejecutar webpack con diferentes variables de entorno para generar diferentes hojas de estilo:

    ENTRY=theme1 webpack
    ENTRY=theme2 webpack
    

    De esta manera, DefinePlugin hará que la variable CURRENT_ENTRY esté disponible para tu cargador Sass, y podrás usarla para importar condicionalmente diferentes archivos de tema.

    Otra solución sería usar ExtractTextPlugin para generar archivos CSS separados para cada tema, y luego cambiar entre ellos dinámicamente según la preferencia del usuario. Este enfoque requeriría más configuración, pero permitiría una mayor flexibilidad en la forma en que gestionas tus temas.

Comments are closed.