Pregunta ¿Puedo usar el paquete web para generar CSS y JS por separado?


Yo tengo:

  1. Archivos JS que quiero agrupar.
  2. MENOS archivos que quiero compilar hasta CSS (resolviendo @imports en un solo paquete).

Esperaba especificar esto como dos entradas separadas y tener dos salidas separadas (probablemente a través de extract-text-webpack-plugin). Webpack tiene todos los complementos / cargadores adecuados para hacer la compilación, pero no parece gustarle la separación.

He visto ejemplos de personas que requieren sus archivos LESS directamente de JS, como require('./app.less');, sin más motivo que indicarle a webpack que incluya esos archivos en el paquete. Esto le permite tener solo un punto de entrada único, pero me parece realmente incorrecto: ¿por qué necesitaría MENOS en mi JS cuando no tiene nada que ver con mi código JS?

Intenté usar múltiples puntos de entrada, entregando tanto la entrada JS como el archivo LESS principal, pero al usar múltiples puntos de entrada, el paquete web genera un paquete que no ejecuta el JS en carga: lo agrupa todo, pero no sabe que debe ser ejecutado al inicio

¿Estoy usando mal el paquete web? ¿Debo ejecutar instancias separadas de paquete web para estos módulos por separado? ¿Debería incluso utilizar el paquete web para activos que no sean de JS si no voy a mezclarlos en mi JS?


32
2018-02-10 18:19


origen


Respuestas:


¿Debería incluso utilizar el paquete web para activos que no sean de JS si no voy a mezclarlos en mi JS?

Tal vez no. Webpack es definitivamente js-céntrico, con la suposición implícita de que lo que estás creando es una aplicación js. Su implementación de require() le permite tratar todo como un módulo (incluidos los parciales Sass / LESS, JSON, casi cualquier cosa), y automáticamente hace su gestión de dependencias por usted (todo lo que require está incluido, y nada más).

¿Por qué necesitaría MENOS en mi JS cuando no tiene nada que ver con mi código JS?

Las personas hacen esto porque están definiendo una parte de su aplicación (por ejemplo, un componente React, una Vista Backbone) con js. Esa pieza de la aplicación tiene CSS que lo acompaña. Dependiendo de algún recurso de CSS externo que se construya por separado y no se haga referencia directamente desde el módulo js es frágil, más difícil de trabajar y puede llevar a que los estilos se desactualicen, etc. Webpack lo anima a mantener todo modular, para que tenga un CSS (Sass, lo que sea) parcial que va con ese componente js, y el componente js require()s para hacer que la dependencia sea clara (para usted y para la herramienta de compilación, que nunca crea estilos que no necesita).

No sé si podría usar el paquete web para agrupar CSS por sí mismo (cuando los archivos CSS no están referenciados desde ningún js). Estoy seguro de que podría conectar algo con complementos, etc., pero no estoy seguro de que sea posible de inmediato. Si hace referencia a los archivos CSS de su js, puede agrupar fácilmente el CSS en un archivo separado con el complemento Extraer texto, como usted dice.


10
2018-02-11 18:51



Se puede generar un paquete CSS separado sin usar require('main/less) en cualquiera de sus JS, pero como señaló Brendan en la primera parte de su respuesta, Webpack no está diseñado para que un paquete global de CSS vaya junto con JS modular, sin embargo, hay un par de opciones.

El primero es agregar un punto de entrada adicional para main.less, luego use el complemento Extraer texto para crear el paquete de CSS:

var webpack = require('webpack'),
    ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: {
        home: [
            'js/common',
            'js/homepage'
        ],
        style: [
            'styles/main.less'
        ]
    },
    output: {
        path: 'dist',
        filename: "[name].min.js"
    },
    resolve: {
        extensions: ["", ".js"]
    },
    module: {
        loaders: [{
            test: /\.less$/,
            loader: ExtractTextPlugin.extract("style", "css", "less")
        }]
    },
    plugins: [
        new ExtractTextPlugin("[name].min.css", {
            allChunks: true
        })
    ]
};

El problema con este método es que también genera un archivo JS no deseado así como el paquete, en este ejemplo: style.js que es solo un módulo de Webpack vacío.

Otra opción es agregar el archivo principal menos a un punto de entrada de Webpack existente:

var webpack = require('webpack'),
    ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: {
        home: [
            'js/common',
            'js/homepage',
            'styles/main.less'
        ],
    },
    output: {
        path: 'dist',
        filename: "[name].min.js"
    },
    resolve: {
        extensions: ["", ".js"]
    },
    module: {
        loaders: [{
            test: /\.less$/,
            loader: ExtractTextPlugin.extract("style", "css", "less")
        }]
    },
    plugins: [
        new ExtractTextPlugin("[name].min.css", {
            allChunks: true
        })
    ]
};

Esto es ideal si solo tiene 1 punto de entrada, pero si tiene más, entonces su configuración de Webpack se verá un poco extraña ya que tendrá que elegir arbitrariamente en qué punto de entrada agregar el archivo principal menos.


8
2017-07-07 15:06



Para aclarar aún más la respuesta anterior de bdmason, parece que la configuración deseable sería crear un conjunto de JS y CSS para cada página, de esta manera:

 entry: {
        Home: ["./path/to/home.js", "./path/to/home.less"],
        About: ["./path/to/about.js", "./path/to/about.less"]
    }

Y luego usa el [name] cambiar:

output: {
        path: "path/to/generated/bundles",
        filename: "[name].js"
    },
plugins: new ExtractTextPlugin("[name].css")

Configuración completa: con algunas adiciones no conectadas a la pregunta (en realidad estamos usando SASS en lugar de LESS):

var ExtractTextPlugin = require("extract-text-webpack-plugin");
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
require('babel-polyfill');

module.exports = [{
    devtool: debug ? "inline-sourcemap" : null,
    entry: {
        Home: ['babel-polyfill', "./home.js","path/to/HomeRootStyle.scss"],
        SearchResults: ['babel-polyfill', "./searchResults.js","path/to/SearchResultsRootStyle.scss"]
    },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                query: {
                    presets: ['react', 'es2015'],
                    plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy']
                }
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract("style-loader","css-raw-loader!sass-loader")
            }
        ]
    },
    output: {
        path: "./res/generated",
        filename: "[name].js"
    },
    plugins: debug ? [new ExtractTextPlugin("[name].css")] : [
        new ExtractTextPlugin("[name].css"),
        new webpack.DefinePlugin({
            'process.env':{
                'NODE_ENV': JSON.stringify('production')
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress:{
                warnings: true
            }
        })
    ]
}
];

3
2017-07-24 12:17



También puede colocar sus declaraciones Less require en su archivo JS de entrada también:

en body.js

// CSS
require('css/_variable.scss')
require('css/_npm.scss')
require('css/_library.scss')
require('css/_lib.scss')

Luego en el paquete web

  entry: {
    body: [
      Path.join(__dirname, '/source/assets/javascripts/_body.js')
    ]
  },

const extractSass = new ExtractTextPlugin({
  filename: 'assets/stylesheets/all.bundle.css',
  disable: process.env.NODE_ENV === 'development',
  allChunks: true
})

0
2018-06-16 11:23