How to Use Webpack to Generate CSS and Js Separately

Can I use webpack to generate CSS and JS separately?

Should I even be using webpack for non-JS assets if I'm not going to mix them into my JS?

Maybe not. Webpack is definitely js-centric, with the implicit assumption that what you're building is a js application. Its implementation of require() allows you to treat everything as a module (including Sass/LESS partials, JSON, pretty much anything), and automatically does your dependency management for you (everything that you require is bundled, and nothing else).

why would I require LESS in my JS when it has nothing to do with my JS code?

People do this because they're defining a piece of their application (e.g. a React component, a Backbone View) with js. That piece of the application has CSS that goes with it. Depending on some external CSS resource that's built separately and not directly referenced from the js module is fragile, harder to work with, and can lead to styles getting out of date, etc. Webpack encourages you to keep everything modular, so you have a CSS (Sass, whatever) partial that goes with that js component, and the js component require()s it to make the dependency clear (to you and to the build tool, which never builds styles you don't need).

I don't know if you could use webpack to bundle CSS on its own (when the CSS files aren't referenced from any js). I'm sure you could wire something up with plugins, etc., but not sure it's possible out of the box. If you do reference the CSS files from your js, you can easily bundle the CSS into a separate file with the Extract Text plugin, as you say.

How to bundle JS and CSS file independently with Webpack?

Use the ignore-emit-webpack-plugin Webpack plugin to not create the excess file. First install it by running in a console:

npm install --save-dev ignore-emit-webpack-plugin

Then add it to your Webpack configuration:

const IgnoreEmitPlugin = require('ignore-emit-webpack-plugin');

module.exports = {
// ...
plugins: [
// ...
new IgnoreEmitPlugin(['styleBaz.js', 'styleBaq.js']) // Or simply: new IgnoreEmitPlugin(/^style.*\.js$/)
]
};

How to generate different CSS bundle with Webpack 5

You can get multiple separate CSS by adding multiple entries in your configuration.

Example:

webpack.config.js

module.exports = {
entry: {
main: "./path/to/your_main.js",
"css-theme-1": "./path/to/your/theme.css",
"css-theme-2": "./path/to/your/another-theme.css",
}
}

Also, you can build it into a folder by configuring filename properties in mini-css-extract-plugin.

Further reading:

  • Webpack Code Splitting

Webpack, generate individual CSS file for each imported CSS file with MiniCssExtractPlugin

Solution

You could use optimization entry of webpack.config.js. You can add this entry in your webpack.config.js after plugins array for example:

optimization: {
moduleIds: "deterministic",
splitChunks: {
cacheGroups: {
styles: {
test: /animate.css/
name: "animate",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},

The above configuration would generate a separate file for animate.css. However it won't generate a separate CSS file per CSS file import. It's kind of the opposite of what a module bundler is made for.

More

Often what we do is to separate the code we wrote from what's coming form node_modules, writting this config:

 optimization: {
moduleIds: "deterministic",
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
styles: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},

This way, in addition to what you would have normally, you get vendors.js and vendors.css for what's coming from node_modules. See Code Splitting on Webpack's official documentation to learn more.



Related Topics



Leave a reply



Submit