Nuxt 3 + Vuetify 3 how to plug custom SASS variables - nuxtjs3

I'm struggling to get my setup to work using
"vuetify": "^3.1.4"
"nuxt": "^3.1.2"
"vite-plugin-vuetify": "^1.0.2",
"#mdi/font": "^7.1.96",
"sass": "^1.58.0",
I've read as many ressources as possible on the topic, starting with this one which seems outdated?
Here's my setup:
// assets/styles/config.scss
#use "vuetify/settings" with (
$font-size-root: 20px,
$heading-font-family: Space Grotesk,
$body-font-family: $font,
$color-pack: false,
$utilities: false,
$typography: (
"h1": (
"size": 2rem,
"weight": 500,
"line-height": 2.2rem,
"letter-spacing": 0,
"font-family": Comic Sans,
"text-transform": none,
),
)
);
import "#/assets/styles/config.scss";
import { createVuetify } from "vuetify";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(
createVuetify({
ssr: true,
// components,
// directives,
styles: { configFile: "assets/styles/config.scss" },
theme: {
defaultTheme: "light",
themes: {
dark: false,
light: {
colors: {
primary: "#4093ff",
secondary: "#4d4d4d",
success: "#25c760",
warning: "#ffc82e",
error: "#ff4c29",
},
},
},
},
})
);
});
import vuetify from "vite-plugin-vuetify";
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
css: ["vuetify/lib/styles/main.sass", "#mdi/font/css/materialdesignicons.min.css", "#/assets/styles/config.scss"],
build: {
transpile: ["vuetify"],
},
modules: [
// #ts-ignore
async (options, nuxt) => {
nuxt.hooks.hook("vite:extendConfig", (config) => config.plugins.push(vuetify()));
},
],
vite: {
ssr: {
noExternal: ["vuetify"], // add the vuetify vite plugin
},
},
});
Custom theme will work but SASS variables are ignored.
Any help appreciated!
Thanks!!

After a full day of researches, I found this github issue, which includes a temporary fix of the underlying bug:
https://github.com/nuxt/nuxt/issues/15412#issuecomment-1399189084
I hope others won't have as much trouble as I did!

Related

For my vue3, vuetify, ts project Vite builds dev, prod but in prod it does not release console

I created my first vue3, ts, vuetify project, using vite (4.1.1).
vite => server is fine, no error, no warning
vite build => no error, no warning, files are generated as expected in dist and work as expected.
But but, when I run build in console, it is stuck after generation, the process never ends. And without the process ending, I cannot deploy the solution :$.
Any idea of what could prevent it from finishing ?
tsconfig.json
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"files": [],
"compilerOptions": {
"newLine": "lf"
},
"references": [
{ "path": "./tsconfig.config.json" },
{ "path": "./tsconfig.app.json" }
]
}
tsconfig.app.json
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "#vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"#/*": ["./src/*"]
},
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"types": ["vuetify"]
}
}
tsconfig.app.json
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "#vue/tsconfig/tsconfig.node.json",
"include": [
"vite.config.*"
],
"compilerOptions": {
"composite": true,
"types": ["node"]
}
}
vite.config.ts
import { defineConfig, type UserConfig } from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';
import { checker } from 'vite-plugin-checker';
import vue from '#vitejs/plugin-vue';
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';
import { fileURLToPath, URL } from 'node:url';
import fs from 'node:fs';
/**
* Vite Configure
*
* #see {#link https://vitejs.dev/config/}
*/
export default defineConfig(async ({ command, mode }): Promise<UserConfig> => {
const config: UserConfig = {
// https://vitejs.dev/config/shared-options.html#base
base: './',
// https://vitejs.dev/config/shared-options.html#define
define: { 'process.env': {} },
plugins: [
// Vue3
vue({
template: {
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin#image-loading
transformAssetUrls,
},
}),
// Vuetify Loader
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin#vite-plugin-vuetify
vuetify({
autoImport: true,
styles: { configFile: 'src/styles/settings.scss' },
}),
// vite-plugin-checker
// https://github.com/fi3ework/vite-plugin-checker
checker({
typescript: true,
vueTsc: true,
eslint: {
lintCommand:
'eslint . --fix --cache --cache-location ./node_modules/.vite/vite-plugin-eslint', // for example, lint .ts & .tsx
},
}),
],
// https://vitejs.dev/config/server-options.html
server: {
fs: {
// Allow serving files from one level up to the project root
allow: ['..'],
},
},
// Resolver
resolve: {
// https://vitejs.dev/config/shared-options.html#resolve-alias
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
'~': fileURLToPath(new URL('./node_modules', import.meta.url)),
},
extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
},
// Build Options
// https://vitejs.dev/config/build-options.html
build: {
// Build Target
// https://vitejs.dev/config/build-options.html#build-target
target: 'esnext',
// Minify option
// https://vitejs.dev/config/build-options.html#build-minify
minify: 'esbuild',
// Rollup Options
// https://vitejs.dev/config/build-options.html#build-rollupoptions
rollupOptions: {
// #ts-ignore
output: {
manualChunks: {
// Split external library from transpiled code.
vue: ['vue', 'pinia'],
vuetify: [
'vuetify',
'vuetify/components',
'vuetify/directives'
],
materialdesignicons: ['#mdi/font/css/materialdesignicons.css'],
},
plugins: [
mode === 'analyze'
? // rollup-plugin-visualizer
// https://github.com/btd/rollup-plugin-visualizer
visualizer({
open: true,
filename: 'dist/stats.html',
})
: undefined,
],
},
},
},
esbuild: {
// Drop console when production build.
drop: command === 'serve' ? [] : ['console'],
},
};
// Write meta data.
fs.writeFileSync(
fileURLToPath(new URL('./src/Meta.ts', import.meta.url)),
`import type MetaInterface from '#/interfaces/MetaInterface';
// This file is auto-generated by the build system.
const meta: MetaInterface = {
version: '${require('./package.json').version}',
date: '${new Date().toISOString()}',
};
export default meta;
`
);
return config;
});
vite build --mode analyze : does build and opens the stat html so means the build is actually finished ? But still, it is stuck in console.
I checked circular dependencies.

