Laravel vite config using separate tailwind.config files for admin and site - laravel

With Laravel Mix I'm generating two different css/js files for Admin and for the main site like this:
const mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');
mix.js('resources/js/site/app.js', 'public/js')
.postCss('resources/css/site/app.css', 'public/css', [
require('autoprefixer'),
require('postcss-import'),
tailwindcss('./tailwind.site.config.js'),
])
.options({
processCssUrls: false,
}).version();
mix.js('resources/js/admin/app.js', 'public/_admin/js')
.postCss('resources/css/admin/app.css', 'public/_admin/css', [
require('autoprefixer'),
require('postcss-import'),
tailwindcss('./tailwind.admin.config.js'),
])
.options({
processCssUrls: false,
}).version();
How can I tell vite to do the same thing ??
Thanks!!
The default vite.config.js is
import { defineConfig } from 'vite';
import laravel, { refreshPaths } from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: [
...refreshPaths,
'app/Http/Livewire/**',
],
}),
],
});

Create two vite.config.js files, and also create two tailwind.config.js files for frontend & backend.
I have already posted this solution on github with demo laravel project.
https://github.com/pkfan/setup-laravel-vite-for-multiple-tailwind.config.js
I have upload a video about it.
watch this video on youtube

See https://laravel-vite.dev/guide/extra-topics/multiple-configurations.html.
You will need to add a configuration to config/vite.php, create a new vite.back-office.config.ts file, pass the configuration name to the #vite directive and run slightly different development and build commands.
The docs are TypeScript-focused, but the same technique will work for your JS/CSS assets.

Starting with Tailwind CSS v3.2, hacky workarounds are no longer needed.
You can now define the config file to use inside of your CSS files:
https://tailwindcss.com/blog/tailwindcss-v3-2#multiple-config-files-in-one-project-using-config

Related

Multiple Tailwind CSS Configs

I am building a project using Laravel/Inertia/Vue and I am using Tailwind CSS.
I want to have separate admin.css and client.css files using tailwindcss 3.2 ability to have multiple config files:
./styles/admin.css
#config "./tailwind.admin.config.js"
#tailwind base;
#tailwind components;
#tailwind utilities;
but the problem is that Vite will build just app.css for me not the admin one
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/js/app.js',
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
ssr: {
noExternal: ['#inertiajs/server'],
},
server: {
host: "localhost",
},
});
app.css is imported in app.js
I can not figure it out
Could you please help me?
I want to have separate admin.css and client.css files per each tailwindcss config file.
You can pass an array of input files to vite as follows:
input: ['resources/js/app.js','resources/css/admin.css','resources/css/client.css']
This should result in seperate output files in your build directory.
If you want to keep the css as javascript import you can create a second InertiaApp for the admin area:
Copy app.js and rename it like 'admin.js'
Change css import in admin.js to '/styles/admin.css'
Change your vite input to: input: ['resources/js/app.js','resources/js/admin.js']
Use a different blade layouts for the 'admin' area with reference to admin.js instead of app.js : #vite('resources/js/admin.js')
Thanks #dustin for your answer. Here are some more things:
I can split javascript application by defining multiple rootViews using inertia-laravel#0.3.2 in HandleInertiaRequests.php middleware:
public function rootView(Request $request)
{
if ($request->routeIs('admin.*')) {
return 'admin';
}
return 'app';
}
And have two different apps.
But do you think its a good approach to have two different apps?
I like the separation idea but is it the right way?
I Also have concerns about bundling and mixing in inertia and ssr, would it be a problem for that when you have two apps? I dont know anything about inertia's way of working
I was hoping there is some other method like creating a higher order component or something like that. I am very new to Vue world and I am still trying to learn.

Laravel Vite configuration for separating assets (CSS and images)

