Global Variables : Stylus Vue Vite

2.5k Views Asked by At

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"
  }
}
2

There are 2 best solutions below

1
ymz On

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)

3
DVN-Anakin On

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