Struggling to develop a basic web app using material-components-vue alongside vue-cli and webpack, I encountered an issue with importing stylesheets from node_modules
without prefixing them with ~
.
After experimenting with various webpack/vue-cli configurations, I finally settled on configuring vue.config.js
to pass loader options.
This is how my vue.config.js
looks:
module.exports = {
css: {
loaderOptions: {
sass: {
includePaths: [
'./node_modules', //including node_modules path here
]
},
}
}
}
With this configuration in place, I expected to be able to import styles like so:
@import 'normalize/normalize'
(assuming there is a directory named normalize
within my node_modules
folder containing a file named normalize.scss
)
However, webpack throws an error stating that it cannot locate the module.
Interestingly, this version works:
@import '~normalize/normalize'
The challenge arises when dealing with third-party modules that contain their own @import
statements, resulting in webpack compilation failures.
EDIT 1:
In response to a query by @Styx:
Please share additional configurations
and
Show the output of vue inspect --rule scss, along with the entire file featuring this problematic import
Here is the content of my problematic file which is quite minimal:
<template>
<div id="app">
<m-button>Hello</m-button>
</div>
</template>
<script>
import Vue from 'vue'
import Button from 'material-components-vue/dist/button'
Vue.use(Button)
export default {
name: 'App',
components: {
}
</script>
<style lang="scss">
@import "~material-components-vue/dist/button/styles"; //this works
@import "material-components-vue/dist/button/styles"; //but this does not
</style>
The result from vue inspect --rule scss
can be viewed here
All other configurations are as per the defaults generated by vue init webpack <name>
EDIT 2: Step-by-step guide to reproduce this issue:
- Initialize a vue-webpack app:
vue init webpack .
- Choose Vue build: Runtime + Compiler (Default)
- Do not include Vue-router
- Select npm as the package manager
Install sass-loader:
npm i -D sass-loader node-sass
- Create a file named
vue.config.js
and add the following code:
module.exports = {
css: {
loaderOptions: {
sass: {
includePaths: [
'./node_modules', //adding node_modules path here
]
},
}
}
}
Next, install a module that includes scss/sass files (For instance, for
material-components-web
, runnpm i material-components-web
)Then, import a stylesheet from
node_modules
like so:
@import '@material/button/mdc-button'; //mdc-button is part of material-components-web
- Finally, launch the development server:
npm run dev
- An error will be thrown as follows:
ERROR Failed to compile with 1 errors 11:36:35 AM
error in ./src/App.vue
Module build failed:
@import '@material/button/mdc-button';
^
File to import not found or unreadable: @material/button/mdc-button.
in /home/maxim/projects/holiday.js/stackoverflow/src/App.vue (line 18, column 1)
@ ./node_modules/vue-style-loader!./node_modules/css-loader?{"sourceMap":true}!./node_modules/vue-loader/lib/style-compil
er?{"vue":true,"id":"data-v-7ba5bd90","scoped":false,"hasInlineConfig":false}!./node_modules/sass-loader/lib/loader.js?{"s
ourceMap":true}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue 4:14-359 13:3-17:5 14:22-367
@ ./src/App.vue
@ ./src/main.js
@ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js
Note that in the initial example, I attempted to import
material-components-vue/dist/foo/styles
, while in this case, I imported @material/foo
.