I have one application where I want to separate my asset folders in Vite configuration.
This is how my current vite.config.js look like. I want something like
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
build: {
assetsDir: './images'
},
plugins: [
laravel({
input: [
'resources/css/app.css,'
'resources/scss/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
],
});
I want to separate all images and CSS after the build. For instance
Build - Assets - images (all images will be going)
Build - Assets - Css (all CSS will be going)

Laravel mix won't make sourceMaps

I need to make sourceMaps for my mix.combine() assets but laravel mix only creates maps for default mix.js()
Code
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css').sourceMaps();
// admin
mix.styles([
'public/themes/admin/vendor/fontawesome-free/css/all.min.css',
'public/themes/admin/vendor/datatables/datatables.min.css',
'public/css/print.min.css',
'public/js/dist/summernote-bs4.css',
'public/themes/admin/css/admin.min.css'
], 'public/css/admin.css');
mix.combine([
'public/themes/admin/vendor/jquery/jquery.min.js',
'public/themes/admin/vendor/datatables/datatables.min.js',
'public/js/print.min.js',
'public/themes/admin/vendor/bootstrap/js/bootstrap.bundle.min.js',
'public/themes/admin/vendor/jquery-easing/jquery.easing.min.js',
'public/themes/admin/js/demo/datatables-demo.js',
'public/themes/admin/js/admin.min.js'
], 'public/js/admin.js').sourceMaps();
// front
mix.styles([
'public/themes/front/css/bootstrap.min.css',
'public/themes/front/css/mega-menu/mega_menu.css',
'public/themes/admin/vendor/fontawesome-free/css/all.min.css',
'public/themes/front/css/themify-icons.css',
'public/themes/front/css/magnific-popup/magnific-popup.css',
'public/themes/front/css/owl-carousel/owl.carousel.css',
'public/themes/front/revolution/css/settings.css',
'public/themes/front/css/slick/slick.css',
'public/themes/front/css/slick/slick-theme.css',
'public/themes/front/css/style.css',
'public/themes/front/css/responsive.css',
], 'public/css/front.css');
mix.combine([
'public/themes/front/js/jquery.min.js',
'public/themes/front/js/popper.min.js',
'public/themes/front/js/bootstrap.min.js',
'public/themes/front/js/mega-menu/mega_menu.js',
'public/themes/front/js/owl-carousel/owl.carousel.min.js',
'public/themes/front/js/slick/slick.min.js',
'public/themes/front/js/magnific-popup/jquery.magnific-popup.min.js',
'public/themes/front/js/isotope/isotope.pkgd.min.js',
'public/themes/front/js/jquery.appear.js',
'public/themes/front/js/counter/jquery.countTo.js',
'public/themes/front/revolution/js/jquery.themepunch.tools.min.js',
'public/themes/front/revolution/js/jquery.themepunch.revolution.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.actions.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.carousel.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.kenburn.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.layeranimation.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.migration.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.navigation.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.parallax.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.slideanims.min.js',
'public/themes/front/revolution/js/extensions/revolution.extension.video.min.js',
'public/themes/front/js/custom.js',
], 'public/js/front.js').sourceMaps();
result
/css/app.css
/js/app.js
/js/app.js.map <-- only app.js has map file
\css\admin.css
\css\front.css
\js\admin.js
\js\front.js <-- front.js didn't create map file
Any idea?

Configuring postcss-uncss for Laravel Mix

I am trying to remove unused css rules from one or more of my sass files.
Research led me to postcss-uncss as the best option for removing unused css if you do not use server-side rendering (see: https://www.purgecss.com/comparison)
https://github.com/uncss/postcss-uncss
Now, postcss-uncss is a wrapper for uncss: https://github.com/uncss/uncss
However, the uncss documentation is confusing to me, and the example configuration here is not useful: https://github.com/uncss/postcss-uncss#example-configuration
How does one configure postcss-uncss for Laravel Mix?
THis is what I have so far:
mix.js('resources/js/app.js', 'public/js')
.options({
processCssUrls: false,
postCss: [
require('postcss-uncss'),
tailwindcss('./tailwind.config.js')
],
})
I want to:
Tell it which laravel routes to use (or 'all' should also be fine)
Where my sass / scss files are located: /resources/sass/* (example files: /resources/sass/app.scss, /resources/sass/admin/admin.scss, etc)
Where to put the output ie the compiled (and cleaned up) css without the unused rules: /public/css/* (so as to preserve the same structure, for example: /public/app.css, /public/admin/admin.css, etc)
Thoughts would be greatly appreciated.
This is what I ended up doing (used purgecss, which turns out, is a better option than uncss, according to my conversation with Adam Wathan
let mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');
// Removes unused CSS
// According to Discord chat: Running Purge CSS as part of Post CSS is a ton faster than laravel-mix-purgecss
// But if that doesn't work use https://github.com/spatie/laravel-mix-purgecss
const purgecss = require('#fullhuman/postcss-purgecss')({
// Specify the paths to all of the template files in your project
content: [
'./resources/views/*.php',
'./resources/views/**/*.php',
'./resources/js/components/*.vue',
'./resources/js/components/**/*.vue',
],
// Include any special characters you're using in this regular expression
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
});
mix.options({
clearConsole: true, // in watch mode, clears console after every build
processCssUrls: false,
postCss: [
//require('tailwindcss'),
tailwindcss('./tailwind.config.js'),
// to enable purgecss on production only
...process.env.NODE_ENV === 'production' ? [purgecss] : []
// to enable on all environments, local and production
//purgecss
],
})
;
Perhaps you might try the Spatie package?
Let's install it.
npm i laravel-mix-purgecss
Call purgeCss() in your webpack.mix.js.
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.purgeCss({ enabled: true });

Bootstrap-Vue CSS compilation in Laravel Mix

I'm using Laravel 5.6, Laravel Mix 2.0, and Bootstrap-Vue 2.0.0-rc.1.
Trying to find a way to configure Laravel Mix to include Bootstrap-Vue's CSS into my app.css file and prevent Bootstrap-Vue from including <style> tags into the page <head>.
I saw this note in the package docs but still not sure how to use this properly:
Note: requires webpack configuration to load css files (official guide)
Finally, found a solution - ExtractTextPlugin.
let mix = require('laravel-mix');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
mix.webpackConfig({
module: {
rules: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
}
});
Reference: https://github.com/JeffreyWay/laravel-mix/issues/1589
Install:
npm i bootstrap-vue
npm install --save-dev style-loader css-loader
Use:
edit resources/js/app.js to:
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)
edit resources/sass/app.scss to:
Import the styles:
import '~bootstrap/dist/css/bootstrap.css'
import '~bootstrap-vue/dist/bootstrap-vue.css'
Make sure the app.js and app.css are included in the blade(view) that is acting as the container for your vue.
See: https://bootstrap-vue.js.org/docs/

Resources