Hi guys.
I got issue and it's driving me nuts. Please help me with that.
I am trying to integrate Google's material-components-web with Nuxt and got issue with importing SCSS.
The thing is, they for some reason using this kind of path @import '@material/checkbox';
everywhere in node_modules components files, and default Nuxt Webpack settings obviously can''t resolve that. https://github.com/material-components/material-components-web#css
To fix it I need to include node_modules
in Sass include path. And I can't set it to work. This kind of code is not working:
extend (config, ctx) {
if (ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
}, {
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, '../node_modules')]
}
})
}
}
}
Found some answers here, but still got an error - https://github.com/nuxt/nuxt.js/issues/772
I guess I need to extend config not only for sass-loader?
Mh, you actually don't need to include node_modules.
Try @import "~@material/checkbox.scss";
Are you trying to import it in a vue component or a seperate scss file?
@apertureless I tried that. The thing is, that files in @material has a lot of import who also using this path. I am trying that from .vue file.
@apertureless and yes, I need to include node_modules. This is very strange library, I don't know what creaters had in mind when they did that.
Hm thats interesting. For me the sass-loader is working without any additional configuration. And I can import external scss files without problems. Which are for example scoped with the @
:thinking:
Which version of nuxt are you using?
@apertureless this is what I have if I am not using includePaths and just @import "~@material/checkbox.scss";
Module build failed:
@import "@material/animation/functions";
^
File to import not found or unreadable: @material/animation/functions.
Parent style sheet: /home/dedde/TESTING/mdc-nuxt/node_modules/@material/checkbox/mdc-checkbox.scss
in /home/dedde/TESTING/mdc-nuxt/node_modules/@material/checkbox/mdc-checkbox.scss (line 17, column 1)
@apertureless are we talking about same mdc library? I suggest you to try it first - it will not work.
I am using last version of Nuxt.
@jerakode nah I am not using mdc, but other scss libs which are scoped with @.
I will check if I can get mdc running
I have no issues with external scss files! It just this awful library paths. I dodn't know why they did that. I am struggling for 3 days with this bullshit. Hate Google.
Well with external scss files I mean scss files whcih are installed over npm in packages. The library paths are that way, because they scoped them on npm with an organisation. If you create an orga and publish packages in there, they are scoped with @organame/packagename
I guess they did it, so multiple developers can publish packages under the @material
handle. ;)
The problem however is, as far as I see that they reference inside their scss files the scoped files.
Have you tried to edit the config according to https://github.com/material-components/material-components-web/issues/351 ?
const path = require('path');
const glob = require('glob');
{ loader: 'sass-loader',
options: {
sourceMap: true,
// mdc-web doesn't use sass-loader's normal syntax for imports
// across modules, so we add all module directories containing
// mdc-web components to the Sass include path
// https://github.com/material-components/material-components-web/issues/351
includePaths: glob.sync(
path.join(__dirname, '**/node_modules/@material')
).map((dir) => path.dirname(dir)),
},
},
@apertureless sorry, went out.
My config is
extend (config) {
const vueLoader = config.module.rules.find((rule) => rule.loader === 'vue-loader')
vueLoader.query.loaders.scss = 'vue-style-loader!css-loader!sass-loader?' + JSON.stringify({ includePaths: [path.resolve(__dirname), 'node_modules'] })
}
If I add '**/node_modules/@material'
it will broke my entire Nuxt config, right? Nonsense.
Hi @jerakode & @apertureless
Here a working demo of nuxt.js with Material Design: https://material-nuxt.glitch.me/
Configuration: https://glitch.com/edit/#!/material-nuxt?path=nuxt.config.js:1:13
I took the solution from https://github.com/material-components/material-components-web/issues/351#issuecomment-298796798
I recommend to use https://vuetifyjs.com/ for Material Design with Nuxt.js, it's a great library.
@Atinux hi, thanks for you time, but unfortunately this not a solution, since your code are using CSS-only version of MDC (as far as I can see)! I need JS-version. They are not the same. So something 100% broken here.
Vuetify is nice, but it's monolithe framework which is not acceptable for me at certain cases. I need components. So if there's a chance to integrate Google's MDC, it would be perfect.
And issue remains unsolved :cry:
Yes, I checked, this is CSS version.
Notice how checkbox is working - https://glitch.com/edit/#!/bitter-catsup?
Here's with JS - https://material-components-web.appspot.com/checkbox.html
Notice there's not ripple effect on button. No JS is working.
What a awful integration mdc has. And this is Google. Unbelievable.
Here is my solution that loops through all loaders and allows for more fine-grained filtering based on loader type. For example, to add includePaths
to sass / scss:
const util = require('util')
module.exports = {
build: {
extend(config, ctx) {
const vueLoader = config.module.rules.find(
({loader}) => loader === 'vue-loader')
const { options: {loaders} } = vueLoader || { options: {} }
if (loaders) {
for (const loader of Object.values(loaders)) {
changeLoaderOptions(Array.isArray(loader) ? loader : [loader])
}
}
config.module.rules.forEach(rule => changeLoaderOptions(rule.use))
// console.log(util.inspect(config.module.rules, { depth: 6 }))
}
}
}
function changeLoaderOptions(loaders) {
if (loaders) {
for (const loader of loaders) {
if (loader.loader === 'sass-loader') {
Object.assign(loader.options, {
includePaths: ['./styles'],
data: '@import "_imports";'
})
}
}
}
}
@lehni where to put changeLoaderOptions?
@iamdubx you can just put it underneath the module.exports = {}
block in nuxt.config.js
@lehni I can't get this to work. Could you help a bit ? Im using https://github.com/nuxt-community/adonuxt-template
Im trying to use bulma variables (colors) in single file templates.
nuxt.js (nuxt.config.js)
function changeLoaderOptions (loaders) {
if (loaders) {
for (const loader of loaders) {
if (loader.loader === 'sass-loader') {
Object.assign(loader.options, {
includePaths: ['~/assets/scss'],
data: '@import "_variables.scss";'
})
}
}
}
}
Folder structure
assets
scss
main.scss
_variables.scss
_variables.css
// Import bulma variables
@import "~bulma/sass/utilities/initial-variables";
// Override bulma variables here !
@alanaasmaa is resources a folder as well? Looks like you'll have to include that as '~resources/assets/scss'
~/ is an alias to resource folder
This won't work anymore because the code changed.
{ test: /\.sass$/, use: this.styleLoader('sass', {loader: 'sass-loader', options: { indentedSyntax: true }}) },
{ test: /\.scss$/, use: this.styleLoader('scss', 'sass-loader') },
You need to follow the structure there to be able to override this.
The problem is with NUXT, because it doesn't expose this things in a better way for the nuxt config to change them.
Hello,
I do have the same problem with the last version of Nuxt #1901.
I did not find a way to make it works for now.
Matthieu
The approach I've outlined above still works for me with v1.0.0-rc11. Here a version that supports both Sass and Stylus:
module.exports = {
build: {
extractCSS: true,
extend(config, ctx) {
const vueLoader = config.module.rules.find(
({loader}) => loader === 'vue-loader')
const { options: {loaders} } = vueLoader || { options: {} }
for (const loader of Object.values(loaders || {})) {
changeLoaderOptions(Array.isArray(loader) ? loader : [loader])
}
for (const rule of config.module.rules) {
changeLoaderOptions(rule.use)
}
// console.log(util.inspect(config.module.rules, { depth: 6 }))
}
}
}
function changeLoaderOptions(loaders) {
for (const loader of loaders || []) {
let options
switch (loader.loader) {
case 'sass-loader':
options = {
includePaths: ['./styles'],
data: '@import "_imports";'
}
break
case 'stylus-loader':
options = {
paths: [path.resolve('./styles')],
import: ['_imports']
}
break
}
if (options) {
Object.assign(loader.options, options)
}
}
}
Try nuxt-sass-resources-loader :heart:
I have actually coded almost the same code into my config.js but i might
try this approach also. Thanks for the tip.
On Sun, Mar 4, 2018, 00:28 Antério Vieira notifications@github.com wrote:
Try nuxt-sass-resources-loader
https://github.com/anteriovieira/nuxt-sass-resources-loader—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nuxt/nuxt.js/issues/864#issuecomment-370184948, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AMMicds38qgahUmU1-GSpu1-aXPjI6mpks5taxj7gaJpZM4N0i_t
.>
Alan Aasmaa
[email protected]
+358 44 359 5642
Vuetify is nice, but it's monolithe framework which is not acceptable for me at certain cases. I need components. So if there's a chance to integrate Google's MDC, it would be perfect.
This is an old comment but for anyone reading this as of 10/2018...
You can pull in the components you need with Vuetify (A la cart) and now they have a shaker that will remove what you don't use.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
The approach I've outlined above still works for me with v1.0.0-rc11. Here a version that supports both Sass and Stylus: