Global Variables : Stylus Vue Vite - javascript

I would like to create and use stylus variables globally in my Vue Vite project. How can I import stylus variables globally to use within the script section of my SFC?
Here's my Vite config:
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'#': path.resolve(__dirname, './src'),
},
},
css: {
preprocessorOptions: {
styl: {
additionalData: `#import "#/styles/styles.styl"`
}
}
}
})
In my styles.styl file I define a variable like:
contentSideMargin = 50px
In my SFC I try to use a style from styles.styl such as
<style lang="stylus" scoped>
#main-container
padding: $contentSideMargin /* have also tried `contentSideMargin` */
</style>
but it does not work.
—
EDIT: adding package.json. There are no visible errors, the variable is passed directly into the css rather than its value.
{
"name": "project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"pinia": "^2.0.17",
"pug": "^3.0.2",
"vue": "^3.2.37",
"vue-router": "^4.1.3"
},
"devDependencies": {
"#vitejs/plugin-vue": "^3.0.0",
"stylus": "^0.58.1",
"stylus-loader": "^7.0.0",
"vite": "^3.0.0"
}
}

METHOD A) - CONFIGURING VITE FOR STYLUS USING additionalData PROPERTY
This is the solution You have been searching for
vite.config.js:
import { defineConfig } from 'vite'
import path from 'path'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
stylus: {
additionalData: `#import "${path.resolve(__dirname, 'src/assets/global_variables.styl')}"`
}
}
},
})
METHOD B) - IMPORTING STYLUS VARIABLES IN CSS
If you don't want to custom-configure how Vite should bundle your code, all your <style lang="stylus" scoped> must contain definitions of stylus variables that you are going to use in the component.
Either u can define the variables explicitly at the beginning of <style lang="stylus" scoped> or if you have variables definitions in a separate file, you can import that file:
App.vue:
<template>
<div id="my-div">THIS IS MY DIV</div>
</template>
<style lang="stylus" scoped>
#import "./assets/global.styl";
#my-div {
padding: 1rem;
color: $c-text;
background-color: $c-bg;
}
</style>
assets/global.styl:
$c-bg = red
$c-text = yellow
METHOD C) - CONFIGURING VITE WITH CUSTOM PLUGIN FOR STYLUS:
If you prefer not to use import within your components' <style> tags, you can configure Vite to automatically inject stylus files into the CSS of your app by including a custom Vite plugin vite-stylus-import-plugin.js. An advantage of this method over method A is that you can extra-customize the transformation of your stylus files.
vite-stylus-import-plugin.js:
import path from 'path'
export function importStylus() {
return {
name: 'vite-stylus-import-plugin',
async transform(code, id) {
if (/.stylus$/g.test(id)) {
return {
code: `
#import "${path.resolve(__dirname, 'src/assets/global_variables.styl')}"
${code}
`,
map: null,
}
}
return null
}
}
}
After that you can use that plugin in your Vite config file:
vite.config.js:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
import { importStylus } from './vite-stylus-import-plugin.js'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), {
...importStylus(),
enforce: 'pre',
}]
})
WORKING DEMOS
I have a working demo for the last two methods HERE - GitHub repo HERE. In the demo, the big red <div> element was styled using the method B, the blue <div> was styled using the method C. The method A is not in my demo, but it works too

I think that instead
contentSideMargin = 50px
...
<style lang="stylus" scoped>
#main-container
padding: $contentSideMargin /* have also tried `contentSideMargin` */
</style>
The code should be
$contentSideMargin = 50px
...
<style lang="stylus" scoped>
#main-container {
padding: $contentSideMargin;
}
</style>
Thanks to #DVN-Anakin comment and the link provided in the comment ( github.com/TOA-Anakin/Vite-Vue3-TS-template) to a working boilerplate - it's easy to spot the differences
In short: dear stackoverflow users - please read the comments! Members here put their best effort to try to assist without making to much noise (hence comments). If you skip them or not reading them properly - you may loose some vital information that will help you to solve your problem (which is kinda of what we are doing here in the first place)

Related

Dark mode switcher in Nuxt 3 not working with official #nuxtjs/color-mode

