58 lines
1.9 KiB
JavaScript
58 lines
1.9 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
const repoRoot = process.cwd();
|
||
|
|
const pkgPath = path.join(repoRoot, 'package.json');
|
||
|
|
const publicDir = path.join(repoRoot, 'public');
|
||
|
|
if (!fs.existsSync(pkgPath) || !fs.existsSync(publicDir)) process.exit(0);
|
||
|
|
|
||
|
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
||
|
|
const version = pkg.version;
|
||
|
|
if (!version) {
|
||
|
|
console.error('package.json version missing');
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
function walkHtmlFiles(dir) {
|
||
|
|
const out = [];
|
||
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||
|
|
const full = path.join(dir, entry.name);
|
||
|
|
if (entry.isDirectory()) out.push(...walkHtmlFiles(full));
|
||
|
|
else if (entry.isFile() && entry.name.endsWith('.html')) out.push(full);
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
function isLocalAsset(rawUrl) {
|
||
|
|
return !/^(?:[a-z]+:|\/\/|#)/i.test(rawUrl);
|
||
|
|
}
|
||
|
|
|
||
|
|
function withVersion(rawUrl) {
|
||
|
|
const [baseWithQuery, hash = ''] = rawUrl.split('#');
|
||
|
|
const [pathname, query = ''] = baseWithQuery.split('?');
|
||
|
|
const params = new URLSearchParams(query);
|
||
|
|
params.set('v', version);
|
||
|
|
const qs = params.toString();
|
||
|
|
return pathname + (qs ? '?' + qs : '') + (hash ? '#' + hash : '');
|
||
|
|
}
|
||
|
|
|
||
|
|
const htmlFiles = walkHtmlFiles(publicDir);
|
||
|
|
let changed = 0;
|
||
|
|
for (const file of htmlFiles) {
|
||
|
|
let content = fs.readFileSync(file, 'utf8');
|
||
|
|
const next = content
|
||
|
|
.replace(/(<link\b[^>]*href=["'])([^"']+\.css(?:\?[^"']*)?)(["'][^>]*>)/gi, (m, p1, url, p3) => {
|
||
|
|
return isLocalAsset(url) ? p1 + withVersion(url) + p3 : m;
|
||
|
|
})
|
||
|
|
.replace(/(<script\b(?![^>]*type=["']application\/json["'])[^>]*\bsrc=["'])([^"']+\.js(?:\?[^"']*)?)(["'][^>]*>\s*<\/script>)/gi, (m, p1, url, p3) => {
|
||
|
|
return isLocalAsset(url) ? p1 + withVersion(url) + p3 : m;
|
||
|
|
});
|
||
|
|
if (next !== content) {
|
||
|
|
fs.writeFileSync(file, next);
|
||
|
|
changed += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (changed > 0) console.log('Synced versioned assets in ' + changed + ' HTML file(s).');
|