React & Next.js - Added a SCSS parser and tried adding CSS to webpack module config, but it doesn't live-reload, why? - css

In my package.json I've changed a few things:
"scripts": {
"build-css": "node-sass-chokidar ./static/style.scss ./static/style.css",
"watch-css": "npm run build-css && node-sass-chokidar ./static/style.scss ./static/style.css --watch --recursive",
"dev": "npm-run-all -p watch-css next",
"next": "next",
"build": "next build",
"start": "next start"
},
Because I much prefer a single SASS file containing all styles, until a solution is found to make a require('./style.scss'); work server-side and client-side.
The stylesheet is parsed and output as a single CSS-file while developing, just fine. I just need to reload the entire page to see my changes. That's a little bit of a drag, of course.
So I created a next.config.js file and added this:
const path = require('path');
const glob = require('glob');
const node_modules_dir = path.resolve(__dirname, 'node_modules');
module.exports = {
webpack: (config, { dev }) => {
config.module.rules.push(
{
test: /\.(css|scss)/,
exclude: [node_modules_dir],
loaders: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
);
return config
}
};
And next.js is running in my terminal just fine, and the SCSS-file is parsed into a CSS-file just fine, too. Just, no client-side live-reload. I was expecting adding this to the config file would be sufficient to live-reload a CSS-file.
In my components/Page I've added this line:
<Head>
<title>{title}</title>
<link rel="stylesheet" type="text/css" href="/static/style.css" />
</Head>
But I'm not too familiar with hot-reload/live-reload inner workings.
What am I doing wrong?

Related

Vite and VueJS3 and .mount('#app'); NOT WORKING

I've been reading on the internet, all foruns and communities that are some issues with Vite+VueJS3 at the .mount("#app") point.
I am facing this exactly problem and can't figure how to fix it!
Uncaught DOMException: String contains an invalid character pointing to app.mount('#app'); at app.js.
Let's see some code:
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js',
},
},
});
app.js
import { createApp } from 'vue';
import Lead from './components/Lead.vue';
import Atendimento from './components/Atendimento.vue';
const app = createApp({
components: {
Lead,
Atendimento,
render: h => h(app)
}
});
app.component('atendimento', Atendimento);
app.component('lead', Lead);
app.mount('#app');
The app.blade.php witch all Blade extends has the <div id="app"> clearerly, so there is no problem (I guess) with disposition of the script.
You can see, at vite.config.js that there are a alias pointing to the dev compiler:
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js',
},
},
Right now I am pulling all my hair out of my head!
Can anyone help me?
Thanks in advance!
Since I couldn't solve this issue, I decided to migrate from Vite to Laravel-mix and used ChatGPT to help.
Check this out:
Here are the steps to migrate from ViteJS to Laravel-mix in a Laravel project:
Install Laravel-mix by running npm install laravel-mix.
Create a new file, webpack.mix.js at the root of your project.
Copy the following code into webpack.mix.js:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
In your package.json file, change the scripts section from:
"scripts": {
"dev": "vite",
"build": "vite build"
}
to:
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}
Remove the vite.config.js file, since Laravel-mix uses the webpack.mix.js file to configure webpack
Remove the vite package by running `npm uninstall vite`
Test the migration by running npm run dev and verify that your JavaScript and CSS assets are being compiled as expected.
That's it! You have successfully migrated from ViteJS to Laravel-mix.
The problem for a production-build seems to be the place there the #vite is included.
Change your app.blade to this and it will work.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How To Install Vue 3 in Laravel 9 with Vite</title>
</head>
<body>
<div id="app">
</div>
#vite(['resources/css/app.css', 'resources/js/app.js'])
</body>
</html>

Is it normal that tailwind.config.js, vite.config.js are in root folder of Laravel 9?

Fresh install of Vite and Tailwind results in tailwind.config.js, postcss.config.js and vite.config.js in the root folder of Laravel 9.
Is this expected? I want to organize these file into the existing resources/js folder. Where do I update references to these files to avoid breaking things?
Yes this is the default behaviour.
You can change the location of your vite.config.js to any location you want by using the --config flag in your package.json script:
"scripts": {
"dev": "vite --config custom/location/vite.config.js",
"build": "vite build --config custom/location/vite.config.js"
},
In the vite.config.js you can change the tailwind.config.js and remove the need for your postcss.config.js entirely like this:
...
css: {
postcss: {
plugins: [
require("tailwindcss")({
config: "custom/location/tailwind.config.js",
}),
require("autoprefixer"),
],
},
},