I wanted to implement dark mode on my Nuxt app using tailwind and the recommended #nuxtjs/color-mdoe module. Testing tailwind's dark: classes went fine and worked as expected, however I can't make a button switcher work to set the color mode programmatically.
I installed in devDeps the module in version 3.2.0, which should be compatible with Nuxt 3, according to the docs
"#nuxtjs/tailwindcss": "^6.1.3",
"#nuxtjs/color-mode": "^3.2.0"
And applied the proper configuration in nuxt.config.ts
modules: [ '#nuxtjs/color-mode' ],
colorMode: {
classSuffix: '',
preference: 'system',
fallback: 'dark'
}
I used tailwind nuxt module
In tailwind.config.js
module.exports= {
theme: {
colors: {
transparent: 'transparent',
current: 'currentColor',
dark: '#212129',
darkPrimary: '#00E1FF',
darkSecondary: '#00D6D6',
light: '#E9DAC1',
lightPrimary: '#1d68f3',
lightSecondary: '#00b5f0',
main: '#0073FF',
white: '#FFFFFF',
},
spacing: {
'header': '120px',
},
darkMode: 'class'
}
}
While in ./assets/css/main.css I have no meaningful config about dark mode, just some classes I defined globally
html {
#apply transition-colors ease-in duration-1000;
#apply bg-gradient-to-b bg-no-repeat w-screen ;
#apply dark:from-dark/95 dark:via-dark/95 dark:to-dark dark:text-white from-white via-light/50 to-light;
}
.contain {
#apply px-[5%] md:px-[25%];
}
Since I wanted to place the switch in the header here's what I did in the component:
<template>
<header class="contain py-[15px] flex items-center justify-between backdrop-blur-3xl">
<button #click="toggleDarkMode($colorMode.preference === 'dark' ? 'light' : 'dark')">
<nuxt-icon v-if="$colorMode.preference === 'dark'" name="sun"/>
<nuxt-icon v-else name="moon"/>
</button>
</header>
</template>
<script setup>
function toggleDarkMode(theme) {
useColorMode().preference = theme
}
</script>
The classes are actually toggling when I manually change the color mode from my os (win11) settings, but clicking the button won't replicate the same behavior. The mode seems to be switching since the icon does change accordingly.
Looking at the docs and tutorials I found elsewhere it should just work like that.
Do I need to set the mode as a global state inside the store? Should I call the hook in a root-level component?
ok, there are several mistakes:
package.json
my package.json file content is this:
i think your tailwind version is 3.1.6
"devDependencies": {
"#nuxtjs/color-mode": "^3.2.0",
"autoprefixer": "^10.4.13",
"nuxt": "3.0.0",
"postcss": "^8.4.19",
"tailwindcss": "^3.2.4"
}
tailwind.config.js
there are mistakes in your tailwind.config.js file:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ['./app.vue'], // you forget content
darkMode: 'class', //you should define darkMode here
theme: {
extend: {},
//darkMode: 'class' >> this is mistake
},
plugins: [],
};
first, you forget the content property you should get this warn:
warn - The content option in your Tailwind CSS configuration is missing or empty.
what is content:
The content section of your tailwind.config.js file is where you configure the paths to all of your HTML templates, JavaScript components, and any other source files that contain Tailwind class names.
second, your darkMode shouldn't be the property of theme you should define it in the root
main.css
now about your main.css file you didn't add tailwind directives( but this is not necessary) :
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer base {
body{
#apply bg-lightPrimary dark:bg-darkPrimary;
}
}
nuxt.config.ts
Finally, your nuxt.config.ts should be this:
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
modules: ['#nuxtjs/color-mode'],
colorMode: {
classSuffix: '',
preference: 'system',
fallback: 'dark',
},
css: ['/assets/css/main.css'],
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
});
I copied your codes and tested them I think your main mistake is that you define darkMode property in the wrong place:
PLS CHECK THIS LINK
summary
check tailwind installation here
add darkMode: 'class' correctly
check content property (read more here)
make sure you added main.css file to nuxt.config.ts globally
these two questions can help you too:
Install tailwind in nuxt3
better dark mode configuration

React import background image

