Use scoped CSS in Vue components from library (no data tags) - vuejs3

When building a reusable Vue component library, the scoped CSS is not applied, because the PostCSS data-tags are missing. (If the component is not imported as a package, but directly imported into the project it works as intended: styles are applied, and data-tags are present, so the SFC itself is okay.)
https://vuejs.org/api/sfc-css-features.html
I'm building the components use Vite, so maybe it's something to configure in vite.config.ts?
vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig, type PluginOption } from 'vite'
import vue from '#vitejs/plugin-vue'
import vuetify from 'vite-plugin-vuetify'
import typeScript2 from "rollup-plugin-typescript2"
import { visualizer } from "rollup-plugin-visualizer"
export default defineConfig({
plugins: [
vue(),
vuetify(),
typeScript2({
check: false,
include: ["src/components/*.vue"],
tsconfigOverride: {
compilerOptions: {
sourceMap: true,
declaration: true,
declarationMap: true,
}
},
exclude: [
"vite.config.ts"
]
}),
visualizer() as PluginOption
],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url))
}
},
build: {
cssCodeSplit: false,
lib: {
entry: './src/components/index.ts',
formats: ["es", "cjs"],
name: "CommonVtfyPlugin",
fileName: format => (format == "es" ? "index.js" : "index.cjs"),
},
rollupOptions: {
external: ["vue", "vuetify", "vuetify/lib", 'vuetify/lib/util/colors.mjs'],
output: {
exports: 'named',
globals: {
vue: "Vue",
vuetify: "Vuetify",
'vuetify/components': "VuetifyComponents",
'vuetify/directives': "VuetifyDirectives",
'vuetify/lib/util/colors.mjs': 'colors'
}
}
}
}
})
The Single File Component:
<template>
<v-select
:class="{'nkd':isNkd}"
....
>
....
</v-select>
</template>
<style scoped>
.nkd :deep(.v-field__input) {
padding: 0;
min-height: auto;
}
.nkd :deep(.v-field) {
padding: 0;
align-items: center;
background-color: transparent;
}
.nkd :deep(.v-field__append-inner) {
padding: 0;
}
</style>
I don't think it matters, but the SFC component uses a Vuetify component (V-Select).

Related

Tailwindcss / Vite / Vue - Using #{!important} - results in [vite] Internal server error: [postcss] Unknown word or with '!w-3' [vite] expected ";"

dev dependencies
{
"vue": "^3.2.45",
"vite": "^4.0.3",
"sass": "^1.57.1",
"postcss": "^8.4.19",
"tailwindcss": "^3.2.4",
}
Vite.config.ts
import { defineConfig, type PluginOption } from 'vite'
import vue from '#vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'
import { visualizer } from 'rollup-plugin-visualizer'
import type { UserConfig as VitestUserConfigInterface } from "vitest/config"
import dts from 'vite-plugin-dts'
import { resolve } from 'path'
const vitestConfig: VitestUserConfigInterface = {
test: {
globals: true,
environment: "jsdom",
},
}
export default defineConfig({
build: {
target: ['edge90', 'chrome90', 'firefox90', 'safari15'],
outDir: './dist',
lib: {
formats: ['es', 'cjs'],
entry: resolve(__dirname, './src/components/index.ts'),
name: 'Vuesty',
fileName: 'index',
},
rollupOptions: {
external: ['vue'],
output: { globals: { vue: 'Vue' } },
},
},
test: vitestConfig.test,
plugins: [vue(), eslintPlugin(),
dts({
beforeWriteFile: (filePath, content) => {
const newFilePath = filePath
.replace('/src', '/global');
return {
filePath: newFilePath,
content,
};
},
skipDiagnostics: true,
}),
visualizer({
emitFile: true
}) as PluginOption
],
})
avatar.scss
.v-avatar__status-circle_large{
#apply !w-2.5 ;
}
Avatar.vue
<style lang="scss">
#import "src/assets/themes/main/components/avatar.scss";
</style>
If i use global styles, not importing it directly into component then it works fine, but i need it exactly in the component
If the code is:
.v-avatar__status-circle_large{
#apply !w-2.5 ;
}
Then error is: [vite] Internal server error: [sass] expected ";".
And if the code is:
.v-avatar__status-circle_large{
#apply w-2.5 #{!important};
}
Error:[vite] Internal server error The important class does not exist. If important is a custom class, make sure it is defined within a #layer directive.

Laravel vite won't process custom css

I am trying to inject my custom css in built css file but it does not process resources/css/app.css file
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
],
resolve: {
alias: {
'$': 'jQuery'
},
},
});
resources/css/app.css
h2.swal2-title {
font-size: 1.2em !important;
}
This css does not add to generate css file by npm run build
Any idea?

how to import global css in react?

