I am using css-loader with modules enabled in my webpack.config. I am very much into locally scoped css, but wish to have the ability to turn off css-modules for certain stylesheets (e.g. bootstrap.css).
I am currently accomplishing this by bypassing the loader configuration as follows:
import '!style!css!path/to/external_library.css'
This will insert the stylesheet in a style tag in the head of my markup. This is all well and good, except the stylesheets are not extracted by the ExtractTextPlugin during my production builds.
Any thoughts on this?
Best,
Matt
I believe the intention is for the developer to use global: for classes that they want to expose.
Indeed, and you can wrap multiple selectors in a global: statement making it easy to do on a per-file basis.
What if you are importing css from an installed node module? Are we meant
to edit the source and check it in to version control?
On Thu, Jan 7, 2016 at 2:12 PM Jop de Klein [email protected]
wrote:
Indeed, and you can wrap multiple selectors in a global: statement making
it easy to do on a per-file basis.—
Reply to this email directly or view it on GitHub
https://github.com/webpack/css-loader/issues/193#issuecomment-169777270.
That is exactly a question I'm having to: We have a set of react components in our company which are not using css-modules. Right now it is not possible to use the components in a team which wants to use CSS-Modules because it breaks everything...
A better option may be to simply remove ?modules which will make everything global by default. Then you'll have to wrap your css-modules in local, but at least it's more explicit in a mixed codebase...
You can use different loaders for different CSS files. If you want to use CSS Modules alongside legacy global CSS, a useful technique I've seen in the wild is to name your CSS Modules files with .local.css, then target that pattern in your webpack config.
^
loaders: [{
exclude: /src\/style/,
include: /src/,
loader: 'style!css?module&importLoaders=2!postcss!sass',
test: /\.scss$/
}, {
include: /src\/style/,
loader: 'style!css?importLoaders=2!postcss!sass',
test: /\.scss$/
}]
Inside src/style I have @import '~foundation-sites/scss/foundation';. Not 100% confident on this solution, but I am assuming that all styles, located in src, will be local beyond some global setup in src/style.
@snaptopixel and @jopdeklein: am I right to assume global: refers to a flag in the webpack configuration? So, not something one can use in, e.g., the import 'style!css!path/to/external_library.css' statement?
Just for future reference, both of the following also work fine in an Angular 2 component, to not scope the result, like to allow it to affect <body> and all:
require('style!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss');
require('style!../../../node_modules/bootstrap/dist/css/bootstrap-reboot.css');
@mattmarcello Sorry I missed your question. If you're dealing with external files you should indeed be able to send them through a different set of loaders (via include/exclude) which don't use css modules, similar to chemoish' solution.
@avbentem We are referring to :global as described here: https://github.com/webpack/css-loader#local-scope, so just in the CSS itself (if you have control over it, otherwise see above). I am using SASS which allows you to nest selectors and turn on global mode for multiple selectors.
Funny you resurrected this @avbentem I was just working on a config for this... In my case, I have two loaders and use the convention @markdalgleish mentioned. The regex was a little tricky to get right but it saves you from having to worry about include/exclude.
With these loaders you can load scss|css files from all over the place and only files denoted .local.css|scss will get the module treatment.
var cssPrefix = 'css?-mergeRules&importLoaders=2';
var cssModulesPrefix = cssPrefix + '&modules&localIdentName=[local]-[hash:8]';
var cssPostfix = '!postcss!sass';
sassLoader = {
test: /^((?!\.local).)*\.s?css$/,
loader: base.extractSass.extract('style!raw', cssPrefix + cssPostfix)
},
sassModuleLoader = {
test: /\.local\.s?css$/,
loader: base.extractSass.extract('style!raw', cssModulesPrefix + cssPostfix)
}
We are referring to
global:as described here: https://github.com/webpack/css-loader#local-scope
So, that's :global, not global: :-)
Again just for future reference, for those like me who are trying to make Angular 2 not add scope to imported CSS: something like the following does NOT stop Angular 2 from scoping the result. (Yes, I know nobody claimed it would, and Angular 2's scoping seems to be unrelated here.)
// This does NOT stop Angular 2 from adding scope to the imported CSS, hence
// the CSS will not be applied to the document's <html> and <body> elements:
:global {
@import '../../../node_modules/bootstrap/scss/bootstrap-reboot.scss';
}
But any of the following would:
require('style!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss');
require('style!../../../node_modules/bootstrap/dist/css/bootstrap-reboot.css');
...or specific to Angular 2:
@Component({
selector: 'my-component',
styles: [require('style!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss')]
})
@avbentem - You can't use require in a component as it will fail aot.
You are also trying to pull globals into a component, defeating the purpose of the whole component thing and by extension, the frameworks architecture.
@jopdeklein
Indeed, and you can wrap multiple selectors in a global: statement making it easy to do on a per-file basis.
That doesn't seem to be the case.
:global {
.class1{}
.class2{}
}
class1 and class2 are processed as local
:global (
.class1{}
.class2{}
)
is illegal
:global(class1){}
:global(class2){}
is just an evil plot to make life as hard as possible
Most helpful comment
^
Inside
src/styleI have@import '~foundation-sites/scss/foundation';. Not 100% confident on this solution, but I am assuming that all styles, located insrc, will be local beyond some global setup insrc/style.