Need Help Understanding Aurelia with Webpack and CSS


#1

I’m trying to understand how Aurelia CLI configures webpack in regards to CSS.

I created a project using Babel, Webpack and SASS with maximum minification.

In my main.js file, I do the following

import './styles/app.scss'
import 'toastr/build/toaster.min.css'

In this case, I wind up with all my application css (from my sass files) being compiled into my .js files and the css for toastr being compiled into a [some hash name].css file.

The problem I run into is that my .css isn’t loaded until my .js is loaded which means I can’t rely on any .css for my default “Loading” screen. No biggie, but I’m curious how others handle this? Is there a way to get the toastr.css to bundle in with the rest of my compiles css? Is there a reason .scss gets compiled into the .js files rather than into separate .css files?

Thanks for your help.


#2

Generally, I’d recommend:

  1. Keep all your static assets in static folder at project root level
  2. Use webpack-copy-plugin, and configure it to copy static assets with preserved paths, so you can avoid mis-referencing issue.
  3. Use https://github.com/webpack-contrib/mini-css-extract-plugin to extract all CSS/SCSS in your app into static css so it can be loaded before your JS.

The reason for this browser can handle the loading of CSS better, as it has years of development put into it to optimize this process, compared to injecting style from JS


#3

I’m a bit confused because it would appear that the webpack.config.js file created by the CLI is already using mini-css-extract-plugin. My problem is, I’m not super familiar with webpack to begin with so looking at the webpack.config.js is a bit overwhelming at this point – there’s a lot there and I’m having difficulty finding where it is being configured to compile sass into js rather than css.

Incidentally, it does not appear that you can put .scss files in static as they simply get copied into dist rather than compiled into .css.


#4

is there a sass loader in your config? If you select the default one, i guess you already have everything configured. It’s midnight here so I’ll get back after few hours :smiley:


#5

If you build your app with the following command, au build --env prod, it should extract the CSS files from your JS.


#6

I am indeed using au build --env prod however all the .scss files get compiled directly into the .js files output by webpack. I’m curious if the default webpack config created by the Aurelia CLI for .less acts any differently.

Incidentally, I’ve not made any changes to the webpack.config.js file that Aurelia CLI created for me – this seems to be the default behavior when using the SASS option.


#7

What version CLI have you got? Version 1.0.0-beta.13 seems to extract the CSS just fine.

Cloud you also check what’s in your aurelia_project/aurelia.json, under the build property?


#8

I’m on version 1.0.0-beta.13.

"build": {
"options": {
  "server": "dev",
  "extractCss": "prod",
  "coverage": false
    }
  }

Like I said, I’m not super familiar with webpack and the whole build process. I have the following import at the beginning of my main.js - import './styles/app.scss' Notice that my styles (.scss files) are in a folder within my src directory – ./src/styles. Maybe that’s not where they’re supposed to be?


#9

I’d say you might have found a bug. I generated a new project using the options you did and I can confirm that it is not extracting the CSS. However, the issue does not exist when you set it to use TypeScript.

I’ve had a look at the webpack.config.js files that was generated and the only obvious difference is this additional snippet on the Babel version.

{
    test: /\.scss$/,
    use: ['style-loader', 'css-loader', 'sass-loader'],
    issuer: /\.js$/i
},
{
    test: /\.scss$/,
    use: ['css-loader', 'sass-loader'],
    issuer: /\.html?$/i
}

#10

What do you suggest from here? Do I need to submit this as a bug?

Also, just curious. Your snippet doesn’t totally match mine and I’m wondering if that was a typo on your part or if there is something else at play as well. The .scss rules in mine look like this.

    test: /\.scss$/,
    use: ['style-loader', 'css-loader', 'sass-loader'],
    issuer: /\.[tj]s$/i
  },
  {
    test: /\.scss$/,
    use: ['css-loader', 'sass-loader'],
    issuer: /\.html?$/i
  }

(Notice the issuer: of my first rule.)


#11

Whoops, my bad. I removed the [tj] and replaced with j.

It seems that I might have some solution for now, I’m not entirely sure if this is the correct solution thought or if there’s a better one.

{
  test: /\.scss$/,
  use: [ extractCss ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'sass-loader'],
  issuer: /\.[tj]s$/i
},
{
  test: /\.scss$/,
  use: ['css-loader', 'sass-loader'],
  issuer: /\.html?$/i
}

Try replacing your webpack config with the snippet above.


#12

That does seem to put my compiled .scss into a .css in my dist folder.

A couple further questions.

  1. The resulting .css is not minified – any ideas how to accomplish that as well?
  2. If I also have a vendor import in main.js like this import 'toastr/build/toastr.min.css' is there a way to get that included in the same .css file as my .scss files?
  3. Lastly, the .css file gets created with a random name i.e. 73c329e9186d7eeb5e5e.css. How do I <link> to that in my _Layout.cshtml or index.html file since I don’t know in advance what name will be generated?

#13

As for minifying your CSS, it might be useful to look at the setup highlighted here.

Your vendor CSS should be included in the extracted file. Might be worth checking if the classes are there.

The index.html in this case is generated as part of the build process and it will automatically create those link and script tags. As for Razor views, in dotnet core, you should be able to use the tag helpers.

It would probably look something like this.


#14

Thanks so much for your help!

I think the dotnet core thing is going to be an issue. The example you pointed to works great for .js files in a <script> tag, but for whatever reason, it doesn’t appear that wildcard characters are supported in <link> tags – at least when I try it, the console error gives me a 404 trying to load *.css – almost like its looking for a file named *.css instead of treating * as a wildcard character.

Anyhow, thanks again for all your help.


#15

In ASP.NET Core, You should be able to use:
<link rel="stylesheet" asp-href-include="*.css">

see: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.taghelpers.linktaghelper?view=aspnetcore-2.2