Why my style section is gray using postcss with nuxt 3?

I don't know why all the style sections of my project having a gray text. Anything work normally but this make it hard to watch.
image.
My nuxt.config.ts
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
typescript: {
shim: false,
},
modules: [
[
"#pinia/nuxt",
{
autoImports: ["defineStore"],
},
],
],
css: [
"~/assets/css/tailwind.css",
"#fortawesome/fontawesome-svg-core/styles.css",
],
build: {
postcss: {
postcssOptions: require("./postcss.config"),
},
},
});
My postcss.config.js
module.exports = {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": "postcss-nesting",
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {}),
},
};
content of my tailwind.config
content: [
"./assets/**/*.{vue,js,css}",
"./components/**/*.{vue,js}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./nuxt.config.{js,ts}",
"./app.{vue,ts,js}",
],
Have anyone encountered this problem before? please help me.
Nevermind, I installed extension language-postcss and its good

React - Electron, using React-Quill package with styles not applying to component

I have this very weird problem with the React-Quill library component.
I am importing the component as per the NPM instructions, and the editor does load but without any actual CSS applied
The only when the styles are applied are when I link the stylesheet through CDN in the index.html file
<link rel=“stylesheet” href=“//cdn.quilljs.com/1.2.6/quill.snow.css”>
I’ve tested in a stackblitz the same code and it works without such issues.
I am using similar other components such as ‘react-color-palette’ where I do import the styles in the same fashion through the node_modules and there is no problem with it, so it doesn’t make sense to me to be a webpack config problem either but I tested various options with different settings on webpack to no avail.
Even added the CSS to my global CSS which works perfectly fine too, but it still doesn’t apply to the React-Quill
For some reason, the CSS isn't targeting the classes, or its scoped out, but I am unable to understand why that happens
Here is the code
import React, { useState } from 'react';
import hljs from 'highlight.js';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
const modules = {
// syntax: {
// highlight: (text: string) => hljs.highlightAuto(text).value,
// },
toolbar: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'],
[{ color: [] }],
[{ align: [] }],
[{ indent: '-1' }, { indent: '+1' }],
[{ list: 'ordered' }, { list: 'bullet' }],
['link', 'image', 'video'],
['code-block', 'blockquote'],
[{ script: 'sub' }, { script: 'super' }],
],
clipboard: {
matchVisual: false,
},
syntax: false,
};
const textFormats = [
'font',
'header',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'background',
'color',
'script',
'list',
'bullet',
'link',
'image',
'video',
'clean',
'code-block',
'indent',
'list',
'align',
];
function RichTextEditor() {
const [value, setValue] = useState('');
hljs.configure({
// useBR: false,
languages: [
'javascript',
'java',
'html',
'xml',
'sql',
'typescript',
'bash',
],
});
return (
<ReactQuill
value={value}
onChange={setValue}
placeholder="Write a new Note"
modules={modules}
formats={textFormats}
/>
);
}
export default RichTextEditor;
Edit
I opened the console and checked in the tags
there are styles currently applied for the react-quill, but seems react modifies the class names:
.RichTextEditor__ql-container__SP9Yv
Where it should really just be
.ql-container