I am trying to import global css file inside react javascript file. I am importing in following way:
import React from "react";
import MainWrapper from "./components";
import "./global.css";
const App = () => {
return (
<MainWrapper />
);
};
export default App;
My global.css file looks like following:
#import '/node_modules/antd/dist/antd.css';
i.anticon.anticon-menu-unfold.trigger, i.anticon.anticon-menu-fold.trigger {
margin: auto;
display: flex;
justify-content: center;
padding: 12px;
color: white;
}
i.anticon.anticon-menu-fold.trigger{
float: right;
}
Here above, I am overidding predefined css of ANT Design. Here it is not able to override ant's predefined css.
My webpack.config.js looks like following:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const WebapckManifestPlugin = require("webpack-manifest-plugin");
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
"#babel/preset-env",
"#babel/preset-react"
],
plugins: [
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-proposal-class-properties"
]
}
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
},
// {
// test: /\.css$/,
// use: [
// "style-loader"
// ,
// "css-loader"
// ]
// },
{
test: /\.css$/,
use:
[
{
loader: "style-loader",
},
// {
// loader: "isomorphic-style-loader",
// },
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]"
}
}
}
]
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
loader: "url-loader?limit=100000" }
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "./index.html"
}),
new WebapckManifestPlugin({
template: "./public/manifest.json"
})
],
resolve: {
extensions: ["*",".js",".jsx"]
}
}
However, look below. I am importing css file in below js file. It works
import React, { useState } from "react";
import { Layout, Menu, Icon } from "antd";
// import useStyles from 'isomorphic-style-loader/useStyles'
import style from "./style.css";
const Dashboard = () => {
// useStyles(style);
return(
<div className={style.dashboard}>
karan
</div>
);
};
export default Dashboard;
My style.css file looks like this:
.dashboard{
text-align: center;
}
I think the problem is with webpack.config.js.
When I change style syntax from:
className={style.dashboard}
To:
className="dashboard"
And import statement from:
import style from "./style.css";
To:
import "./style.css";
And webpack.config.js test: /.css$/ to:
{
test: /\.css$/,
use: [
"style-loader"
,
"css-loader"
]
}
Everythings works then.

Why are imported SASS styles being purged by PurgeCSS when using camelCase?

I am trying to combine CSS-modules and PurgeCSS to get module scoping and a light CSS bundle.
I have been able to accomplish this using syntax like styles["my-class"] but would prefer styles.myClass (which works, but gets stripped out for imported SASS within SASS files).
SASS from a local file works as expected, but SASS #imported from node_modules or another file doesn't work with camelCase references.
In the below code, I will get an output like:
.Component--container--AfniF {
margin: 1em;
}
but all the imported SASS that I reference in the component as styles.myClass is purged.
But, when referenced like styles["my-class"] everything works as expected and I get output like:
.Component--my-class--6Mlw4 {
color: purple;
}
.Component--container--AfniF {
margin: 1em;
}
Any ideas?
// otherstyles.scss
.my-class {
color: purple;
}
// Component.scss
#import "otherstyles";
.container {
margin: 1em;
}
///Component.js
import React, { Fragment, useState } from "react";
import classnames from "classnames";
import styles from "./Component.scss";
export default function ({ data }) {
return <div className={classnames([styles.myClass, styles.container])}>
//webpack.config.js
...
{
test: /.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
modules: true,
camelCase: true,
importLoaders: 1,
sourceMap: true,
localIdentName: "[name]--[local]--[hash:base64:5]",
},
},
{
loader: "postcss-loader",
},
{
loader: "#americanexpress/purgecss-loader",
options: {
paths: [path.join(__dirname, "src/**/*.{js,jsx}")],
},
},
{
loader: "sass-loader",
options: {
includePaths,
outputStyle: "expanded",
sourceMap: true,
},
},
],
},

Svelte: Is there a way to make global css variables in scope of svelte components?

I have set my global.css file which I import in index.js
--root {
--main-color: red;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
index.js
import "./global.css";
import App from "./App.svelte";
const app = new App({
target: document.body
});
My webpack setup
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.(html|svelte)$/,
exclude: /node_modules/,
use: {
loader: "svelte-loader",
options: {
emitCss: true,
hotReload: true
}
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: { loader: "style-loader", options: { sourceMap: true } },
use: [
{ loader: "css-loader", options: { sourceMap: true } },
{
loader: "postcss-loader",
options: {
sourceMap: true,
ident: "postcss",
plugins: loader => [
require("postcss-import")({}),
require("postcss-preset-env")(),
require("cssnano")()
]
}
}
]
})
}
]
},
plugins: [new HtmlWebpackPlugin(), new ExtractTextPlugin("styles.css")]
};
Works perfect for setting up global css for the entire app. But I am trying to use the --main-color in my svelte components. Is there a way to inject them down to all the components' css ?
Since I import global.css first, it should work as it emits a file with --root{} first then rest of the component styles.
You can place global styles under /routes/index.svelte file, like the example below:
<style>
:global(:root){
--header-color: purple
}
</style>
And simply use it anywhere like normally how you use CSS variables like so:
h1 {
color: var(--header-color);
}
I was busy with this, trying different webpack settings etc., seeing that the output css should work, I just could not find why it did not work. I wrote the post before trying for one last time, which wasted another hour. I finally found the error.
Instead of using :root{} I have mistyped it --root{}. I have posted it anyways, in case someone is stuck with the same mistake.

Resources