-
-
Notifications
You must be signed in to change notification settings - Fork 606
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
Clarify importLoaders documentation? #228
Comments
I'm new to Webpack as well and as I understand it, It does what is says on the tin:
Given the following CSS: /* File style.css */
@import "body.css";
body {
/*background: yellow;*/
font-size: 20px;
}
div {
display: flex;
}
/* File body.css */
$color: red;
body {
background: $color;
}
div {
color: white;
a {
color: green;
}
}
div {
display: flex;
} On a basic set up with using PostCSS the following would only apply PostCSS plugins to style.css, NOT the @imported body.css: module: {
loaders: [
{
test: /\.css$/,
loader: "style-loader!css-loader!postcss-loader"
}
]
},
postcss: function() {
return [autoprefixer, precss];
} To get autoprefixer (and precss) working on @imported CSS files we use importLoaders instead: module: {
loaders: [
{
test: /\.css$/,
loader: 'style!css?importLoaders=1!postcss'
}
]
},
postcss: function() {
return [autoprefixer, precss];
} I assume this has something to do with how Webpack loaders parse assets. You have to explicitly tell the loader to interpret @import directives. Why that isn't done by default or as an option in style-loader or css-loader I don't know - maybe there is a way of doing it that I am missing. |
Thanks @mummybot for the explanation. That helped me to get a bit better understanding. Any idea what the number after |
As far as I can tell it is simply to make sure that the value of importLoaders is true: module.exports = function getImportPrefix(loaderContext, query) {
if(query.importLoaders === false)
return "";
var importLoaders = parseInt(query.importLoaders, 10) || 0;
var loadersRequest = loaderContext.loaders.slice(
loaderContext.loaderIndex,
loaderContext.loaderIndex + 1 + importLoaders
).map(function(x) { return x.request; }).join("!");
return "-!" + loadersRequest + "!";
}; https://github.com/webpack/css-loader/blob/master/lib/getImportPrefix.js On an expanded note to my earlier reply, here is the webpackconfig.js I have currently assembled (based on the Webpack getting started example) which does the following:
var ExtractTextPlugin = require('extract-text-webpack-plugin'),
autoprefixer = require('autoprefixer'),
precss = require('precss');
module.exports = {
entry: [
"./entry.js",
],
output: {
path: __dirname,
filename: "bundle.js"
},
devtool: "source-map",
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap&modules&importLoaders=1!postcss-loader')
},
]
},
postcss: function() {
return [autoprefixer, precss];
},
plugins: [
// Set the name of the single CSS file here.
new ExtractTextPlugin('main.css', { allChunks: true })
]
}; |
Thanks for that @mummybot . Not sure that the number really comes down to true/false though. For now I just put |
My understanding is that the number specifies how many loaders after css-loader should be applied to imports. The README says:
If all you have is |
Thanks @randycoulman, your answer help me alot |
what if I want my @import files to use a different set of loaders? For example my project's CSS is postcss but I'm using a npm package with .less files |
@alisonailea Just have multiple loader sections in your webpack config which include/exclude the folders you want. |
{
test: /\.less$/,
loader: ExtractTextPlugin.extract(
'style' ,
'css?sourceMap&importLoaders=1!' +
'postcss-loader!' +
'less?sourceMap'
)
} I found that if I set importLoaders = 1, less-loader still work for @import file. In this case, |
I have to say that the order in which loaders are executed, and the language used here and in the docs is totally confusing.
Let's look at the order of chaining.
Now, tell me - which "after" are we talking about? From my understanding of the docs, and what's been said here, what people mean by "after" is the order when reading from left-to-right. So, "chain order" is right-to-left. |
Yeah, it's a bit confusing. What the docs are missing is another example, with an additional loader (sass-loader, less-loader, whatever), just so users can realize that they need to bump the number. |
I would have thought that importing would apply the same rules as the parent document. Ah well. |
@quantuminformation but maybe you don't want everything applied. Although, it would be a nice default 👍 but I'm not sure if current webpack API supports that. |
I read all the comment above. But still confused. module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'less-loader'
]
}
]
}
}; I tried with the recommended configuration. No matter what provided to importLoaders, import statements in less file are handled by less loader and make none difference. I am more confused. |
@yanghuabei what are you trying to achieve? Don't you want imported Less files to be handled by less-loader? |
it seems only have an effect on imported |
Fixed by #500 |
@codeboyim's comment did it for me. This is exactly what is missing in the docs. Explanation of
|
@guidobouman whoa, I had no idea it works that way… do you mind adding that to the docs? |
@silvenon I've updated my previous comment with my most recent learnings. ☝️ It's a tad bit simpler than you'd think. |
@guidobouman I think it's better to include |
@roymiloh That feels a bit weird to me, mixing css modules with SASS. Then you'd be better off using the full future CSS spec with just postCSS and it's plugins, and completely dropping anything like SASS, LESS or Stylus. |
I guess would be great to put a small real-life example of a |
@dvakatsiienko PR welcome |
The documentation is still strange. They show this: {
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2 // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
}
},
'postcss-loader',
'sass-loader'
]
} But when would you ever want to include |
@mnpenner Sass in this case already handles importing of It does make sense to let PostCSS run on imported |
original issue + PR: #21 |
I think sass-loader will resolve @import, there will be no @import. importLoaders only has effect on unresolved @imports, so value shuld be 0? |
It still doesn't make any sense. Also pipe syntax is catastrophe and should be deprecated immediately. |
The docs totally need clarification. This option is extremely confusing, especially when you use |
What here need clarify?
|
@evilebottnawi The value |
TLDR; if you use |
{
loader: "css-loader",
options: {
importLoaders: 0, // I think this can be realized by referencing @import './xxx.scss' in the css file
modules: {
exportGlobals: true,
localIdentName: "[path][name]__[local]--[hash:base64:5]",
namedExport: true,
exportLocalsConvention: "camelCaseOnly",
},
},
} webpack will throw an error, example: |
I tried to understand
importLoaders
from the readme but completely don't get it.Can anybody please give a better explanation of what
importLoaders
do?Thank you
Bernd
The text was updated successfully, but these errors were encountered: