Preact-cli: preact build ignores CSS files

Created on 21 Dec 2019  路  12Comments  路  Source: preactjs/preact-cli


Do you want to request a _feature_ or report a _bug_?
Bug

What is the current behaviour?
When importing a CSS file, preact build ignores it while preact watch puts it in the build.

If the current behaviour is a bug, please provide the steps to reproduce.
Import a CSS file without specifying imports.

import "@material/radio/dist/mdc.radio.css";

And run build. The CSS file will not be in the build folder and the page will miss this styles.

What is the expected behaviour?
Preact bundles the styles in the CSS file, without changing the class names.

If this is a feature request, what is motivation or use case for changing the behaviour?

Please mention other relevant information.

Please paste the results of preact info here.
Unknown argument: info

Version is 2.2.1

All 12 comments

I guess the file you're trying to import is not being copied to the build folder.

I'm not sure if preact-cli supports CSS @import, but even if it does, it's not the best solution in most cases because it's making a request chain, and slowing down your web page.
Better approach is to bundle your CSS in one file which preact-cli is currently doing.

If you want to import CSS files, you might wanna consider adding support for SASS to your project. In that case the file would be imported in build process and be part of your CSS chunk.

I'm not sure if preact-cli supports CSS @import, but even if it does, it's not the best solution in most cases because it's making a request chain, and slowing down your web page.

I am not using @import in CSS. I am using CSS modules like it is done in the default template. However instead of import * as styles from './styles.css'; I just import it because I want all styles to be included.

Better approach is to bundle your CSS in one file which preact-cli is currently doing.

Whether it is its won CSS file or bundled doesn't matter to me. The problem is that these styles aren't included at all.

If you want to import CSS files, you might wanna consider adding support for SASS to your project. In that case the file would be imported in build process and be part of your CSS chunk.

I tried that, but it changed all the class names in the styles, which made them unusable. The problem with that is that material components use the class names in their JS code.

It is possible that these styles are included and I have not found them (even though I looked through the output files), but the class names are changed. But that would still be unexpected behavior, because the development build keeps the class names as is.

Is there a way to tell preact to just copy this file to the styles?

@DerDrodt sorry, my bad. I didn't quite understand the problem.

I have 2 possible workarounds for you:

  1. I think CSS files included in src/index.js don't have hashed class names. So moving your import "@material/radio/dist/mdc.radio.css"; to src/index.js might solve your issue.
  2. Install SASS and include your file like this from another .scss file:
:global {
  @import "@material/radio/dist/mdc.radio.css";
}

Thanks, the second one did the trick!

@DerDrodt What did you do exactly? If I include css files scss files like (2), I still get hashed class names in the resulting output.

I am using the typescript template.

If module: true is not added here:
https://github.com/preactjs-templates/typescript/blob/6849d32f667dde836602bbe426315079af87360f/template/preact.config.js#L23

typings for css files are not generated (css -> css.d.ts).

If it is enabled, so modules: true, class names will be hashed, imports do not work. No matter from css or from scss.

Similar issue (without solution):
https://github.com/preactjs-templates/typescript/issues/16

@DerDrodt What did you do exactly? If I include css files scss files like (2), I still get hashed class names in the resulting output.

I used SASS and added the following code:

:global {
    @import "@material/switch/mdc-switch";
}

Classes in :global don't seem to be hashed

@DerDrodt Thanks. I couldn't figure out how to solve it with the typescript template and finally removed the typed css module loader and switched to https://github.com/Quramy/typed-css-modules which gives me a correct output.

The issue might happen if you include the css files in src/components or src/routes, because files imported from there get treated as css modules

The issue might happen if you include the css files in src/components or src/routes, because files imported from there get treated as css modules

Is there a config setting where we can turn hashing of CSS off from files in these locations?

Essentially all i'm looking to do is have any component CSS sit with the component and simply import it into the file without the class name being hashed.

Found it:

let css = helpers.getLoadersByName(config, 'css-loader')[0];
css.loader.options.modules = false;

@wagg-matt Thank you for the snippet. I'm working on a small project with the Simple template and came across the same problem. I started having all styles at src/styles.css and later, I thought it was big enough to split the styles into src/components/component-name/component-name.css files but I found out that the CSS files in the src/components doesn't seem to build which led me to this thread.

In my case, I didn't have didn't have a preact.config.js, so I just created it and put the following (with small changes):

export default {
    webpack(config, env, helpers, options) {
        const [ css ] = helpers.getLoadersByName(config, 'css-loader');
        css.loader.options.modules = false;
    }
};

It's not closed so I'm posting my solutions to this.
My project is started with preact-cli with typescript and I use sass (installation tips are in preact cli docs)

I installed https://github.com/TeamSupercell/typings-for-css-modules-loader and created preact.config.js file with:

export default {
  webpack(config, env, helpers, options) {
    const [css] = helpers.getLoadersByName(config, 'css-loader');
    css.rule.use.splice(1, 0, '@teamsupercell/typings-for-css-modules-loader');
  },
};

My classes are hashed and I can import sass files correctly in tsx files (like import {someClass} from './file.scss) as d.ts files are created side by side with scss files.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nephix picture nephix  路  4Comments

oren picture oren  路  4Comments

jpoo90 picture jpoo90  路  4Comments

raphaelbauer picture raphaelbauer  路  3Comments

AlStar01 picture AlStar01  路  3Comments