Trying to import a jpeg image to use as my background in React, but keep getting error msg
Error: Can't resolve '/img/dots.jpeg' in 'D:\Developer\mysite\src'
My App.css
.App {
text-align: center;
background-image: url('/img/dots.jpeg');
}
My App.js
import './App.css';
function App() {
return (
<div className="App" >
<h1>asdasdasd</h1>
</div>
);
}
export default App;
My project structure:
My understanding is as long as the image is in the src folder I can access it relatively through URL(). Can someone tell me what I am doing wrong?
/img/dots.jpeg is indicating that it's in the root of your project, whereas ./img/dots.jpeg will indicate that the img directory is in the same directory as the App.css file.
You can use module-resolver plugin and update your babel config with
{
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}]
]
}
#same configuration available in the link. Then you can refer your image with complete path
it seems there is wrong in importing the file in your css,
you are not telling the exact position to look for the file
.App {
text-align: center;
background-image: url('/img/dots.jpeg');
}
add these above lines it will solve the problem

CSS module is not working in react 16.13.1

I want to style components in react JS. I tried several ways to do that. When I try to create a CSS object and apply it to the component in the same JS file, then it is working. But when I try to apply CSS from external CSS file and import it in the JS file then it is not working. And I have also tried to save that file as filename.module.css. But it didn't help me.
The list of installed node modules and their versions is given below.
> #material-ui/core#4.9.11
> #material-ui/icons#4.9.1
> firebase#7.14.1
> react#16.13.1
> react-dom#16.13.1
> react-router-dom#5.1.2
> react-scripts#3.4.1
In webpack.config.js file of react-script module, I found below code:
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
So I guess my react project is supporting CSS files as well as SCSS and SASS files. Did I understand correctly?
header.module.css file:
.heading {
color: '#3592EF';
font-weight: '600';
letter-spacing: '2px';
}
.navButton {
color: '#444';
font-size: '16px';
padding: '4px 8px';
margin: 'auto';
margin-right: '15px';
}
Header.js file:
import React from 'react';
import { Button } from '#material-ui/core';
import styles from './header.module.css';
export default class Header extends React.Component {
render() {
return (
<div>
<span className={styles.headling}>Heading element</span>
<Button className={styles.navButton}>Home</Button>
<Button className={styles.navButton}>About</Button>
</div>
);
}
}
The output is coming with the Heading element and Home, About button. But without CSS style.
How can I solve this issue?
Thank you.
CSS module is included in react
all you have to do is building a file with the correct name like "example.module.css" and import it with the correct path if it's in the same folder `import tst from 'example.module.css' or whatever path it is in, you can replace "tst" with any any name you like.
and then you can use it in className like
<button className={tst.buttonPrimary}>Submit /button>
this video can help you more:
https://www.youtube.com/watch?v=Udf951dyTdU
Generally custom components do not accept className prop if it is not propagated to the inner of the component.
Looking in the material ui react components Button documentation, this component cannot have className property.
https://material-ui.com/components/buttons/
It means, you cannot use it. To convince your self, try to use general html <button> and it will work, you see.
Edit: grammar
first : open your terminal and run "npm install css-loader style-loader --save-dev"
These loaders enable Webpack to bundle CSS files
Second: in your webpack.config.js file, add the new loaders for interpreting CSS files:
module.exports = {
...
module: {
rules: [
...
*///
{
test: /\.css$/i,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
*////
],
},
...
};

Using styled-components results in `cannot read withConfig of undefined`

When attempting to transpile the Spacing.js file, it results in an undefined import even when styled-components was seemingly being imported and used (in the same way) successfully in other files. Even when removing the styled-components babel plugin, a similar error occurs.
.babelrc
{
"presets": [["es2015", { "modules": false }], "react-native"],
"plugins": [
["styled-components", { "displayName": true }],
"react-hot-loader/babel",
"react-native-web",
"transform-decorators-legacy",
"transform-class-properties"
],
"env": {
"production": {
"plugins": [
"transform-react-inline-elements",
"transform-react-constant-elements"
]
}
}
}
Spacing.js - Code before transpilation
import React, { Component, Node } from "React";
import styled from "styled-components";
type Props = {
size: string,
color: string,
fullWidth?: boolean
};
class SpacingComponent extends Component<Props> {
render(): Node {
const { size, color, fullWidth = false } = this.props;
return <Spacing size={size} color={color} fullWidth={fullWidth} />;
}
}
const Spacing = styled.View`
height: ${props => props.size}px;
background-color: ${props => props.color || "transparent"};
width: ${props => {
return props.fullwidth ? "100%" : props.size + "px";
}};
`;
export default SpacingComponent;
Generated code for importing and resolving styled-components
Generated code for using the styled-components library (v3.2.5)
The resulting error
Another example can be seen when removing the styled-components babel plugin from the babelrc, thus the withConfig is not added.
Generated error with no styled-components babel plugin
Generated code making this error
Is babel or webpack adding .default when it doesn't need to, if so, how could I investigate why?
try doing styled(View) instead of styled.View
Not sure if this is going to be helpful to anyone but for me the same error was triggered like this style.something and fixed using an html element eg style.span

Splitting React components into separate files

This seems to be a common question, I'm finding a lot of people asking it and the responses are all very different and seem to be a bit hit and miss. I've watched various video tutorials, read plenty of tutorials, and the documentation. But alas it seems React is moving faster than the writers can keep up with. Or I'm just misunderstanding.
I want to create each component in a separate file, where logical to do so. I have React working, but am unable to work out how to import and use additional files. I don't know if this is because Chrome will not load in files when not on a web server (local test dev), or if I'm just going about it all wrong.
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Test One</title>
</head>
<body>
<div id="rootNode"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
And here is my main.js:
var React = require('react');
var ReactDOM = require('react-dom');
var Square = require('../components/square.jsx').square;
ReactDOM.render(
<div>
<h1>Hello React!</h1>
<Square />
</div>,
document.getElementById('rootNode')
);
This works fine if I don't try to use Square also.
This is my square.jsx:
class Square extends React.Component{
render() {
return (
<p>Square</p>
)
}
}
module.exports = {
square: Square
};
Babel create the bundle.js fine, no errors. Chrome throws the error:
Uncaught SyntaxError: Block-scoped declarations (let, const, function,
class) not yet supported outside strict mode
I have tried the following also for square, along with many other things, all lost from the undo queue:
import React from 'react';
class Square extends React.Component{
render() {
return (
<p>Square</p>
)
}
}
export default Square;
All help appreciated. React seems to make sense aside from separating out the class files.
Thanks.
EDIT:
Also tried:
var {Component} = React;
class Square extends Component{
render() {
return (
<p>Square</p>
)
}
}
window.Square = Square;
And if it helps here is the Gulp file:
var vendors = [
'react'
];
gulp.task('vendors', function () {
var stream = browserify({
debug: false,
require: vendors
});
stream.bundle()
.pipe(source('./src/main.js'))
.pipe(gulp.dest('./dist/bundle.js'));
return stream;
});
And the package.json:
{
"name": "reacttestone",
"version": "1.0.0",
"description": "Testing React Components",
"main": "index.js",
"dependencies": {
"babel-preset-react": "^6.1.2",
"babelify": "^7.2.0",
"react": "^0.14.2",
"react-dom": "^0.14.2"
},
"devDependencies": {
"gulp": "^3.9.0",
"vinyl-source-stream": "^1.1.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Myself",
"license": "MIT"
}
Your es6 example of exporting like export default Square should work fine. It looks like you've installed babelify but you're not using it in the transform process, hence why the browser is complaining that you're trying to use es6 features outside of strict mode.
If you look at the babelify instructions it says to do something like:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var gutil = require('gulp-util');
gulp.task('browserify', function () {
browserify('./src/main.js', { debug: true })
.transform('babelify', {presets: ['es2015', 'react']})
.bundle()
.on('error', gutil.log)
.pipe(source('bundle.js'))
.pipe(gulp.dest('./dist'))
});
gulp.task('watch',function() {
gulp.watch('./src/**/*.js', ['browserify'])
});
It looks like you only have babel-preset-react installed, you'll need to do npm i babel-preset-es2015 --save-dev. Also babelify and babel-preset-react are fine as devDependencies.

Categories