Vite appending assets path to image URLs - tailwind-css

Using Vite/React/Tailwind, I am trying to set dev/prod workflow so that images stored in 'public' directory has the correct path when deployed to gh-pages. Below is my Tailwind config starting point where 'backgroundImages' property is referencing an image file stored in 'public'.
module.exports = {
mode:'jit',
content: ["./src/**/*.{html,jsx}"],
theme: {
screens: {
sm: '480px',
md: '768px',
lg: '976px',
xl: '1440px',
},
colors: {
'splash-hex': '#6BD1D2',
'splash-rgba': 'rgba(107, 209, 210,1.0)',
'splash-hsla': 'hsla(181, 53%, 62%, 1.0)',
},
fontFamily: {
sans: ['Graphik', 'sans-serif'],
serif: ['Merriweather', 'serif'],
},
backgroundImages:{
'default':'url("./10475996-3x2-940x627.jpeg")'
},
extend: {
spacing: {
'128': '32rem',
'144': '36rem',
},
borderRadius: {
'4xl': '2rem',
}
}
},
prefix: 'tw-',
plugins: [],
}
In dev this works fine.
http://localhost:3000/10475996-3x2-940x627.jpeg
In 'dist' folder, it looks correct as well when 'build' is run.
When deployed to gh-pages, the path changes to /assets/ and the image is no longer served from root as I expected according to Vite.
https://unevenartwork.com/assets/10475996-3x2-940x627.jpeg
Is there a configuration that would suppress the /assets/ on deploy or another solution?

The solution to this issue has two parts.
First, as shown in this answer, on build or deploy command, Rollup will create the output directories when set in the config. Just place the image assets in src/img folder as a target for Rollup to output to dist folder.
Then, in Tailwind config, be sure to make a reference to the parent directory in the asset path - ../img/10475996-3x2-940x627.jpeg instead of ./img/10475996-3x2-940x627.jpeg. This helps Vite make the correct path association to the parent directory.
It appears this is effective for properties defined in Tailwind theme extensions. No issues experienced with img src attribute values.

Related

How to develop/debug two apps with shared components using vue3 and vite?

I'm building a couple of apps with vue3 and vite, using some shared components. The production build process works OK but I'm having a problem with dev/debug. The Vite docs (for multi-page apps) says
"During dev, simply navigate or link to /nested/ - it works as
expected, just like for a normal static file server."
but I don't know what this means - how do I link to a sub folder? I have added /src/app1 to url in launch.json, but it has no effect. I have also tried using cd src\app1 in the terminal before running npm run dev
"version": "0.2.0",
"configurations": [
{
"type": "firefox",
"request": "launch",
"name": "vuejs: firefox -width 300 -height 600 -P default",
"url": "http://localhost:5173/src/app1",
"webRoot": "${workspaceFolder}",
"pathMappings": [
{
"url": "file:///C:",
"path": "c:"
}
]
}
]
(This launch.json works well with a simple single-page app).
What happens with trying to debug one of the apps is that the project launches but with an empty index.html (i.e. a blank screen with no errors). I'm pretty sure the basic project structure is OK because (as I said) the build process works; I get two separate outputs of html+css+js both of which work as expected, with the correct shared components.
Also, if I tell the Vite server to automatically open the page (as I have done in my vite.config.js below) the page opens correctly - although without a debugger attached of course. So I guess that the settings in launch.json are incorrect.
The project structure is:
-src
-app1
-app.vue
-index.html
-main.js
-app2
-app.vue
-index.html
-main.js
-assets
...
-shared
-components
-shared.vue
If I have just one index.html, moved up a level, I can debug each app but only by editing it every time to point to a different main.js and to change the title, which seems a laborious way of approaching the task.
Below is my vite config. The extra lines in alias were added as an attempt to solve the problem but they are probably incorrect (or unneccesary)
import { fileURLToPath, URL } from 'node:url'
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
server: {
base: '/src/app1',
open: '/src/app1/index.html',
},
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
'#': fileURLToPath(new URL('./src', import.meta.url)),
app1: fileURLToPath(new URL('./src/app1', import.meta.url)),
app2: fileURLToPath(new URL('./src/app2', import.meta.url)),
// shared: fileURLToPath(new URL('./src/shared/components', import.meta.url)),
}
},
build: {
rollupOptions: {
input: {
app1: resolve(__dirname, './src/app1/index.html'),
app2: resolve(__dirname, './src/app2/index.html'),
},
},
},
})
I've made things more complex than neccesary because I missed the important setting. In vite.config.js, it's important to define root to point to where each index.html is found. So for my structure above, the config file looks like
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig({
plugins: [vue() ],
root: "src\app1",
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
}
}
})
In the process I've also swapped from Firefox to Chrome for debug (I was getting a lot of irrelevant error messages from Firefox), and my launch.json is now simply
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}",
}
]
}
It doesn't really matter what the file structure looks like, as long as within each file its dependencies are correctly addressed. The only important bit is the root. Simply by changing that from 'app1' to 'app2' will switch both the debug and the build to the correct folders, with the release (built) files being stored in subfolders of 'app1' and 'app2' independently.
It would be easy to extend this to have more than 2 apps each sharing the same common components.

