Importing SCSS variables in Vue components - vue.js

I recently switched from Vue-CLI to laravel-mix, the usage of SCSS variables worked perfectly with Vue-CLI and now doesnt seem to work anymore at all after I switched to laravel-mix.
Vue-CLI just handled everything for me and I feel like I have to configure something to get the variables to work in laravel-mix.
This is what I've tried (and what worked with Vue-CLI):
// vue component
import variables from "#/styles/variables.scss";
// ...
data() {
return {
variables
}
}
methods: {
test() {
console.log(this.variables)
}
}
// scss
$variable: #FFFFFF;
:export {
variable: $variable;
}
Edit: To clarify, this log outputs an empty object, not undefined.

For this thing to work you need to follow that particular steps
Make Your Variables File. As you made your scss file inside your style its not good you need to make inside /assets/sass/
Add Variables File To App.scss. For that thing you need to import newly create file inside your app.scss by #import 'folder/file';
Add Alias To webpack.mix.js. What we essentially need to do is define an alias or variable that contains the path to our sass directory so we can include that SASS in our Vue components. Just add alias like this in your webpack
resolve: {
alias: {
'#': path.resolve('resources/assets/sass')
}
}
Last thing add Navigation Vue Component. You can import scss variables by adding #import '~#/folder/fie.scss'; in the vue component

Related

How to bundle tailwind css inside a Vue Component Package

In one of my projects, I build a nice vue3 component that could be useful to several other projects. So I decided to publish it as an NPM package and share it with everyone.
I wrote the isolate component, build it and publish BUT I use Tailwind css to make the style.
When I publish and install the component everything is working BUT without the beauty of the css part.
I tried several configurations and alternative tools to generate the package that automatically add the tailwind as an inner dependency to my package.
Does someone have experience with this? how can build/bundle my component by adding the tailwind CSS instructions into it?
You're almost there
Since you've got your component working, the majority of the part has been done.
For configuring the styling of the component you need to identify the Tailwind CSS classes being used by your Vue component package and retain them in the final CSS that is generated by the Tailwind engine in your project.
Follow below steps in the project where you want to use your tailwind vue component package.
For Tailwind CSS V3
// tailwind.config.js
module.exports = [
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
]
For Tailwind CSS V2
// tailwind.config.js
module.exports = [
//...
purge: {
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
//...
}
]
The content property in the tailwind.config.js file defines file path pattern that the tailwind engine should look into, for generating the final CSS file.
For Pro users
You may also try to automate the above setup by writing an install script for your npm package to add this configuration to the tailwind.config.js file
References
Tailwind Docs - 3rd party integration
It's a bit difficult for someone to answer your question as you've not really shared the source code, but thankfully (and a bit incorrectly), you've published the src directory to npm.
The core issue here is that when you're building a component library, you are running npm run build:npm which translates to vue-cli-service build --target lib --name getjvNumPad src/index.js.
The index.js reads as follows:
import component from './components/numeric-pad.vue'
// Declare install function executed by Vue.use()
export function install (Vue) {
if (install.installed) return
install.installed = true
Vue.component('getjv-num-pad', component)
}
// Create module definition for Vue.use()
const plugin = {
install
}
// Auto-install when vue is found (eg. in browser via <script> tag)
let GlobalVue = null
if (typeof window !== 'undefined') {
GlobalVue = window.Vue
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue
}
if (GlobalVue) {
GlobalVue.use(plugin)
}
// To allow use as module (npm/webpack/etc.) export component
export default component
There is no mention of importing any CSS, hence no CSS included in the built version.
The simplest solution would be to include the index.css import in your index.js or the src/components/numeric-pad.vue file under the <style> section.
Lastly, I'm a bit rusty on how components are built, but you might find that Vue outputs the CSS as a separate file. In that case, you would also need to update your package.json to include an exports field.

Can't access CSS variables in script tag of Vue file

