In-repo-addon css files in 'my-addon/addon/styles' should not be processed
My app has an in-repo-addon and this addon has the following CSS file in lib/my-addon/addon/styles/foo.css:
/* lib/my-addon/addon/styles/foo.css */
.red {
color: red;
}
Ember-cli automatically merges these CSS files into vendor.css and my app can use the CSS classes. So the following template would render the text in red:
{{!-- app/templates/application.hbs --}}
<span class="red">I am red because the .red class is provided by my-addon</span>
But if I want to use ember-css-modules for the addon's components, lib/my-addon/addon/styles/foo.css seems to be processed and vendor.css will look like:
/* dist/assets/vendor.css */
.red_1yx9rc {
color: red;
}
and obviously, the <span class="red"> won't be red anymore.
Is there a config that I am missing here or is this a limitation of ember-css-modules?
Hi @bartocc, sorry for the long silence here!
The short answer is that ECM intentionally doesn't treat the styles directory of an app or addon as special, since if you're using the classic (i.e. non-pods) project layout, that's where all the styles for your components and route templates go.
Fortunately there are a few different ways you can accomplish what I think you're describing. The last one in the list is what we tend to do in all our own internal addons and applications, and we design the classes to be consumed that way.
Explicitly make the .red class global
In lib/my-addon/addon/styles/foo.css, you can write this to avoid having the class name be rewritten:
:global(.red) {
color: red;
}
Or, if you're using e.g. the postcss-nested plugin, you can put any number of global classes in a block:
:global {
.red { /*...*/ }
.green { /*...*/ }
.blue { /*...*/ }
}
Configure a custom extension for modules
One approach some folks have had success with, especially when migrating from global CSS to CSS Modules, is to make the name rewriting opt-in by configuring a custom extension:
cssModules: {
extension: ['module.css']
}
With config like ☝️, only files named foo.module.css will be treated as isolated modules, and anything ending in plain .css will still be global.
Reference the local class from your app
Instead of forcing the class to be global, another option is to update your template to indicate where the class you're trying to use comes from:
<span class={{local-class "red" from="my-addon/styles/foo"}}>
I am red because the .red class is provided by my-addon
</span>
Compose the addon class from an app class
This is generally how we manage these sorts of utility classes in all our internal addons and applications.
/* app/styles/application.css */
.my-block-of-text {
composes: red from 'my-addon/styles/foo';
composes: padding-large centered from 'my-addon/styles/layout';
/* additional custom styles here */
}
{{! app/templates/application.hbs }}
<span local-class="my-block-of-text">
I am red because the .red class is provided by my-addon
</span>
Hi @dfreeman. Have recently needed to achieve the issue referred to here and felt the solution you offerred would work perfectly in my case. Here is my configuration:
cssModules: {
intermediateOutputPath: 'app/styles/_module.scss',
extension: ['module.scss'],
}
I have the following folder structure:
app
>> styles
>>>> app.scss
>>>> ember-paper.global.scss // this has global styles
>>>> transport.module.scss //this has local styles
Now app.scss imports the following at the top:
@import 'ember-paper.global';
@import 'module'; //I assume this pulls in 'transport.module.scss' transformed/localized by ECM
ember-paper uses ember-cli-sass extensively, so I went ahead and set up ECM to use ember-css-modules-sass.
As expected, the styles within ember-paper.global.scss are passed through to the dist/assets/app-name.css file with the above configuration. However, the styles within transport.module.scss file do not appear in the dist/assets/app-name.css.
What I want is for the Ember Paper styles within transport.module.scss to be transformed/localized by ECM, passed-through and concatenated with the ember-paper.global.scss in dist/assets/app-name.css`?
Could I be missing something?
Let me know and thanks for your help.
Have racked my brain over this for two whole days and have finally found the solution. It turns out this library is much more powerful than we give it credit for especially because of the use of the PostCSS engine and plugin ecosystem.
The culprit was the installation of the ember-css-modules-sass and incomplete configuration setup. On removal and slight modification of the cssModules configuration to the following:
cssModules: {
plugins: {
before: [
require('postcss-nested')
]
},
intermediateOutputPath: 'app/styles/_module.scss',
extension: 'module.scss',
postcssOptions: {
syntax: require('postcss-scss')
}
}
The problem was resolved with much more capabilities than expected. I was able to not only transform the files with the module.scss extension and pass through all the other scss files but also to use the global scope identifiers :global within the module.scss files to put a few selectors in the global scope during transformations.
I can now selectively migrate my global scope code into local scope over time.
Thanks team for this library.