Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: postbuild patched file hash recalculation
Browse files Browse the repository at this point in the history
Vladislav Kharitonov committed Jan 26, 2024
1 parent 7432961 commit 3e115f1
Showing 3 changed files with 482 additions and 11 deletions.
431 changes: 421 additions & 10 deletions package-lock.json
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@
"dev": "npm run clean && next dev",
"build": "npm run clean && next build",
"dev:export": "EXPORT_MODE=true npm run dev",
"build:export": "EXPORT_MODE=true npm run build && EXPORT_MODE=true next export",
"build:export": "EXPORT_MODE=true npm run build && npm run export",
"preexport": "node scripts/preexport.js",
"export": "npm run preexport && EXPORT_MODE=true next export",
"start": "next start",
"start:dev": "NODE_ENV=development next start",
"start:export": "EXPORT_MODE=true next start",
@@ -65,6 +67,7 @@
"eslint": "^8.26.0",
"eslint-config-next": "12.0.10",
"express": "^4.17.3",
"glob": "^10.3.10",
"js-yaml": "^4.1.0",
"lint-staged": "^13.0.3",
"next-purgecss": "^4.0.0",
57 changes: 57 additions & 0 deletions scripts/preexport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const {join} = require('path');
const crypto = require('crypto');
const {globSync} = require('glob');
const {readFileSync, writeFileSync} = require('fs');

const BUILD_DIR = '.next';
const ASSETS_MANIFEST_PART = join(BUILD_DIR, 'assets-manifest.json');
const NEXT_OUT_DIR = '.next/server/pages';
const POSTBUILD_PATCHED_FILES = ['_ssgManifest.js'];
const SHA_FUNC = 'sha384';

const assetsManifest = JSON.parse(readFileSync(ASSETS_MANIFEST_PART).toString());

// Next.js patches some script files (like '_ssgManifest.js') after build, so need to run script like this to recalculate pathced file hashes and replace it in html files
function main() {
const replacementPairs = POSTBUILD_PATCHED_FILES.map(getReplacementPair).filter(Boolean);

replaceInPages(replacementPairs);
}

function getReplacementPair(fileName) {
const fileInfo = getFileInfo(fileName);

if (fileInfo) {
const {src, integrity} = fileInfo;
const content = readFileSync(join(BUILD_DIR, src)).toString();
const postBuildIntegrity = getIntegrity(content);

return [integrity, postBuildIntegrity];
}

return null;
}

function replaceInPages(replacementPairs) {
globSync(`${NEXT_OUT_DIR}/**/*.html`).forEach((pageFile) => {
const content = readFileSync(pageFile).toString();
const newContent = replacementPairs.reduce(
(result, [oldValue, newValue]) => result.replaceAll(oldValue, newValue),
content,
);

writeFileSync(pageFile, newContent);
});
}

function getFileInfo(fileName) {
return Object.entries(assetsManifest).find(([asset]) => asset.includes(fileName))?.[1];
}

function getIntegrity(content) {
const digest = crypto.createHash(SHA_FUNC).update(content, 'utf8').digest();

return `${SHA_FUNC}-${digest.toString('base64')}`;
}

main();

0 comments on commit 3e115f1

Please sign in to comment.