Tailwind will not purge

I am trying to get tailwind to purge CSS on my files, but I can't seem to get it working.
To provide some context, I have a public folder that contains a CSS folder and a views folder. I am trying to purge the single ejs file within the views folder.
Here is my tailwind.config.js
module.exports = {
purge: {
enabled: true,
content: ['./public/**/*.ejs']
},
theme: {},
variants: {},
plugins: [],
}
Here is my postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
Here is my script I'm running from my package.json
"tw-prod": "tailwind build public/css/tailwind.css -o public/css/style.css"
I have also tried the following, without any luck
"tw-prod": "postcss public/css/tailwind.css -o public/css/style.css"
And finally here is some code from my app.js which may help diagnose my problem
app.use(express.static("public"));
app.set("view engine", "ejs");
app.set('views', path.join(__dirname, '/public/views'));
Each time I run the build script, the size of the stylesheet remains the same at 3.81mb. Can anyone tell me what I'm doing wrong here, please?
Did you try running the script with NODE_ENV=production?
like
NODE_ENV=production npx tailwindcss -i ./src/tailwind.css -o ./dist/tailwind.css
EDIT:
Instead of running
"tw-prod": "tailwind build public/css/tailwind.css -o public/css/style.css"
run this
"tw-prod": "NODE_ENV=production tailwind build public/css/tailwind.css -o public/css/style.css"
Tailwind requires the NODE_ENV to be set for the purge function to kick in and do its job.
Read more about this here
PS: BTS postcss file now comes configured by default that I guess takes care of this purging functionality

Add SCSS support to Vue project

In my packages.json file by default I get:
"postcss": {
"plugins": {
"autoprefixer": {}
}}
When I add <style lang='scss'> It doesn't compile like magic like it does for Typescript support. I know I will need to specify some NPM package as devDependencies and specify something above in the postcss section to get scss to compile, but I can't find any documentation outside of webpack so I am lost.
See https://vue-loader.vuejs.org/guide/pre-processors.html.
For example, to compile our <style> tag with SASS/SCSS:
npm install -D sass-loader node-sass
In your webpack config:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
Now in addition to being able to import 'style.scss', we can use SCSS
in Vue components as well:
<style lang="scss"> /* write SCSS here */ </style>
Any content inside the block will be processed by webpack as if it's
inside a *.scss file.

How to get Tailwind.css working with Gatsby.js?

