Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use webpack to generate CSS and JS separately?

I have:

  1. JS files that I want to bundle.
  2. LESS files that I want to compile down to CSS (resolving @imports into a single bundle).

I was hoping to specify these as two separate inputs and have two separate outputs (likely via extract-text-webpack-plugin). Webpack has all the proper plugins/loaders to do compilation, but it doesn't seem to like the separation.

I've seen examples of people requiring their LESS files directly from JS, such as require('./app.less');, for no other reason than to tell webpack to include those files into the bundle. This allows you to only have a single entry point, but it seems really wrong to me -- why would I require LESS in my JS when it has nothing to do with my JS code?

I tried using multiple entry points, handing both the entry JS and main LESS file in, but when using multiple entry points, webpack generates a bundle that doesn't execute the JS on load -- it bundles it all, but doesn't know what should be executed on startup.

Am I just using webpack wrong? Should I run separate instances of webpack for these separate modules? Should I even be using webpack for non-JS assets if I'm not going to mix them into my JS?

like image 219
Brent Traut Avatar asked Feb 10 '16 18:02

Brent Traut


People also ask

Can webpack process CSS files?

To be able to use CSS in your webpack app, you need to set up a new loader. Out-of-the-box, webpack only understands Javascript and JSON. With a loader, you can translate another type of file to a format that webpack understands and can work with. There are many webpack loaders and each loader has a specific purpose.

Why you should not use webpack?

The newer bundlers have simpler configuration, allowing people to add/create plugins and configure the setup more easily, and some utilize ESM to make ultra fast reload speeds and smaller bundles. Because of this, Webpack is not the best tool to use anymore.

How do I bundle CSS with webpack?

By default, Webpack will inline your CSS as Javascript tags that injects the CSS into the page. This sounds strange but it lets you do hot reloading in development. In production you extract them to a file using the ExtractTextPlugin, and require it with a normal link tag.

Which of these would extract text CSS from bundles into a separate file?

ExtractTextPlugin: Extract text from a bundle, or bundles, into a separate file.


1 Answers

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.

like image 58
Brendan Gannon Avatar answered Sep 24 '22 14:09

Brendan Gannon