Problem
I am trying to access variables defined within an SCSS file from a .vue file. The project is using vue-cli.
According to Vue's docs:
"Vue CLI projects comes with support for PostCSS, CSS Modules and pre-processors including Sass, Less and Stylus."
However, if I create a variables.css file with a variable called variable, and try to import it within the script, this variable is not found.
styles/variables.module.css
$variable: 'foo';
:export {
variable: $variable
}
App.vue
<script>
import variables from "./styles/variables.module.scss";
export default {
name: "App",
methods: {},
computed: {
variable() {
console.log(variables); // Object {}
return variables.variable || "not found";
}
}
};
</script>
Importing the variables.css file within the <style module> tag of the same vue file does work however.
App.vue
<style module lang="scss">
#import "./styles/variables.module.scss";
:export {
variable: $variable;
}
</style>
What I'm trying to achieve
<p>Importing within <script>, the variable is {{variable}}</p>
// 'not found', should be "foo"
<p>Importing within <style>, the variable is {{$style.variable}}</p>
// correctly showing "foo"
Have tried:
Adding .module to the SCSS file name (as per vue's docs)
Creating a vue.config.js file with requireModuleExtension: false
(from same docs)
Reproducible demo
https://codesandbox.io/s/importing-css-to-js-o9p2b?file=/src/App.vue
You need to add webpack and CSS modular code into webpack.config.js.
npm install -D vue-loader vue-template-compiler webpack
Here is the working demo
Note: your vue-template-compiler and vue should be the same version

Overriding Vuetify variables

I'm using Vuetify in my project, and I want to use a variable file to override the styles generated by Vuetify.
I'm loading the components and their corresponding styles using the a-la-carte method, so I'm NOT importing the Vuetify SASS file using this:
#import '~vuetify/src/styles/styles.sass'
// Not using this method because I don't want to generate styles that are not being used by
// vuetify components I'm not using
Also, my project is using *.scss, not *.sass.
I'm also injecting a global SCSS file containing mixins and other variables in my vue.config.js:
css: {
sourceMap: productionSourceMap,
loaderOptions: {
scss: {
prependData: `#import '#/scss/_common.scss';`
}
}
},
I included a Vuetify variable, $border-radius-root, in that common.scss file, but it doesn't seem to have any effect.
Any idea how to do what I want without having to write entirely new CSS rules to override Vuetify's generated stylesheet? Basically I want to change the units that Vuetify uses using their own stylesheet generator.
Actually the solution is, and I'm dumb for not thinking of this before, to add another loader to vue.config.js:
css: {
sourceMap: productionSourceMap,
loaderOptions: {
scss: {
prependData: `#import '#/scss/_common.scss';`
},
sass: {
prependData: `#import '#/sass/_vuetify-variables.sass';`
}
}
},
Since vuetify is using sass as the css pre-processor, it needs sass-loader to handle the variable overrides and apply it to the framework.
If you are using Nuxt:
you can add customVariable path in your nuxt.config.js file, in vuetify object
Note you have to enable treeShake. This option is required for custom SASS variables to work
example:
vuetify: {
// usually file should be in assets folder
customVariables: ['~/path/to/variables.scss'],
treeShake: true,
}
If you are using Vue CLI:
Create a folder with name: sass, scss, or styles
Create new file inside this folder and name it: variables.scss or variables.sass
vuetify-loader will automatically bootstrap your variables into Vue CLI’s compilation process, overwriting the framework defaults.
From Vuetify docs:
If you have not installed Vuetify, check out the quick-start guide. Once installed, create a folder called sass, scss or styles in your src directory with a file named variables.scss or variables.sass. The vuetify-loader will automatically bootstrap your variables into Vue CLI's compilation process, overwriting the framework defaults.
So, the vuetify-loader automatically loads #/scss/variables.scss in a Vue CLI project, so you could set $border-radius-root in that file, and it will overrride the framework default.

How to import whole SCSS folder in Vue Nuxt project?

At my company we are not writing css in Vue files, we prefer to do it the old way with SCSS.
Problem is, we end up with a need of writing new import in styles.scss any time we create new component, and it really bugs me in bigger projects.
Not so long ago, when I have been developing in React, I imported module called node-sass-glob-importer in webpack.config file, tweaked a bit (you can check here) and it worked - I could have imported folder like this: #import "components/**";
In Nuxt, I only have nuxt.config.js file and I am lost a bit. I know how to extend some simple stuff there, but this seems to be more complicated.
Any help of importing node-sass-glob-importer or doing the same thing in some other way?
how about using https://github.com/nuxt-community/style-resources-module and than:
export default {
modules: ['#nuxtjs/style-resources'],
styleResources: {
scss: [
'./assets/yourFolder/*.scss'
]
}
}
You can use node-sass-glob-importer in Nuxt like this:
nuxt.config.js:
const globImporter = require('node-sass-glob-importer');
export default {
...
css: [
'~/assets/scss/global.scss'
],
...
build: {
extend(config, {loaders: {scss}}) {
const sassOptions = scss.sassOptions || {};
sassOptions.importer = globImporter();
scss.sassOptions = sassOptions;
}
}
}
global.scss:
#import "./assets/scss/base/*";
#import "./assets/scss/components/*";
styleResources is used for things like variables, mixins and functions that you want to use anywhere in your SCSS without having to import the files.

Vue SFC add global Sass variables to all components

Im my webpack config I add a path
"mixins": path.resolve(
__dirname,
"resources/assets/sass/mixins/mixins.scss"
),
Which means in all my single file components I use
<style lang='scss' scoped>
#import '~variables';
This works fine but what I am finding is this file is used in 95% of components so the import really is unnecessary. I want these vars available everywhere.
How can I globally add my SASS to my single file components without the need for the import in every file?
Well, Load your common CSS from Webpack and make it available globally for all the component. Webpack configurations are as below.
sass-loader also supports a data option which allows you to share common variables among all processed files without having to explicit import them
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
#import "#/scss/_variables.scss";
#import "#/scss/_mixins.scss";
`
}
}
}
};
In here, specifing the sass loader under the loaderOptions option. Just like that, all the code in those files will be available in the global scope. So from any component we can use it out of the box:
And now you can able to access the variable in your Vue SFC without importing it.
<style lang="scss">
.classroom {
/* No need to import, it just works \o/ */
background: $bg-classroom;
}
</style>
Reference Official Docs here
Hope this helps!