TailwindCSS doesn't purge plugin classes

I was trying to reduce the size of my CSS file using Tailwind's in-house compiler. This is my config file:
module.exports = {
content: ["./pages/*.html", "./components/**/*", "./src/*"],
mode: "jit",
plugins: [
require("tailwindcss"),
require("tw-elements/dist/plugin"),
require('tailwind-scrollbar')({ nocompatible: true }),
function ({ addVariant }) {
addVariant("child", "& > *");
addVariant("child-hover", "& > *:hover");
},
],
},
};
I have checked that the directories specified in content don't contain any hidden classes, however, it seems that Tailwind includes every class from the package tw-elements and doesn't purge them.
Is there any way how I can get a clean CSS file?
Many thanks for your help!
It is possible to reduce the size of your CSS file using Tailwind's in-house compiler. You can add the purge option to your Tailwind configuration file. Additionally, you can use the whitelist option to specify a list of classes that should not be purged. For example:
module.exports = {
content: ["./pages/*.html", "./components/**/*", "./src/*"],
mode: "jit",
purge: {
content: ['./pages/*.html', './components/**/*', './src/*'],
whitelist: ['tw-elements']
}
....
}

Tailwindcss margin not working inside docker but works perfectly outside container [duplicate]

This question already has an answer here:
Why is the custom color in tailwind not defined in NextJS production stage
(1 answer)
Closed 1 year ago.
Sample: https://play.tailwindcss.com/Xialm0nYXU (this works as expected in tailwind playground & when app is run directly on laptop but not within my containerized app. The margins mx are not working only inside containers.)
I have a HTML code that is similar to the above (but within a larger application). The margins between the <p> elements work fine while testing locally. But once I containerize my application it stops working. Oddly margin works at mx-2 but nothing else work, padding is not working either. Margins for other elements work fine (even inside container), so it should be something about this shared snippet that stops working inside a container. I could not share the whole application code, so I understand you might not have full context to understand what else could be happening. But want to check if anyone knows what could possibly cause issue only when run inside container. I suspect something gets messed up in the containerization process. Appreciate any pointers here.
My Dockerfile:
FROM node:14
# Create app directory
RUN mkdir -p /usr/src/app/
WORKDIR /usr/src/app/
COPY package*.json .
RUN npm install
# Bundle app source
COPY . .
EXPOSE 3000
ENV NODE_ENV production
CMD ["npm", "start" ]
tailwind.config.json:
const colors = require('tailwindcss/colors')
module.exports = {
purge: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}'
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
colors: {
blueGray: colors.blueGray,
emerald: colors.emerald,
lime: colors.lime,
trueGray: colors.trueGray,
teal: colors.teal,
cyan: colors.cyan,
sky: colors.sky,
warmGray: colors.warmGray,
green: {
25: '#f5fff8'
}
},
fontSize: {
'xxs': '.70rem'
},
overflow: ['hover', 'focus'],
textOverflow: ['hover', 'focus']
},
},
variants: {
extend: {
display: ['hover', 'focus', 'group-hover'],
opacity: ['disabled'],
backgroundColor: ['active'],
whitespace: ['hover', 'focus'],
width: ['hover', 'focus'],
},
},
plugins: [
require('#tailwindcss/forms'),
],
}
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Update: The problem turned out to be me dynamically generating tailwind class names through string concatenation. Exactly what the tailwind folks recommended not to do as PurgeCss cant recognize those classes at build time. Once i turned that into an annoyingly long conditional statement returning statically coded class names things started working fine. For information on this checkout tailwind doc - https://tailwindcss.com/docs/optimizing-for-production#writing-purgeable-html
The problem turned out to be me dynamically generating tailwind class names through string concatenation. Exactly what the tailwind folks recommended not to do as PurgeCss cant recognize those classes at build time. Once I turned that into an annoyingly long conditional statement returning statically coded class names things started working fine. For information on this checkout tailwind doc - https://tailwindcss.com/docs/optimizing-for-production#writing-purgeable-html

