I started a new project with vue-cli and noticed what less styles in my components can't use resolve.alias from webpack.
To test that you can add style to hello component eg:
<style scoped lang="less">
@import "src/less/theme";
.hello {
color: @theme-primary;
}
</style>
I tried to add less to the resolve.extensions in build/webpack.base.conf.js like so:
resolve: {
extensions: ['', '.js', '.vue', '.less'],
alias: {
'src': path.resolve(__dirname, '../src')
}
},
But it isn't working for me.
Webpack error:
ERROR in ./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js?id=_v-94e51594&scoped=true!./~/less-loader!./~/vue-loader/lib/selector.js?type=style&index=0!./src/components/Hello.vue
Module build failed: Cannot resolve 'file' or 'directory' ./src/less/theme.less in /abs../path../to../project.../src/components
@ /abs../path../to../project.../src/components/Hello.vue (line 2, column 0)
near lines:
@import "src/less/theme";
@ ./~/vue-style-loader!./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js?id=_v-94e51594&scoped=true!./~/less-loader!./~/vue-loader/lib/selector.js?type=style&index=0!./src/components/Hello.vue 4:14-279 13:2-17:4 14:20-285
Add this to the array loaders inside build/webpack.base.conf.js:
{
test: /\.less$/,
loader: "less-loader"
},
Then npm install less-loader.
Thanks but didn't work for me:
ERROR in ./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js?id=_v-94e51594&scoped=true!./~/less-loader!./~/vue-loader/lib/selector.js?type=style&index=0!./src/components/Hello.vue
Module build failed: Cannot resolve 'file' or 'directory' ./src/less/theme.less in /project/src/components
@ /project/src/components/Hello.vue (line 2, column 0)
near lines:
@import "src/less/theme";
@ ./~/vue-style-loader!./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js?id=_v-94e51594&scoped=true!./~/less-loader!./~/vue-loader/lib/selector.js?type=style&index=0!./src/components/Hello.vue 4:14-279 13:2-17:4 14:20-285
Managed to reproduce the error. It actually turns out I only get it to work with scss, but not with less. I haven´t used less too much, so I don´t know weather the error could be due to less or not. This is the code I´m currently running.
Within Hello.vue:
<style lang="sass">
@import "src/styles/somefile";
.somestyle {
color: $somecolor;
}
</style>
Note: My somefile uses .scss extension, not .sass :)
I don´t know weather the following actually is necessary to add, but I´ve also added this to the loaders array within build/webpack.base.conf.js:
{
test: /\.sass$/,
loader: "sass-loader"
},
I´ve also installed sass-loader.
@b44rd I think in your case for LESS, you might have just needed @import '../src/less/theme.less (relative importing, rather than absolute from the project root). As for getting lang="scss" working and possibly some other issues, I believe #29 should fix a lot.
@chrisvfritz Yes, relative path works fine in both less and sass/scss. However, the issue is that the "src" alias doesn't work in less (as it do in sass/scss).
Glad to see that #29 specify a difference between sass and scss though! :)
Ah, interesting. This thread has some people reporting a similar issue. Do any of their proposed solutions work for you?
@chrisvfritz I didn't find really good solutions in that thread. Is it webpack problem? I see issue is closed...
@OEvgeny It's unclear. :confused: The problem seems to be specific to LESS - that much we know. The maintainers of less-loader are pretty sure it's not their problem (hence the issue being closed), some are saying it's an issue with Webpack, and some are saying fixing it requires special configuration in .babelrc. Then someone else said updating and configuring postcss was the way to fix it.
Either way, if you find something that works for you, please let us know! This is an odd situation, where the problem definitely isn't specific to this project, but it's not very clear _where_ the problem is originating. So while the LESS ecosystem is figuring it out, I think it makes sense to keep this issue open and then incorporate a patch once we find one.
In the meantime, would you mind renaming this issue based on our discussion? I'm thinking something like LESS imports not respecting Webpack resolve alias.
@chrisvfritz thanks, got it!
I have a similar issue and got it solved by explicitly adding the .less extension to my alias, like this:
alias = { 'uikit.less': '/path/to/uikit/index.less'}
Then I can import my library in my other less files like this:
@import '~uikit';
I wish there'd be a better way but for now that worked well for me.
Thanks @mbensch! @OEvgeny, can you confirm whether that solution works for you?
Having the same issue here. Did anyone ever figure out the solution?
I am having the same issue
`This dependency was not found:
To install it, you can run: npm install --save !!vue-style-loader!css-loader?{"minimize":false,"sourceMap":false}!../../node_modules/vue-loader/lib/style-rewriter?{"id":"data-v-7074dcac","scoped":false,"hasInlineConfig":false}!less-loader?{"sourceMap":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./section02.vue`
If your project is from vue-cli.
Run:
npm install --save-dev less less-loader
And and add this code in your xxx.vue
Having the same issue as well, I think the problem is that in import, less loader prepends import paths with ./ so if we had an alias src and @import src/.../style.less then the error would always be something along the lines of cannot resolve './src/.../style.less'. Perhaps if it tries to resolve src/.../style.less it would work? Just an idea if anyone more familiar with the source can see if this might be an issue.
@dogbot @al3x-huang, so it looks like in order to remove the ./ (which turned out to be the problem for me) from the path in the .less file's @import statement you add _only_ the ~ to the beginning of the path.
In my case my original @import was:
@import 'src/App/asset/incl/global/variable.less';
& the import statement that wound up working was:
@import '~src/App/asset/incl/global/variable';
that was all I had to do in the end.
Hope that helps, cheers.
@davieghost Thanks. This should be made more explicit in the documentation (specifically using aliases since the doc only suggest this to import from node_modules). Also suggesting that "The less-loader applies a Less plugin that passes all queries to the webpack resolver" makes me think that I shouldn't need the ~ to make imports behave as expected.
@al3x-huang, no problem at all. I fully agree, all fronts i see no benefit for the use of a ~ to remove non-standard behavior, it just stands to confuse folks
@davieghost Thanks! do work for me
this is my code
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@src': resolve('src'),
'@assets': resolve('src/assets'),
'@components': resolve('src/components'),
'@views': resolve('src/views'),
'@styles': resolve('src/styles')
}
<style lang="less" scoped>
@import "~@styles/mixin.less";
</style>
@al3x-huang I agree I don't think its standard/expected webpack to have to add the ~ in-front of your alias, doesn't that normally indicate to the css-loader you are loading from a node package? @chrisvfritz Should we open an issue to update the documentation with this workaround somewhere so people don't need to google this github issue for the solution? Or should the loader recognize all the aliases without the ~? I think a global sass/scss/less import is a very common use case. It seems like this issue isn't really resolved, there is just a good work around.
similar issue here (import node_modules less file)
my solution:
npm install --save-dev less less-loader (https://github.com/vuejs-templates/webpack/issues/25#issuecomment-288287910)// vue-loader options
...
loaders: {
less: 'vue-style-loader!css-loader?sourceMap!less-loader?sourceMap'
}
~ prefix (https://github.com/vuejs-templates/webpack/issues/25#issuecomment-293128337, https://github.com/webpack/webpack/issues/1789#issuecomment-277024235)<style scoped lang="less">
@import "~spectre.css/src/variables.less";
@import "~spectre.css/src/timelines.less";
</style>
Similar issue
resolve:{
alias:{
"boooya": path.resolve(__dirname, 'app/Resources/public/boooya')
}
}
In less file i have to use ~boooya.
My problem is that i'm using theme with hundreds of files that imports each other by using relative paths and the only way to manage that is using aliases (i could to add it in _css-loader alias options_).
Folder structure
+ app/Resources/public/boooya/
+ css/
+ components/
- app-heading.less
- styles.less
+ img/
- bg.png
// app/Resources/public/boooya/css/styles.less
@import "components/app-heading.less"
// app/Resources/public/boooya/css/components/app-heading.less
background: url(../img/bg.png) top left no-repeat
So i can compile webpack only by defining aliases for ../img that resolve to app/Resources/public/boooya/img
But how can i do that?
You can see less-loader,it work fine for me.
Just prepend them with a ~ which tells webpack to look up the modules.
I'm sure i'm late to the party, but this thread helped me solve this exact problem. For anyone else that may come across this, just throwing my solution out there in case it helps...
@import '~@/assets/less/editor.less';
which resolves to {root}/src/assets/less/editor.less.
Using just @ (which is aliased in my webpack) wasn't sufficient. It's only when i prefixed the tilde that it worked. Might be a bit dirty, but it beats having to use relative paths.
it works for me, thanks for saving my time!!!!!!!!!! @hybridwebdev
I'm sure i'm late to the party, but this thread helped me solve this exact problem. For anyone else that may come across this, just throwing my solution out there in case it helps...
@import '~@/assets/less/editor.less';
which resolves to {root}/src/assets/less/editor.less.Using just @ (which is aliased in my webpack) wasn't sufficient. It's only when i prefixed the tilde that it worked. Might be a bit dirty, but it beats having to use relative paths.
Excellent!
@hybridwebdev thanks! it works!
@chrisvfritz I think this is still an issue because people are still coming here for a "workaround". It's not particularly intuitive on how to resolve when you first start a project and it's not well documented. Something should be changed.
@import "~@/..."
It works for me.
add "~" in front of "@".
Yes, ~ works, but if you must use ~, then it should be documented in the main vuejs docs.
I'm using shared less files across projects. In one project I refer to the imports as import "twitter-bootstrap/..." and in the other project I refer to the import as import "../../node_modules/twitter/...".
Essentially I'd like to share the less files across the 2 projects and thus create an alias in my
Webpack config that means I can alias twitter-bootstrap to ~/twitter/.
Unfortunately the alias is not respected and the path resolver looks for the file relative to the file with import statement in.
Is there no way to get Webpack alias working with less-loader imports? One of the points of aliasing is to not have to prepend ~ to every import!
My config didn't seem to take webpack.config.js into account. I hade to set my alias into a new vue.config.js at the root of the project.
├── src/
│ ├── assets/
│ ├── components/
│ ├── js/
│ └── style/ // Where my .less files are
│ └── main.less
│ ├── views/
│ ├── main.js
│ └── App.vue
├── vue.config.js // Where I set my alias
└── webpack.config.js // Useless in my case
My @import is like @import "~Style/main"; the ~ is still necessary to tell that it's an absolute path!
My vue.config.js is like this :
const path = require('path');
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('Style', path.resolve(__dirname, 'src/style/'));
}
}
Hope it helps :smiley:
Most helpful comment
@dogbot @al3x-huang, so it looks like in order to remove the
./(which turned out to be the problem for me) from the path in the.lessfile's@importstatement you add _only_ the~to the beginning of the path.In my case my original
@importwas:& the import statement that wound up working was:
that was all I had to do in the end.
Hope that helps, cheers.