How to setup SASS in VueJS project (vue-cli, no webpack config) - css

My Repo: https://github.com/leongaban/VueJS-RobotBuilder
The course I'm following: https://app.pluralsight.com/player?course=vuejs-fundamentals&author=jim-cooper
This is after I already set it up. Did not remember if there was a sass option.
Anyways currently running into this error:
Invalid CSS after "<": expected 1 selector or at-rule, was ""
I replaced my old <style> CSS stuff here </style>
With:
<style lang="scss">
#import "_robotBuilder.scss";
</style>
I also installed the following packages, but I don't see a webpack config file I can edit.
"node-sass": "^4.11.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",

Just fixed my problem.
I removed this:
<style lang="scss">
#import "_robotBuilder.scss";
</style>
Thought it was strange that an import would exist inside a style tag anyways.
Then I cleaned up the .scss file and then just used this import statement inside of the <script> section.
import './_robotBuilder.scss';
Update
Just learned you can scope the <style scoped> tag so styles only apply to the component.

My app.vue (main container) has only this in the style tags
<style lang="scss">
#import url('https://fonts.googleapis.com/css?family=Lato:300,400,400i,700,900&subset=latin-ext');
#import "#/scss/style.scss";
</style>
and works just fine.
And this in the vue.config.js
const path = require("path");
module.exports = {
baseUrl: '/',
outputDir: undefined,
assetsDir: 'assets',
runtimeCompiler: undefined,
productionSourceMap: undefined,
parallel: true,
css: {
modules: false,
loaderOptions: {}
}
}
Turning off the CSS Modularization "might" have something to do with making it work with the imports...

Related

Use Sass in Saber

Goal
I'd rather enjoy using Sass in the Saber framework, which it supports. Here are the docs for it if you wish. Simple, right?
Problem
You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser
My code is extremely vanilla at this stage.
Context
I did this:
yarn add sass-loader sass --dev
And initially did that:
// saber-config.js
module.exports = {
build: {
loaderOptions: {
sass: {
data: `#import "#/scss/main.scss";`
}
}
}
}
...which resulted in no styles. M'kay. So I removed that part and imported the styles directly into the layout component, like so—
<!-- layouts/page.vue -->
<style lang="scss">
#import url('../scss/main.scss');
</style>
That's the point at which the aforementioned error occurs. What's also interesting is that if I move the Sass code from main.scss to the page.vue <style> tags, it works.
Turns out is was a Sass version issue. I resolved it by bumping down a version.
"devDependencies": {
"saber": "^0.11.7",
"saber-plugin-feed": "^0.4.3",
"saber-plugin-query-posts": "^0.4.6",
"sass": "^1.22.12",
"sass-loader": "^8.0.0"
}

Creating Critical CSS files from compiled .scss