How does NuxtJS css extraction work for generated static websites?

I am trying to generate a static website out of my (minimal) code with Nuxt. In that code, I integrate in particular the tailwindcss toolkit as well as vue2-leaflet. Upon
nuxt generate
I get two css files, one for the tailwindcss css and the other for the leaflet css. While the former file is fine and contains everything I need, the latter is pretty sparse:
.leaflet-tile-pane{z-index:200}#-webkit-keyframes leaflet-gestures-fadein{to{opacity:1}}#keyframes leaflet-gestures-fadein{0%{opacity:0}to{opacity:1}}
Of course, that makes my map render in a pretty strange way, because most of the css is missing. Here's my current nuxt.config.js:
module.exports = {
mode: 'universal',
head: {
title: pkg.name,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
css: [
],
plugins: [
{ src: '~plugins/leaflet.js', mode: 'client' }
],
buildModules: [
'#nuxtjs/tailwindcss'
],
modules: ['#nuxtjs/apollo', 'nuxt-purgecss', ['nuxt-i18n', i18n]],
[...]
build: {
extractCSS: true,
}
}
Getting rid of the extractCSS ends up incorporating all the relevant css into the index.html. It works, but then I get the following error:
ERROR Webpack mode only works with build.extractCSS set to *true*. Either extract your CSS or use 'postcss' mode
I'm not sure I understand how that whole css extraction works. Could someone enlighten me? Why is it not working with extractCSS: true? How can I make it work? Why is it working in SPA mode but not in static mode?
You are using nuxt-purgecss which is using purgecss to strip unused CSS.
purgecss do scan HTML (or vue) files for CSS classes in use and then strip unused classes from final CSS bundle.
You can take a look at default purgecss configuration used by nuxt-purgecss here. The paths lists the paths purgecss will scan for CSS usage.
Because you are not using most of the leaflet css directly (in your components), its is necessary to configure purgecss to don't remove leaflet's css.
You can do that by whitelisting (btw not sure if "comment" method will work in Vue\Nuxt)
You can read more here and here
Not tested!!
// nuxt.config.js
{
purgeCSS: {
whitelistPatterns: [/leaflet/, /marker/]
}
}
Regarding the error message
Error message is from nuxt-purgecss module - it is clearly documented here
I don't have deep knowledge of Nuxt build process. So I just assume from the docs that extractCSS: true will use extract-css-chunks-webpack-plugin to extract all CSS to separate CSS file, while (default) extractCSS: false will use PostCSS to extract all CSS and put it directly into the <style> tag of rendered page.
All of that doesn't matter IMHO because the root problem is the use of purgecss and the solution is to configure it correctly to whitelist leaflet CSS classes....

React: background image not loading when deployed to server

I am using webpack to transpile my reactjs code. When I run it locally on webpack dev server, I can see my background image. However when I deploy it to the server the image doesn't show. I figure it must be some kind of path issue.
css
.centerbg {
background: url(/images/centerbg.jpg) no-repeat;
}
jsx
<div className="centerbg">
</div>
webpack loader
{
test: /\.(woff|ttf|eot|svg|png|jpg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader',
options: {
limit: 10000
}
}
File paths
build/main.js
images/centerbg.jpg
index.html
This is a bug usually dued to output.publicPath config not being explicitely declared.
Set it to the path where your assets will be served from. For basic scenarios this is enough:
output: {
publicPath: '/',
//...
},

Resources