How can I use CSS Modules from my main global scss stylesheet? - vue.js

I need to extend the CSS Loader for Nuxt.js so I can use modules within my global .scss files in assets/scss/screen.scss.
This is taken from the Vue.js site.
// webpack.config.js
{
module: {
rules: [
// ... other rules omitted
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// enable CSS Modules
modules: true,
// customize generated class names
localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
Problem is I don't know where to put this in my Nuxt.config.js for what I have tried fails.
If I place here:
build: {
extend(...){
config.module.rules.push({
test: /\.scss$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// enable CSS Modules
modules: true,
// customize generated class names
localIdentName: '[local]--[hash:base64:8]'
}
}
]
});
}
}
It throws
Error: Cannot read property 'forEach' of undefined at at node_modules\#nuxtjs\style-resources\lib\module.js:88:18
I am confused because I am already extending it successfully in my nuxt.config.js to allow for CSS modules INSIDE of each component.
loaders: {
cssModules: {
modules: {
localIdentName: process.env.NODE_ENV === "production"
? "[hash:base64:6]"
: "[local]--[hash:base64:6]"
}
}
},
But I can't call a CSS class as a module from my main 'global' stylesheet. No error, it just can't find it.
/assets/scss/screen.scss
.triangle{
background:red;
}
Can't be linked-to in my Nuxt file as
<div :class="$style.triangle"></div>
Just like it can if I add the CSS directly within my module. I wonder why I can't access CSS Modules this way? But I can if it's directly within a component using
<style module lang="scss"></style>
Am I able to use CSS modules from a main global stylesheet?

Related

Can't compile sass while using Vue Storybook

I'm trying to create storybook on vue. My components written using sass. So, I made this in .storybook/main.js:
webpackFinal: (config) => {
config.module.rules.push({
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
})
return config
}
And the styles looks like this:
<style lang="sass" scoped>
button
background-color: red
</style>
So I'm getting this error when trying to compile:
SassError: Invalid CSS after "": expected 1 selector or at-rule, was "button"
on line 1 of C:\Code\testproj\src\components\UI\TestComponent.vue
And if I change my style to this:
<style lang="sass" scoped>
button {
background-color: red
}
</style>
All works, but that's not a sass syntax.
I was having this exact same issue and I was able to solve it. The issue is from the webpack config. If you're using SASS, your webpack.config.js file in your .storybook folder should look like this:
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.sass$/,
use: [
require.resolve("vue-style-loader"),
require.resolve("css-loader"),
{
loader: require.resolve("sass-loader"),
options: {
sassOptions: {
indentedSyntax: true
}
}
}
],
});
return config;
};
And if you're using SCSS, then it should be like this:
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.scss$/,
use: [
require.resolve("vue-style-loader"),
require.resolve("css-loader"),
require.resolve("sass-loader"),
],
});
return config;
};
I was able to figure this out while reading the Vue Loader Docs
The problem is that in your webpack config, you are telling webpack that only use sass-loader when de extension of your file was test: /.s[ac]ss$/i That is to say .sass or .scss. However the extension of your file is .vue, because you are using sass in the vue file of your component.
With that configuration, try to put your sass style in a .sass file and check if works
For anyone using React 17+ with Storybook 6.4.9+, I had a similar problem where the Storybook/webpack build was not including my SCSS files. This configuration in .storybook/main.js worked for me:
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
],
"framework": "#storybook/react",
webpackFinal: async (config) => {
// add SCSS support for CSS Modules
config.module.rules.push({
test: /\.scss$/,
use: [
require.resolve("style-loader"),
require.resolve("css-loader"),
require.resolve("sass-loader"),
],
});
return config;
}
}
I spend a lot of time to find better solution. It is may main.js config file for Storybook 6.4.9:
const path = require('path');
module.exports = {
"stories": [
"../src/**/*.stories.#(js|jsx|ts|tsx|mdx)"
],
"addons": [
"#storybook/addon-essentials",
"#storybook/addon-actions",
"#storybook/addon-controls",
"#storybook/addon-links",
{
name: '#storybook/preset-scss',
options: {
sassLoaderOptions: {
implementation: require('node-sass'), // ATTENTION: We need to use "node-sass" instead "sass/dart-sass"
sassOptions: {
indentedSyntax: true
},
},
}
},
"#storybook/addon-postcss",
],
"framework": "#storybook/vue",
features: {
babelModeV7: true,
},
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// ATTENTION: Need to preload "global.sass" style for all elements;
config.module.rules.map(rule => {
if (rule.test instanceof RegExp && rule.test.toString() === '/\\.s[ca]ss$/') {
rule.use.push({
loader: require.resolve('sass-resources-loader'),
options: {
resources: [
path.resolve(__dirname, '../src/styles/global.sass')
]
}
})
}
return rule
})
// ATTENTION: Need to compile "Pug" templates.
config.module.rules.push(
{
test: /\.pug$/,
oneOf: [
// this applies to `<template lang="pug">` in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
}
);
// Return the altered config
return config;
},
}