Looking to improve page speed by using rel="preload" to specify the order in which CSS files should be loaded on our site. The idea is that we would preload our global styles and then preload our hero area styles (as this is the most important element on the page to our marketing team).
We use Sass and follow a pretty typical set-up where each component or module on our site is chunked out into it's own partial .scss file and then imported (#import) into our main styles.scss file.
We compile the styles.scss file via Gulp into a single minified CSS file that contains all of the styles for the site (styles.min.css)
Example: current styles.scss file
//Shared Global Styles
#import "partials/reset"
#import "partials/variables"
#import "partials/typography"
//Individual Components and Modules
#import "partials/buttons"
#import "partials/cards"
etc...
This is what the Sass tasks in our Gulpfile look like:
gulp.task('styles:sass', ['svg'], function() {
const outputStyle = 'expanded';
const path = (watching) ? devCSSPath : buildCSSPath;
const building = (watching) ? false : true;
return gulp.src(['src/sass/*.scss', 'src/apps/*/styles/*.scss'])
.pipe(gulpif(watching, sourcemaps.init()))
.pipe(sass({
outputStyle: outputStyle,
includePaths: [kdsRoot] }).on('error', sass.logError))
.pipe(gulpif(watching, sourcemaps.write('maps')))
.pipe(gulpif(building, rename((path) => {
path.basename += ".min";
})
))
.pipe(gulp.dest(path));
});
gulp.task('styles:postcss', ['styles:sass'], function() {
const path = (watching) ? devCSSPath : buildCSSPath;
const plugins = [
autoprefixer({ grid: true}),
pixelsToRem({ base: 16 })
];
return gulp.src([path + '*.css', path + '**/*.css'],{base: './'})
.pipe(postcss(plugins))
.pipe(gulp.dest('./'))
});
I want to create 3 different stylesheets (2 of which I will preload):
globals_preload.scss
//Shared Global Styles
#import "partials/reset"
#import "partials/variables"
#import "partials/typography"
hero_preload.scss
//Styles for the hero module
#import "partials/hero"
styles.scss
//Styles for the rest of the components/modules
//Global .scss files removed
//Individual Components and Modules
#import "partials/buttons"
#import "partials/cards"
etc...
I would ideally load the 3 stylesheets like so:
<head>
<link rel="preload" href="globals_preload.min.css" as="style">
<link rel="preload" href="hero_preload.min.css" as="style">
<link rel="stylesheet" href="styles.min.css">
</head>
Here lies the problem; Every component or module is dependent on the global styles and variables, but I don't want to load the global styles twice (by having them imported both in globals_preload.scss and styles.scss); If I remove the import statements for the global styles from style.scss my compiler will fail because the subsequent modules will not be able to find the sass variable they are looking for.
Is there anyway for this approach to work with Sass? Is there a way to remove certain partials from the compiled CSS via Gulp? I'm open to any suggestions.

How to include local (not global) stylesheet file for each layout in Nuxtjs

Is it possible to import css-files to a separate layout so that styles are applied only to one layout without affecting others?
I found this solution.
Rename ".css" files to ".scss".
In your layout add the wrapper block with custom class "my-class".
layouts/AuthLayout:
<template>
<div class="auth-layout">
<section>
<Nuxt/>
</section>
</div>
</template>
Then add a style section. This uses SCSS features and the v-deep directive.
layouts/AuthLayout:
<style scoped lang="scss">
.auth-layout {
&::v-deep {
#import '~assets/path/to/style.scss';
#import '~assets/path/to/custom.scss';
// ...
}
}
</style>
I hope it would be helpful for somebody.
If your style files have .css extension you can put them on static directory and address in your layout head function or object in this way (my file is in static/css/main.css directory)
return {
link: [
//you shouldn't mention ~/static itself
{ rel: 'stylesheet', href: '/css/main.css' },
],
};
if your file has .scss extension or any other preprocessor you can put it in assets directory cause webpack compile files on this directory.

Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected

