A better build

This commit is contained in:
2026-02-13 15:17:59 -03:00
parent bbf61cd6d5
commit 26c31fded6
5 changed files with 76 additions and 2 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ node_modules
pnpm-lock.yaml
.eslintcache
.stylelintcache
dist

View File

@@ -1,4 +1,4 @@
FROM nginx:alpine
COPY nginx/conf.d/ /etc/nginx/conf.d/
COPY src/ /usr/share/nginx/html/
COPY dist/ /usr/share/nginx/html/

View File

@@ -4,6 +4,7 @@
"version": "1.0.0",
"packageManager": "pnpm@10.29.3",
"scripts": {
"build": "node scripts/build.js",
"docker:build": "docker build --platform linux/amd64 -t git.mifi.dev/mifi-holdings/landing:latest .",
"docker:push": "docker push git.mifi.dev/mifi-holdings/landing:latest",
"format": "prettier --write .",
@@ -18,11 +19,14 @@
"lint:fix:yaml": "yamllint .woodpecker/ci.yml .woodpecker/build.yml .woodpecker/deploy.yml docker-compose.yml --fix"
},
"devDependencies": {
"clean-css": "^5.3.3",
"critters": "^0.0.25",
"eslint": "^10.0.0",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.4.2",
"stylelint": "^17.3.0",
"stylelint-config-standard": "^40.0.0",
"terser": "^5.46.0",
"yaml-lint": "^1.7.0"
},
"repository": {

69
scripts/build.js Normal file
View File

@@ -0,0 +1,69 @@
/**
* Build script: copy src → dist, minify JS/CSS, inline critical CSS (Critters).
* Run with: pnpm build
*/
import { rmSync, mkdirSync, readFileSync, writeFileSync, cpSync, readdirSync } from 'fs'
import { join, dirname, extname } from 'path'
import { fileURLToPath } from 'url'
import Critters from 'critters'
import { minify as minifyJs } from 'terser'
import CleanCSS from 'clean-css'
const __dirname = dirname(fileURLToPath(import.meta.url))
const root = join(__dirname, '..')
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
}
async function main() {
// 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)
// 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)
}
// 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)
console.log('Build complete: dist/')
}
main().catch((err) => {
console.error(err)
process.exit(1)
})

View File

@@ -14,7 +14,7 @@
<meta name="robots" content="index, follow" />
<meta name="author" content="mifi" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="stylesheet" href="assets/css/style.css" />
<link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg" />
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico" />