Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting options for css-loader in 3.1.1 #1090

Closed
axhamre opened this issue Dec 12, 2017 · 17 comments
Closed

Setting options for css-loader in 3.1.1 #1090

axhamre opened this issue Dec 12, 2017 · 17 comments

Comments

@axhamre
Copy link

axhamre commented Dec 12, 2017

In Webpacker 3.0.2 I had these settings in config/webpack/environment.js as outlined in the docs:

const { environment } = require('@rails/webpacker')
const merge = require('webpack-merge')

const myCssLoaderOptions = {
  modules: true,
  sourceMap: true,
  localIdentName: '[name]__[local]--[hash:base64:5]'
}

const CSSLoader = environment.loaders.get('style').use.find(el => el.loader === 'css-loader')

CSSLoader.options = merge(CSSLoader.options, myCssLoaderOptions)

module.exports = environment

But having those settings after upgrading Webpacker is causing this error:

/Users/me/Documents/my-app/node_modules/@rails/webpacker/package/config_types/config_list.js:55
    if (shouldThrow && index < 0) throw new Error(`Item ${key} not found`)
                                  ^

So I tried the example outlined in the Changelog:

const sassLoader = environment.loaders.get('sass')
const cssLoader = sassLoader.use.find(loader => loader.loader === 'css-loader')

cssLoader.options = Object.assign(cssLoader.options, {
  modules: true,
  localIdentName: '[path][name]__[local]--[hash:base64:5]'
})

The error goes away, but I'm not sure those settings are being applied, because now I'm getting an error about CSS comments:

ERROR in ./app/javascript/packs/Footer.css
Module build failed: ModuleBuildError: Module build failed: Syntax Error

(26:1) Unknown word

  24 | // @include bp-small {
  25 | // 	padding: 40px 20px 20px;
> 26 | // }
     | ^

And error message about local/global scope for css modules:

ERROR in ./node_modules/css-loader?{"minimize":false,"sourceMap":true,"importLoaders":2}!./node_modules/postcss-loader/lib?{"sourceMap":true,"config":{"path":"/Users/me/Documents/my-app/.postcssrc.yml"}}!./app/javascript/packs/link-editor/Durations.css
Module build failed: Error: composition is only allowed when selector is single :local class name not in ".descrText", ".descrText" is weird
    at /Users/me/Documents/my-app/node_modules/postcss-modules-scope/lib/index.js:26:13
    at Array.map (<anonymous>)
    at getSingleLocalNamesForComposes (/Users/me/Documents/my-app/node_modules/postcss-modules-scope/lib/index.js:20:26)
    at /Users/me/Documents/my-app/node_modules/postcss-modules-scope/lib/index.js:106:26
    at /Users/me/Documents/my-app/node_modules/postcss/lib/container.js:198:28
    at /Users/me/Documents/my-app/node_modules/postcss/lib/container.js:148:26
    at Rule.each (/Users/me/Documents/my-app/node_modules/postcss/lib/container.js:114:22)
    at Rule.walk (/Users/me/Documents/my-app/node_modules/postcss/lib/container.js:147:21)
    at Rule.walkDecls (/Users/me/Documents/my-app/node_modules/postcss/lib/container.js:196:25)
    at /Users/me/Documents/my-app/node_modules/postcss-modules-scope/lib/index.js:105:12
@gauravtiwari
Copy link
Member

Footer.css isn't a sass file right? ERROR in ./app/javascript/packs/Footer.css Looks like you are including a mixin there.

@gauravtiwari
Copy link
Member

Ahh my bad, didn't notice that it's a comment

@gauravtiwari
Copy link
Member

Yes, so if you are using composes with css modules, you can't use composes with pseudoselectors or media queries or subclasses.

 Error: composition is only allowed when selector is single :local class name not in ".descrText", ".descrText" is weird

@gauravtiwari
Copy link
Member

Thanks for report. I can reproduce this locally, will push a fix 👍

@axhamre
Copy link
Author

axhamre commented Dec 12, 2017

Yes, removing parts where composes are used removes the error. And it's really not a big deal personally, but it's a bit weird as it worked fine before upgrading.

But the bigger issue is that I still can't getcss-loader to work. Deleting the options in config/webpack/environment.js (mentioned in the Changelog) removes the errors but CSS modules don't seem to be working no more. I guess this is what you had in mind when you said that you're pushing a fix. But anyway I'll post my complete code in config/webpack/environment.js (+ a new error message) to put all cards on the table:

const { environment } = require('@rails/webpacker')

const sassLoader = environment.loaders.get('sass')
const cssLoader = sassLoader.use.find(loader => loader.loader === 'css-loader')

cssLoader.options = Object.assign(cssLoader.options, {
  modules: true,
  localIdentName: '[path][name]__[local]--[hash:base64:5]'
})

module.exports = environment

Error:

/Users/me/Documents/my-app/config/webpack/environment.js:4
    const cssLoader = sassLoader.use.find(loader => loader.loader === 'css-loader')
                                 ^

TypeError: Cannot read property 'use' of undefined
    at Object.<anonymous> (/Users/me/Documents/my-app/config/webpack/environment.js:4:34)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/me/Documents/my-app/config/webpack/development.js:1:83)
    at Module._compile (module.js:635:30)