issue loading css module classes in storybook v6.4

I'm having trouble getting storybook to play nice with css modules within my Gatsby project. I'm able to render the button component but it does not add any of my styling. On inspection of the element, I'm only getting undefined undefined from the following code.
button.jsx
import React from "react"
import * as css from "./style.module.css"
const Button = ({ variant = "button", type, value = null }) => {
const baseOfVariant = () => {
if (variant === "input") {
return (
<input
type={type}
value={value}
className={`${css.button} ${css.clear_button}`}
/>
)
}
return (
<button type={type} className={`${css.button} ${css.submit_button}`}>
{value}
</button>
)
}
return baseOfVariant()
}
export default Button
button.stories.jsx
import React from "react"
import Button from "./button"
export default {
title: "Button",
component: Button,
}
export const Template = args => <Button {...args} />
export const ButtonRegular = Template.bind({})
ButtonRegular.args = {
variant: "button",
value: "Click Me",
type: "submit",
}
main.js
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.#(js|jsx|ts|tsx)"],
addons: ["#storybook/addon-links", "#storybook/addon-essentials"],
core: {
builder: "webpack5",
},
}
Storybook stuff in my devDeps
"devDependencies": {
"#babel/core": "^7.14.6",
"#babel/polyfill": "^7.12.1",
"#storybook/addon-actions": "^6.4.0-alpha.2",
"#storybook/addon-essentials": "^6.4.0-alpha.2",
"#storybook/addon-links": "^6.4.0-alpha.2",
"#storybook/addon-viewport": "^6.4.0-alpha.2",
"#storybook/builder-webpack5": "^6.4.0-alpha.2",
"#storybook/manager-webpack5": "^6.4.0-alpha.2",
"#storybook/react": "^6.4.0-alpha.2",
"babel-loader": "^8.2.2",
"prettier": "2.2.1",
"resize-observer-polyfill": "^1.5.1"
}
Gatsby needs to import css modules with the following synthax:
import * as css from "./style.module.css"
Where Storybook recognizes only this synthax:
import css from "./style.module.css"
This is due to the fact that Gatsby and Storybook don't use the same import convention. Fortunately, you can configure Storybook css module import mechanism via .storybook/main.js file.
const path = require("path")
module.exports = {
// You will want to change this to wherever your Stories will live
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.#(js|jsx|ts|tsx)"],
addons: ["#storybook/addon-links", "#storybook/addon-essentials"],
core: {
builder: "webpack5",
},
webpackFinal: async config => {
// Prevent webpack from using Storybook CSS rules to process CSS modules
config.module.rules.find(
rule => rule.test.toString() === "/\\.css$/"
).exclude = /\.module\.css$/
// Tell webpack what to do with CSS modules
config.module.rules.push({
test: /\.module\.css$/,
include: path.resolve(__dirname, "../src"),
use: [
{
loader: "style-loader",
options: {
modules: {
namedExport: true,
},
},
},
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
namedExport: true,
},
},
},
],
})
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
config.module.rules[0].use[0].options.plugins.push(
require.resolve("babel-plugin-remove-graphql-queries")
)
return config
},
}
With the above configuration, Storybook now accept this import synthax and button.jsx is correctly styled.
import * as css from "./style.module.css"
If any one is looking for sass/scss related fix
import * as style from "./style.module.scss"
Where Storybook recognizes only this synthax:
your .storybook/main.js file.
const path = require("path");
module.exports = {
stories: ["../src/**/*.stories.{js,mdx}"],
addons: [
"#storybook/addon-docs",
"#storybook/addon-actions",
"#storybook/addon-controls",
"#storybook/addon-a11y",
"#storybook/addon-viewport",
],
// https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324
core: {
builder: "webpack5",
},
webpackFinal: async config => {
// https://www.gatsbyjs.com/docs/how-to/testing/visual-testing-with-storybook/
config.module.rules.push({
test: /\.(js)$/,
use: [
{
loader: require.resolve("babel-loader"),
options: {
presets: [
// use #babel/preset-react for JSX and env (instead of staged presets)
require.resolve("#babel/preset-react"),
require.resolve("#babel/preset-env"),
],
plugins: [
// use #babel/plugin-proposal-class-properties for class arrow functions
require.resolve("#babel/plugin-proposal-class-properties"),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve("babel-plugin-remove-graphql-queries"),
// use babel-plugin-react-docgen to ensure PropTables still appear
require.resolve("babel-plugin-react-docgen"),
],
},
},
],
exclude: [/node_modules\/(?!(gatsby)\/)/],
});
config.module.rules.push({
test: /\.s[ac]ss$/i,
oneOf: [
// module.scss files (e.g component styles.module.scss)
// https://webpack.js.org/loaders/style-loader/#modules
{
test: /\.module\.s?css$/,
use: [
// Add exports of a module as style to DOM
{
loader: "style-loader",
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
// Loads CSS file with resolved imports and returns CSS code
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
// Loads and compiles a SASS/SCSS file
{
loader: "sass-loader",
// only if you are using additional global variable
options: {
additionalData: "#import 'src/styles/global.scss';",
sassOptions: {
includePaths: ["src/styles"],
},
},
},
],
},
// scss files that are not modules (e.g. custom.scss)
{
use: [
// Add exports of a module as style to DOM
"style-loader",
// Loads CSS file with resolved imports and returns CSS code
"css-loader",
// Loads and compiles a SASS/SCSS file
{
loader: "sass-loader",
// only if you are using additional global variable
options: {
additionalData: "#import 'src/styles/global.scss';",
sassOptions: {
includePaths: ["src/styles"],
},
},
},
],
},
],
});
return config;
},
};
With the above configuration, Storybook now accept this import synthax and button.jsx is correctly styled.
import * as styles from "./style.module.scss"

Webpack localIdentName mismatch on server and client in a React SSR application

I am trying to use Css modules with React SSR and i have added the following webpack config .
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
},{
test:/\.(s*)css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
modules: {
mode: 'local',
localIdentName: "[name]__[local]___[hash:base64:5]"
},
import: true,
importLoaders: true,
}
},
{
loader: "sass-loader",
}
],
},
]
},
this generates the following css files in the dist bundle
.Home\.module__Container___3B08 {
display: flex;
width: 600px;
height: 300px;
border: 2px solid red; }
Where as in my DOM the div has the following style
<div class="Home-module__Container___14QBF">
how do i make this correct ? and why is the webpack config different with the one in the browser
You have to add the CSS Modules configuration in .babelrc file under plugins. Then only the CSS generated will match with the one in your html.
.babelrc
"plugins": [
["react-css-modules", {
"generateScopedName": "[name]__[local]___[hash:base64:5]"
}]
],
Update :
Had to use css-modules-require-hook for server side CSS rendering and generic-names for generating hash in both client and server.
index.js
const hook = require( "css-modules-require-hook" );
const genericNames = require( "generic-names" );
const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
context: process.cwd(),
});
// Scope Generator function.
hook( {
generateScopedName: ( c, path ) => {
return generate( c, path );
},
} );
webpack.config.js
const genericNames = require( "generic-names" );
const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
context: process.cwd(),
});
const getLocalIdent = ( loaderContext, localIdentName, localName ) =>
generate( localName, loaderContext.resourcePath );
.....
{
loader: "css-loader",
options: {
modules: {
getLocalIdent,
},
},
},
For more, check this repo: https://github.com/ajayvarghese/react-ssr/tree/css-modules.
Note: Repo uses updated versions of babel packages.

Resources