Has anyone managed to get Tailwind.css working with Gatsby.js?
Configuring postCSS plugins with Gatsby is a bit tricky... If anyone has managed to get Tailwind up and running with Gatsby, I'd love to know how!
I managed to get this working (including hot reloading) thanks to this post.
Basically I had to install postcss and autoprefixer additionally:
npm install autoprefixer postcss-cli
I added a postcss.config.js to the root of my Gatsby site folder with this content (tailwind.js is my Tailwind config - yours might be named differently):
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
tailwindcss('./tailwind.js'),
require('autoprefixer'),
],
};
Then I added a CSS watch and build script to my package.json, and included these scripts in my default develop and build scripts:
"scripts": {
"build:css": "postcss src/layouts/index.css -o src/layouts/generated.css",
"watch:css": "postcss src/layouts/index.css -o src/layouts/generated.css -w",
"build": "npm run build:css && gatsby build",
"develop": "npm run watch:css & gatsby develop",
...
}
(Please note the input (index.css) and output (generated.css) filenames and locations for my css are specific to my project. Feel free to use your own convention.)
Let me know, if this works for you.
As a supplement to morgler's answer, here is a similar solution I ended up with (which includes Sass and PurgeCSS).
I went with a CLI solution because gatsby-plugin-postcss-sass currently runs PostCSS before Sass (which breaks Tailwind), and Gatsby's PostCSS plugins are a bit difficult to configure via Webpack at the moment.
I included Sass so I can break main.sass into more manageable partials, and added PurgeCSS so I can remove any unused Tailwinds classes in production. I've found that PurgeCSS is more effective than PurifyCSS, which is why I opted not to use gatsby-plugin-purify-css.
To begin, create a src/styles folder with the following structure (feel free to customize this for your project and adapt the settings below accordingly):
src/
styles/
builds/
after-postcss/
main.css
after-purgecss/
main.css
after-sass/
main.css
// other subfolders for sass partials...
main.sass
Install the necessary dependencies:
npm i node-sass-chokidar postcss-cli purgecss
Add the following to gatsby-node.js (to disable Gatsby's default PostCSS plugins):
const ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.modifyWebpackConfig = ({ config, stage }) => {
switch (stage) {
case 'develop':
// Remove postcss from Gatsby's dev process:
config.removeLoader(`css`)
config.loader(`css`, {
test: /\.css$/,
loaders: [`style`, `css`]
})
break
case 'build-css':
// Remove postcss from Gatsby's build process:
config.removeLoader(`css`)
config.loader(`css`, {
test: /after-purgecss\/main\.css/,
loader: ExtractTextPlugin.extract([`css?minimize`])
})
break
}
return config
}
Add a postcss.config.js file to the project root:
const tailwind = require('tailwindcss')
const cssnext = require('postcss-cssnext')
module.exports = {
plugins: [
// your file's name or path may differ:
tailwind('./src/styles/tailwind.config.js'),
cssnext()
// add any other postcss plugins you like...
]
}
Add the following scripts to package.json:
"scripts": {
"watch:sass": "node-sass-chokidar --source-map true src/styles/main.sass -o src/styles/builds/after-sass -w",
"watch:postcss": "postcss src/styles/builds/after-sass/main.css -o src/styles/builds/after-postcss/main.css -w",
"watch:styles": "npm run watch:sass & npm run watch:postcss",
"build:sass": "node-sass-chokidar src/styles/main.sass -o src/styles/builds/after-sass",
"build:postcss": "postcss src/styles/builds/after-sass/main.css -o src/styles/builds/after-postcss/main.css",
"build:purgecss":
"purgecss --css src/styles/builds/after-postcss/main.css --con public/index.html src/**/*.js -o src/styles/builds/after-purgecss",
"build:styles": "npm run build:sass && npm run build:postcss && npm run build:purgecss",
"develop": "gatsby develop & npm run watch:styles",
"build": "npm run build:styles && gatsby build"
// ...
},
In development, run npm run develop instead of gatsby develop. The watch: scripts will run Sass + PostCSS (in that order) whenever a change is made to main.sass or any of its imports.
To build the site, run npm run build instead of gatsby build. The build: scripts will run Sass + PostCSS (without the watch tasks) + PurgeCSS (in that order).
Add the following to layouts/index.js to import the after-postcss version of main.css during development and the after-purgecss version during production:
switch (process.env.NODE_ENV) {
case `development`:
require('../styles/builds/after-postcss/main.css')
break
case `production`:
require('../styles/builds/after-purgecss/main.css')
break
}
Hope that helps someone! If anyone knows how to convert this into a Webpack equivalent that works with Gatsby, please feel free to post it here.
I recently added it on top of the Gatsby starter default and wrote a detailed step by step guide.
https://www.michaelfasani.com/2020/installing-tailwind-css-on-top-of-the-gatsby-starter-default/
That's my setup and is working perfectly fine with Gatsby:
tailwind.config.js
module.exports = {
mode: "jit",
purge: [
"./src/pages/**/*.{js,ts,jsx,tsx}",
"./src/components/**/*.{js,ts,jsx,tsx}",
],
package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"tw:build": "tailwindcss build ./src/styles/global.css -o ./public/styles/global.css",
"tw:prod": "cross-env NODE_ENV=production postcss build ./src/styles/global.css -o ./public/styles/global.css",
"tw:watch": "onchange \"tailwind.config.js\" \"src/**/*.css\" -- npm run tw:build"
},
You can also use cssnano it's an awsome extension for purging tailwind css
postcss.config.js
const cssnano = require("cssnano");
module.exports = {
plugins: [
require("tailwindcss"),
cssnano({
preset: "default",
}),
require("autoprefixer"),
],
};
Also the devDependencies that are needed for the latest Tailwind version are these:
package.json devDependencies
"devDependencies": {
"autoprefixer": "^10.3.6",
"gatsby-plugin-postcss": "^4.14.0",
"postcss": "^8.3.9",
"postcss-cli": "^9.0.1",
"tailwindcss": "^2.2.17"
}
}
Also make sure to include these on top of the global.css file:
#tailwind base;
#tailwind components;
#tailwind utilities;

Resources