@gauravtiwari
Copy link
Member

Thanks @hundsim Sorry for the trouble. Will fix and make a new release.

Anyway,

/Users/me/Documents/my-app/config/webpack/environment.js:4
    const cssLoader = sassLoader.use.find(loader => loader.loader === 'css-loader')
                                 ^

TypeError: Cannot read property 'use' of undefined

Seems like you are still using an old version of @rails/webpacker

@axhamre
Copy link
Author

axhamre commented Dec 13, 2017

Hm, no I think I'm on the latest, yarn.lock has this:

"@rails/webpacker@^3.1.1":
  version "3.1.1"
  resolved "https://registry.yarnpkg.com/@rails/webpacker/-/webpacker-3.1.1.tgz#040766f1c130a0e71d9d84cf95b0eea32c76bfd3"
  ...

And btw, as always, it's me that have to thank you for your incredible work 🙏

@gauravtiwari
Copy link
Member

@hundsim Thank you 🙏

So, can you update me what issues are you having currently?

The CSS issue you pointed out, it seems like a bug with css loader:

Fails:

// hello.css

.container {
  max-width: 100%;
}

// good one issue


.world {
  max-width: 100%;
}

// see more

Works:

// hello.css

.container {
  max-width: 100%;
}

// good one issue


.world {
  max-width: 100%;
}

Still works:

// hello.css

.container {
  max-width: 100%;
}

//good one issue


.world {
  max-width: 100%;
}

/* see more */

which probably seems correct because for comments in CSS we use /* */ not //

@gauravtiwari gauravtiwari removed the bug label Dec 13, 2017
@gauravtiwari
Copy link
Member

Made an example here with css modules support: https://github.com/gauravtiwari/webpacker-3.1.1

@axhamre
Copy link
Author

axhamre commented Dec 13, 2017

OK, so this error finally vanished when I ran yarn without the postinstall below in package.json (that I inserted half a year ago thanks to this thread). I tried putting postinstall back and it still without errors 🙏

   "scripts": {
      "postinstall": "npm rebuild node-sass"
   }

So with the above applied and removing compose and changing type of comments at end of file there are no more errors. But there are no styles applied. I've concluded that it has to do with the file extensions. Up until Webpacker 3.0.2 I've been using .css on all styling files and still fully been able to use css-loader. How can I continue to use the extension.css? I actually suspect this is the root cause to the CSS errors I've reported in this thread.

In the changelog this is mentioned:

"Separate css and sass loader for easier configuration. style loader is now css loader, which resolves .css files and sass loader resolves .scss and .sass files."

I assume this touches on my problem, but I cannot wrap my head around how to configure so that I can work with .css files again (despite the adhering code example) 😓

@gauravtiwari
Copy link
Member

@hundsim Yep, that's true. If you want to use css modules in .css files, please enable css modules there:

const cssRule = environment.loaders.get('css')
const cssLoader = cssRule.use.find(loader => loader.loader === 'css-loader')

cssLoader.options = Object.assign(cssLoader.options, {
  modules: true,
  localIdentName: '[path][name]__[local]--[hash:base64:5]'
})

@gauravtiwari
Copy link
Member

The idea behind separation is that:

  1. Have global styles where you don't need css modules and use plain imports (import global.css)
  2. Component styles where you want css modules (import styles from './app.scss')

So, it's up to you which one you use for global styles and app styles.

@axhamre
Copy link
Author

axhamre commented Dec 13, 2017

That separation makes so much sense. And your code clarification was of course obvious..

The "only" thing that I'm still battling with is @import in css-files. Is there any way to get it to work as it did before 3.1?

I'm using relative @import at the top of a .css-file like this, mainly to import variables:

@import "../../variables";

@gauravtiwari
Copy link
Member

@import should work, since it should use postcss-import under the hood. Are you getting any errors?

@axhamre
Copy link
Author

axhamre commented Dec 14, 2017

No errors. At a second thought/check, SASS functionality doesn't seem to be applied at all. No nesting, no "Undefined variable:", not possible to apply SASS features in the same file etc.

So perhaps I misunderstood the css-loader settings in config/webpack/environment.js. If we set css in this line

const cssRule = environment.loaders.get('css')

then we can import styles into the js-file like so import styles from './MyComponent.css';

but there is no SASS functionality anymore as it was on Webpacker 3.0?

And if this assumption above is correct, then I assume that if we want the SASS functionality as before we have to do 2 things:

  1. const cssRule = environment.loaders.get('sass')
  2. rename all .css file extensions to .scss or .sass

Right?

@marshall-cho
Copy link

did you resolve this? we use sass functionality like nesting and mixins, but have all files in .css. and use :global to get global scope.

we want to upgrade, so if we convert all .css to .scss everything should work as before?

@axhamre
Copy link
Author

axhamre commented Dec 17, 2017

Yes, I can confirm that it works if you convert all .css files and references 👍

If you have hundreds of css-files like me, then this speeds things up:

brew install rename

cd app/javascript/packs

find . -name "*.css" -exec rename 's/\.css$/.scss/' '{}' \;

And then I did a "find and replace" in my editor for all .css references to those files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants