Tweaks, fixes, etc
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
/**
|
||||
* Build script: copy src → dist, minify JS/CSS, inline critical CSS (Critters).
|
||||
* Build script: copy src → dist, minify JS/CSS, inline critical CSS (Beasties).
|
||||
* Run with: pnpm build
|
||||
*/
|
||||
import {
|
||||
rmSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
cpSync,
|
||||
readdirSync
|
||||
rmSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
cpSync,
|
||||
readdirSync
|
||||
} from 'fs'
|
||||
import { join, dirname, extname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import Critters from 'critters'
|
||||
import Beasties from 'beasties'
|
||||
import { minify as minifyJs } from 'terser'
|
||||
import CleanCSS from 'clean-css'
|
||||
|
||||
@@ -22,55 +22,57 @@ const srcDir = join(root, 'src')
|
||||
const distDir = join(root, 'dist')
|
||||
|
||||
function getFiles(dir, files = []) {
|
||||
const entries = readdirSync(dir, { withFileTypes: true })
|
||||
for (const e of entries) {
|
||||
const full = join(dir, e.name)
|
||||
if (e.isDirectory()) getFiles(full, files)
|
||||
else files.push(full)
|
||||
}
|
||||
return files
|
||||
const entries = readdirSync(dir, { withFileTypes: true })
|
||||
for (const e of entries) {
|
||||
const full = join(dir, e.name)
|
||||
if (e.isDirectory()) getFiles(full, files)
|
||||
else files.push(full)
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// 1. Clean and copy src → dist
|
||||
rmSync(distDir, { recursive: true, force: true })
|
||||
mkdirSync(distDir, { recursive: true })
|
||||
cpSync(srcDir, distDir, { recursive: true })
|
||||
// 1. Clean and copy src → dist
|
||||
rmSync(distDir, { recursive: true, force: true })
|
||||
mkdirSync(distDir, { recursive: true })
|
||||
cpSync(srcDir, distDir, { recursive: true })
|
||||
|
||||
const distFiles = getFiles(distDir)
|
||||
const distFiles = getFiles(distDir)
|
||||
|
||||
// 2. Minify JS
|
||||
const jsFiles = distFiles.filter((f) => extname(f) === '.js')
|
||||
for (const f of jsFiles) {
|
||||
const code = readFileSync(f, 'utf8')
|
||||
const result = await minifyJs(code, { format: { comments: false } })
|
||||
if (result.code) writeFileSync(f, result.code)
|
||||
}
|
||||
// 2. Minify JS
|
||||
const jsFiles = distFiles.filter((f) => extname(f) === '.js')
|
||||
for (const f of jsFiles) {
|
||||
const code = readFileSync(f, 'utf8')
|
||||
const result = await minifyJs(code, { format: { comments: false } })
|
||||
if (result.code) writeFileSync(f, result.code)
|
||||
}
|
||||
|
||||
// 3. Minify CSS
|
||||
const cleanCss = new CleanCSS({ level: 2 })
|
||||
const cssFiles = distFiles.filter((f) => extname(f) === '.css')
|
||||
for (const f of cssFiles) {
|
||||
const code = readFileSync(f, 'utf8')
|
||||
const result = cleanCss.minify(code)
|
||||
if (!result.errors.length) writeFileSync(f, result.styles)
|
||||
}
|
||||
// 3. Minify CSS
|
||||
const cleanCss = new CleanCSS({ level: 2 })
|
||||
const cssFiles = distFiles.filter((f) => extname(f) === '.css')
|
||||
for (const f of cssFiles) {
|
||||
const code = readFileSync(f, 'utf8')
|
||||
const result = cleanCss.minify(code)
|
||||
if (!result.errors.length) writeFileSync(f, result.styles)
|
||||
}
|
||||
|
||||
// 4. Inline critical CSS with Critters (no browser; works in CI)
|
||||
const critters = new Critters({
|
||||
path: distDir,
|
||||
preload: 'default',
|
||||
logLevel: 'warn'
|
||||
})
|
||||
const indexPath = join(distDir, 'index.html')
|
||||
const html = readFileSync(indexPath, 'utf8')
|
||||
const inlined = await critters.process(html)
|
||||
writeFileSync(indexPath, inlined)
|
||||
// 4. Inline critical CSS with Beasties for all HTML files (no browser; works in CI)
|
||||
const htmlFiles = distFiles.filter((f) => extname(f) === '.html')
|
||||
const beasties = new Beasties({
|
||||
path: distDir,
|
||||
preload: 'default',
|
||||
logLevel: 'warn'
|
||||
})
|
||||
for (const htmlFile of htmlFiles) {
|
||||
const html = readFileSync(htmlFile, 'utf8')
|
||||
const inlined = await beasties.process(html)
|
||||
writeFileSync(htmlFile, inlined)
|
||||
}
|
||||
|
||||
console.log('Build complete: dist/')
|
||||
console.log('Build complete: dist/')
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user