vue file dont working in atom IDE with webpack

I'm creating a project in Rails with vue, for this I'm working with webpack, what happens and my text editor, atom IDE, does not process the .vue files, I've tried the steps that the documentation recommends, but I do not know what I'm doing wrong
I provided loading the vue-loader by npm, but I still can not see the .vue files in my project, then I did it by configuring in the webpack.config.js file, and nothing. Then I leave the links of the things I did that did not work.
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import OptimizeCssAssetsPlugin from '../../../src/';
module.exports = {
entry: './index',
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: { loader: 'style-loader' },
use: {
loader: 'css-loader',
options: { minimize: true }
}
},
vue: {
loaders: {
sass: 'style!css!sass?indentedSyntax',
scss: 'style!css!sass'
}
},
plugins: [
new ExtractTextPlugin('file.css'),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /optimize-me\.css/g
})
};
I hope to be able to work the .vue files

Using module in vue.config.js

I am trying to use the following code in my vue.config.js file, but it is giving me errors that module is not allowed. I am aware that there are configureWebpack and chainWebpack options, but I have no idea how to convert the following to use them. Any help would be appreciated
var path = require('path');
module.exports = {
foo:{},
bar{},
// Putting module in here does not work
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
{
loader: "sass-loader",
options: {
includePaths: [
path.resolve(__dirname, "./node_modules/#syncfusion")
]
}
}
]
}
}
}
]
}
}
and in my vue file
<style lang="scss">
#import 'subfolder-inside-syncfusion/some-file.scss';
</style>
Link to code I found:
https://www.syncfusion.com/forums/139116/scss-files-when-included-in-my-file-doesnt-work-as-expected
You dont have to tap into the webpack config, if all you need is to include a global SCSS file. To import #syncfusion from node_modules, you can setup your vue.config.js like so:
css: {
loaderOptions: {
sass: {
data: `#import "~#syncfusion";`
}
}
}
For more info, see the Vue docs "Working with CSS".

Loading .mp3 files with Nuxt.js

I'm facing a problem with loading .mp3 files with Nuxt.JS (Vue.js)...
I've tried to load the file without an specific loader and webpack tells that he need one specific loader for the file and when i added the url-loader in nuxt.config.js file:
build: {
/*
** Run ESLint on save
*/
extend (config, { isDev, isClient }) {
if (isDev && isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
config.module.rules.push({
test: /\.(ogg|mp3|wav)$/i,
loader: 'url-loader'
})
}
}
throws the error:
TypeError
Cannot read property 'middleware' of undefined
Somebody have used another loaders in Nuxt.Js?
Thanks in advance!
From Nuxt.js official documentation: https://nuxtjs.org/faq/webpack-audio-files/
export default {
build: {
extend (config, ctx) {
config.module.rules.push({
test: /\.(ogg|mp3|wav|mpe?g)$/i,
loader: 'file-loader',
options: {
name: '[path][name].[ext]'
}
})
}
}
}
Normally, you just have to use the file-loader in your webpack config :
{
test: /\.mp3$/,
include: '/path/to/directory',
loader: 'file-loader'
}
Can you share your config file ?
Instead of import directly in javascript, I recommend you to load your file with a generic resource loader.

MiniCssExtractPlugin fail to load css file inside node modules

I use MiniCssExtractPlugin in a project which has some problem when I import css file inside node modules in a vue file. Import statement:
import '../../../node_modules/video.js/dist/video-js.css
Webpack config:
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { url: false }
}
]
}
No style has been applied using the above setting. I tried to create a test.css file and put around in different folder. All directory will work except inside node_modules folder. Please help.
Extra info:
If I replace MiniCssExtractPlugin with style-loader, everything will be ok.
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: { url: false }
}
]
}