Closed ravipatipushkar closed 4 years ago
I can confirm this is a problem. I am running into the exact same issue.
I'm encountering this problem too, particularly when trying to import the .less
flag library from the node_module https://github.com/lipis/flag-icon-css
In my less file for that module
@import "~flag-icon-css/less/flag-icon.less";
This resolves fine, and webpack starts importing this file. The problem is then within the flag node package, the relative paths to the individual flag svg files ../flags/1x1/es.svg
look like they're being resolved relative to starting point of the less import into webpack, i.e. styles/app.less
and not relative to the node_modules
package.
The error, excuse all the loaders...
ERROR in ./~/css-loader?sourceMap!./~/postcss-loader!./~/csslint-loader!./~/less-loader?sourceMap!./app/styles/profiler.less
Module not found: Error: Cannot resolve 'file' or 'directory' ../flags/1x1/vg.svg in /app/styles
@ ./~/css-loader?sourceMap!./~/postcss-loader!./~/csslint-loader!./~/less-loader?sourceMap!./app/styles/app.less 6:116980-117010
This looks like the relativeUrls
option is not applied. The less-loader usually applies it automatically, thus it should work out of the box. Could you remove the relativeUrls
option in your loader config and see if it works?
@jhnns Tried with relativeUrls
true or false, same issue. This seems related to the way the file manager provided by the dynamically injected less plugin uses the shared context from less-loader
to resolve paths for url() references within all nested files. I'm not familiar enough with Webpack's internals to know how to split this out.
Is there a way to re-apply less-loader
to each new less file encountered?
We need a small test-case that demonstrates this specific bug. We do have tests that this feature works under "normal" circumstances (I'm using the less-loader also in production and it works)
@jhnns Yes, I have used less-loader many times without issue. I ran into this when (intentionally) attempting to apply less-loader
to modules in node_modules
. In particular, it happened when using namespaced NPM module names (@foo/bar
).
That being said, I was actually able to fix my issue by simply dropping the relative filepath altogether. It still bundles the font properly via webpack, but seems to circumvent the path normalization based on original filename somehow.
src: url('./icons/foo.woff') format('woff');
src: url('/icons/foo.woff') format('woff');
I ran into this issue because the way I set up my webpack.config.js file - the paths were getting a mixture of forward and backwards slashes (context: __dirname + '/src/main/jsx').
Changed to use path.join and path.normalize
context: path.join(dirname, '/src/main/jsx'), ... output: { path: dirname, filename: path.normalize('/src/main/webapp/js/app.js') }, ... new ExtractTextPlugin(path.normalize('src/main/webapp/css/app.css'))
This stopped errors but no files were generated so also had to update to node 4.4.4
I had a similar issue and solved it in a hackish way:
http://stackoverflow.com/a/37293335/1874624
edit: updated my solution
I found the problem. Since most less and scss files are stuck in other directories than where they build to, the css parser gets confused. I added an attribute to the css loader named rel
to specify where the file would built to.
Here is the modified loader: https://github.com/SplicePHP/css-loader
Example usage:
module: {
loaders: [ //default less loader
{
test: /\.less$/,
loader: ["style-loader", "css-loader","less-loader"],
exclude: [ //exclude package in order not to get loaded via this loader
/\package\/less\/style.less$/
]
},
{ //created custom loader to fix wrong rel path issue
test: /\package\/less\/style.less$/,
loader: [
"style-loader",
"css-loader?rel="+path.resolve(__dirname,'path/to/package/dist/css'),
"less-loader"
]
}
]
}
I am not 100% sure that the regex is best practice for detecting relative urls, just pulled it from stack overflow. Works as far as I have tested. I tried to submit a pull request but I don't think it got through. If I don't hear anything by tomorrow I will resubmit the pull request to the css-loader git repo.
Not sure if I will be maintaining this fork, depends if another solution is found.
Sorry guys, this feature is working under "normal" (=expected) circumstances. Please give us a minimal example so we can investigate this.
Hi, here is an example repo that results in build errors: https://github.com/almasaeed2010/AdminLTE.git
npm:
npm install admin-lte --save-dev
entry.js
require('admin-lte/build/less/AdminLTE.less');
Webpack Config [I trimmed a lot of code out of my webpack config but here is the relevant code to illustrate the problem: have not tested this but I think you should get the idea. ]
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: path.resolve(__dirname, "entry.js"),
context: path.resolve(__dirname),
output:
{
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
chunkFilename: "[name]_[chunkhash:20].js",
sourceMapFilename: "[name].map"
},
module:
{
loaders: [
{
test: /\.js$/,
loader: "babel-loader",
query:
{
presets: ['es2015', 'react', 'stage-0']
}
},
{
test: /\.css$/,
loader: ["style-loader", "css-loader"]
},
{
test: /\.less$/,
loader: ["style-loader", "css-loader", "less-loader"],
exclude: [
// /\less\/AdminLTE.less$/
]
},
// {
// test: /\less\/AdminLTE.less$/,
// loader: [
// "style-loader",
// "css-loader?rel="+path.resolve(__dirname,'node_modules/admin-lte/dist/css'),
// "less-loader"
// ]
// },
{
/*
* embed images and fonts smaller than 5kb
* 'image-webpack-loader?optimizationLevel=7&..........'
*/
test: /\.(gif|png|jpg|jpeg|svg)($|\?)/,
loaders: ['url?limit=5000&hash=sha512&digest=hex&size=16&name=resources/[name]-[hash].[ext]']
},
{
test: /\.(woff|woff2|eot|ttf)($|\?)/,
loaders: ['url?limit=5000&hash=sha512&digest=hex&size=16&name=resources/[name]-[hash].[ext]']
}
]
}
};
I commented out the code I currently use to fix the issue.
So this is what happens:
You include the less file from the admin-lte/build/less/ dir.
When it hits the css loader it thinks it is in admin-lte/build/less/ and can't find relative resources.
All the resources lay inside the admin-lte/dist/ dir.
The less file is supposed to built to admin-lte/dist/css/
Now any resources required like: url(../img/someimage.jpg) will try to load admin-lte/build
/img/someimage.jpg instead of admin-lte/dist
/img/someimage.jpg
The solution I propose is to make allowance for the build output dir to be specified in some way in order for the relative paths to load correctly in these cases.
I used the rel keyword in my example.
You can see an example of my hacked css-loader in the link supplied in the previous post.
Thanks.
Thanks for providing an example @SplicePHP
Your assumptions are correct, but this is the expected behavior. The less-loader generates a single css file from multiple less files. That's why the css-loader tries to resolve all urls relatively from the less entry file.
When using webpack, it's best to put your binary assets like images and fonts inside your app
or src
or build
folder (whatever you call it). Then you just reference them in your less file relatively like you would with any other JS import/require and things will work as expected. So, you don't need any path variable in your less files, because if you reference them relatively, things will just work.
The problem is that most people are not in control of those variables. I am working on a pretty large project with a ton of node_modules and other git libraries. The standard is for less and scss files to be stored in another path to where the actual build is rendered to. Making these types of changes on third party libraries will be a nightmare for version control. I would have to fork nearly every git repo I use to modify the paths and I am not even sure that version control can be maintained with npm packages if these types of changes are made locally. This is a serious impediment for maintainability as far as I can tell, Stack Overflow is full of these bugs and no-one seems to have any answers. It is much easier to add a rel path variable to the css loader and no hacking of third party libraries is required. Making this small change fixes the problem and no backward compatibility is sacrificed. I will continue to use my custom css loader for now and will let you know if I find any bugs with my current implementation.
Definitely a problem - We have to link our styles into one big lump from various sources, including some @ node_modules
. However, we're running into a problem where (understandably) all the node_modules
styles are trying to link to files within their own directories, resulting in a ton of errors and a failed compilation. It boggles me how with gulp-less
everything just works, whereas trying to go with a pure webpack 2.0 -route with less-loader
all we get are a ton of cryptic error messages .
Just recognized that @SplicePHP has received a lot of upvotes. I'm not sure if I understand the use-case correctly – and maybe there are different expectations here.
If you don't agree with the current behavior, you can simply overwrite that by passing the relativeUrls: false
option to the less-loader. If you don't want the css-loader to resolve urls, you can disable that.
If you don't want all of that behavior, it is still legitimate to just compile Less without touching webpack at all. All that URL resolving behavior makes sense if you want to treat every file as a single module, but if you don't want that, don't use webpack for your styles. It's ok to use webpack for JS only and handle CSS with a different tool. Webpack and gulp/grunt/npm-scripts are not the same, they serve slightly different purposes.
Relative urls has no effect when using programtically, I tried less.render(raw, { javascriptEnabled: true, relativeUrls: true })
but it still imports from root of the module
The situation is: there is less in one directory with imports relative to that directory, and less in a second directory with imports relative to that directory. The less in the second directory imports the less in the first directory.
gulp-less
handles this with no problem. When I use webpack with less-loader
, this is no longer handled. I tried adding the relativeUrls: false
option, as well as relativeUrls: true
. Neither of those make this situation work.
I haven't got it to a state where I can test that it's totally working, but after adding { url: false }
to css-loader
with { relativeUrls: false }
it does compile.
@sberney's solution works for @lipis's flag-icon-css but then breaks for zavoloklom's material-design-iconic-font
Using url loader doesnt help either, so how should I solve this?
Fixed in master.
PS: To using properly flag-icon-css
package, you must redefine @flag-icon-css-path
variable:
@import "~flag-icon-css/less/flag-icon.less";
@flag-icon-css-path: '~flag-icon-css/flags';
I am getting the below error when trying to use the less loader with webpack to compile my less files.
Following is my directory structure
Following are the contents of app.js
require('./styles/app.less');
app.less
fontImports.less
I am using the below webpack config
In fontImports.less, If I provide relative path of the font form fontImports.less, webpack command is failing with the below error.
If I provide the relative path from app.less, I am getting the expected result. Do I have to include any specific configuration to make the above work ?
You can repro this issue using the sample here