I am trying to import "../../node_modules/react-quill/dist/quill.snow.css"; in my next.js project but I get following error
[ error ] ./node_modules/react-quill/dist/quill.snow.css
Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to pages/_app.js.
Read more: https://err.sh/next.js/css-global
Location: components\crud\BlogCreate.js
I managed to make it work with next.config.js. It worked with this configuration
// next.config.js
const withCSS = require('#zeit/next-css');
module.exports = withCSS({
cssLoaderOptions: {
url: false
}
});
But now I am getting a warning,
Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected.
See here for more info: https://err.sh/next.js/built-in-css-disabled
It seems my solution is not the best way to solve this problem. How could I get rid of this warning?
You may remove the #zeit/next-css plugin because the Next.js 9.3 is very simple. Then Next.js 9.3 is Built-in Sass Support for Global Stylesheets after removing the #zeit/next-css you may install
npm install sass
Then, import the Sass file within pages/_app.js.
Global CSS
Import any global CSS in the /pages/_app.js.
import '../styles.css'
// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
Importing CSS in components or pages won't work with the built-in CSS support.
Component CSS
Next.js supports CSS Modules using the [name].module.css file naming convention.
components/Button.module.css
/*
You do not need to worry about .error {} colliding with any other `.css` or
`.module.css` files!
*/
.error {
color: white;
background-color: red;
}
components/Button.js
import styles from './Button.module.css'
export function Button() {
return (
<button
type="button"
// Note how the "error" class is accessed as a property on the imported
// `styles` object.
className={styles.error}
>
Destroy
</button>
)
}
CSS Module files can be imported anywhere in your application.
Third-party CSS on Component / Page level
You can use <link> tag in the component.
const Foo = () => (
<div>
<link
href="third.party.css"
rel="stylesheet"
/>
</div>
);
export default Foo;
The loaded stylesheet won't be automatically minified as it doesn't go through build process, so use the minified version.
If none of the options doesn't fit your requirements consider using a custom CSS loader like #zeit/next-css.
In that case you will see a warning which is fine:
Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected.
See here for more info: https://err.sh/next.js/built-in-css-disabled
Suggested reading:
Next.js Built-In CSS Support
Global SASS
CSS Modules
Install sass module by running following command.
npm install sass
You then need to remove all css-loader and sass-loader configuration from next.config.js.
For example, I had to remove the withSass() function (in your case withCSS()) and just return the configuration object.
Had to remove the following lines from next.config.js
{
test: /\.scss$/,
use: {
loader: "sass-loader",
options: {
data: '#import "./scss/_variables.scss"',
sourceMap: true,
},
},
}
Move your options to sassOptions in next config file.
sassOptions: {
data: '#import "./scss/_variables.scss"',
sourceMap: true,
}
Also remove the old #zeit/next-sass and #zeit/next-css from package.json
I had to remove following #zeit dependency from my package.json
"dependencies": {
"#zeit/next-sass": "1.0.1",
This worked for me.
For more details, visit https://nextjs.org/docs/basic-features/built-in-css-support

Best way to have global css in Vuejs

What is the best way to have a global css file in Vuejs for all components? (Default css like bg color, button styling, etc)
import a css file in the index.html
do #import in main component
put all the css in the main component (but that would be a huge file)
Import css in your index.html, but if you're using webpack you can just import your stylesheets in your main js config and all your components will get the css.
As comments below suggested if using webpack adding this to main.js works:
import './assets/css/main.css';
I found the best way is to create a new file in the assets folder, I created as global.css but you can name anything of your choice. Then, import this file global.css file in the main.js.
Note: Using this approach you can also create multiple files if you think the global.css is getting really large then simply import all those files in the main.js.
#\assets\global.css
/* move the buttons to the right */
.buttons-align-right {
justify-content: flex-end;
}
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './routes'
Vue.config.productionTip = false
// Importing the global css file
import "#/assets/global.css"
new Vue({
router,
render: h => h(App)
}).$mount('#app')
In App.vue you can add a style property to declare you CSS file:
<style>
#import './assets/css/global.css';
</style>
You can also do something like this: https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/
My folders are mostly structured like this:
- src
- assets
- _global.scss
- _colors.scss
- _fonts.scss
- _paragraphs
- index.scss // <-- import all other scss files.
This also works with normal css.
create a new css file in your assets folder for example : global.css
import "global.css" to main.js
import '#/assets/main.css';
There are to two ways, as I know, to achieve this.
Approach 1
Utilize vue.config.js configuration, less config can also be replaced with sass:
module.exports = {
css: {
loaderOptions: {
less: {
additionalData: `#import '#/style/common.less';`
}
}
}
}
Approach 2
In your .vue file, make your style looks like this:
<style lang="less">
#import (reference) "../../style/variables.less";
#app {
background: #bgColor;
}
</style>
Note: the (reference) flag is used to make variables defined in variables.less take effect. If you don't have variables, #import "../../style/variables.less"; is sufficient to do the trick.
For your reference, you can also take a look at this link:
https://github.com/tjcchen/vue-practice/tree/master/multipage-app
Sass announced their new module system. Why don't you use #use and #forward?
My approach is the best way to use scss with vite.
Use defineConfig to setup global scss (colors, mixin) and reuse in all component without import
css: {
preprocessorOptions: {
scss: {
additionalData: `#use "~/styles/main.scss" as *;`,
},
},
},
Here: code sandbox
create a vue.config.js file in your root directory
Create a styles folder inside your src folder and you can create your global style file here for example base.scss
to use scss install two dependencies
npm install node-loader sass-loader
Inside your vue.config.js paste code from below
module.exports = {
css: {
loaderOptions: {
sass: {
additionalData: `#import "#/styles/base.scss";`
}
}
}
};

Resources