1

I have a project on Vite + Vue.js, and there are many large static reference files in public/data with .json extension. How can I minify them during build without turning them into javascript?

I tried to do it via esbuild:

esbuild public/data/*.json --outdir=/dist/public/data/ --allow-overwrite --minify

but it makes .js output files with module export [...] I don't need that, since I get them at runtime via fetch as needed, not via import.

I whant only minify pretty-print spaces, tabs and new lines inside json.

6
  • 1
    I suppose this involves custom vite plugin, I'm unaware of an existing one. And for such basic minification you could need JSON.parse/stringify transform without the need for 3rd-party minification tools. I'm not up to give a ready to use answer, but consider asking gpt if you're out of options, it's not bad for this kind of routine tasks Commented Nov 4 at 20:28
  • Doesn't vite-plugin-compress do what you want? Seems it by default supports compressing .json files.
    – Davi
    Commented Nov 5 at 0:38
  • For large public files, you may want to host them statically using an external system such as AWS S3. During development, you'll have the files locally and everything will work. At build time, disable the public directory using Vite's publicDir configuration and/or use rsync to exclude specific public directories. See this solution for more: github.com/vitejs/vite/discussions/…
    – TestWell
    Commented Nov 5 at 4:00
  • @EstusFlask yes I asked GPT and it helps with some correction, see my answer
    – Talleyran
    Commented Nov 5 at 10:27
  • @Davi this is compress to gz, this is not that i want.. And for newest versions of vite has vite-plugin-compression2
    – Talleyran
    Commented Nov 5 at 10:30

1 Answer 1

0

Here is the solution to my problem:

yarn add jsonminify -D

Then I created a /minify-data.js:

import fs from 'fs'
import path from 'path'
import jsonminify from 'jsonminify'
import { fileURLToPath } from 'url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

//this is the target path of my json files, copyed from `./public/data` by Vite
const publicDir = path.resolve(__dirname, './dist/data')

//recursively call jsonminify to json files in directory
const minifyJsonFiles = dir => {
    fs.readdirSync(dir).forEach(file => {
        const filePath = path.join(dir, file)
        const stat = fs.statSync(filePath)

        if (stat.isDirectory()) {
            minifyJsonFiles(filePath)
        } else if (path.extname(file) === '.json') {
            const content = fs.readFileSync(filePath, 'utf8')
            const minifiedContent = jsonminify(content)
            fs.writeFileSync(filePath, minifiedContent)
            console.log(`Minified: ${filePath}`)
        }
    })
}

minifyJsonFiles(publicDir)

And finaly I appended build command in package.json:

"scripts": {
   "dev": "vite",
   "build": "vite build && node minify-data.js",
   ...
},

It works slowly but it does what I need it to.

2
  • 1
    You don't need an external lib for that. JSON.stringify(JSON.parse(fs.readFileSync(filePath, 'utf8'))) does the same. If this works "slowly" and your json files are not frequently changing, I'd suggest to either create a separate script, which does minifying upon request and keeps the minified files in a temp directory and during build just copy those tempfile instead of always minifying. Or keep some timestamp of your last minification and just minify files that have been changed after that timestamp. Commented Nov 5 at 10:35
  • @derpirscher thank you! The native method is really much faster, given that my json files don't have comments that a third-party library removes, this suits me
    – Talleyran
    Commented Nov 5 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.