Skip to content

Instantly share code, notes, and snippets.

@AdrianFahrbach
Created December 6, 2023 18:16
Show Gist options
  • Save AdrianFahrbach/c9099d8315085dd43cde6ad894d5aa5a to your computer and use it in GitHub Desktop.
Save AdrianFahrbach/c9099d8315085dd43cde6ad894d5aa5a to your computer and use it in GitHub Desktop.
Strapi patch admin script
// @ts-check
const fs = require('fs');
const path = require('path');
const { consola } = require('consola');
const patchFolderPathAbs = path.join(__dirname, '../src/admin/patch');
const distFolderPathAbs = path.join(__dirname, '../.strapi/dist/patches');
const chunkFolderPath = '../node_modules/@strapi/admin/dist/_chunks';
const chunkFolderPathAbs = path.join(__dirname, chunkFolderPath);
const filesToPatch = fs.readdirSync(patchFolderPathAbs).filter(fileName => fileName.endsWith('.js'));
const chunkFiles = fs
.readdirSync(chunkFolderPathAbs)
.filter(fileName => fileName.endsWith('.js') || fileName.endsWith('.mjs'));
let filesPatched = 0;
async function patchChunkFile(chunkFile) {
let chunkFileContents = fs.readFileSync(path.join(chunkFolderPathAbs, chunkFile)).toString();
const foundFilesToPatch = [];
// Find the variables that should be patched and imports that we have to fix in this chunk file
for (const fileToPatch of filesToPatch) {
const variableRegex = new RegExp(`^const ${fileToPatch.split('.')[0]} = [\\s\\S]+?^};$`, 'm');
// Check if this patch file is relevant for this chunk file
if (variableRegex.test(chunkFileContents)) {
const newFileName = `${fileToPatch.split('.')[0]}-${chunkFile}`;
let fileToPatchContent = fs.readFileSync(path.join(patchFolderPathAbs, fileToPatch)).toString();
foundFilesToPatch.push({ importName: fileToPatch.split('.')[0], importFileName: newFileName });
chunkFileContents = chunkFileContents.replace(variableRegex, '');
// Fix admin/chunk imports
const chunkImports =
new RegExp(/import { (.*) } from 'CHUNK_IMPORT';/).exec(fileToPatchContent)?.[1].split(', ') ?? [];
for (const chunkImport of chunkImports) {
const chunkImportRegex = new RegExp(
`import .*?(?<importName>(?:[^\\s,]+ as )?${chunkImport}).*from "(?<importFileName>[^\\s,]+)"`
);
const { groups } = chunkImportRegex.exec(chunkFileContents) ?? { groups: null };
const importName = groups?.importName ?? chunkImport;
const importFileName = groups?.importFileName;
if (!importName || !importFileName) {
// This file does not have the import we are looking for, so it is probably not relevant for us
return false;
}
fileToPatchContent =
`import { ${importName} } from "${path.join('../../', chunkFolderPath, importFileName)}";\n` +
fileToPatchContent;
}
fileToPatchContent = fileToPatchContent.replace(/import { (.*) } from 'CHUNK_IMPORT';/, '');
fs.writeFileSync(path.join(distFolderPathAbs, newFileName), fileToPatchContent);
filesPatched++;
}
}
if (foundFilesToPatch.length === 0) {
// No files to patch found
return false;
}
// Add import to new variables
const targetFilePath = path.join(chunkFolderPathAbs, chunkFile);
for (const foundFileToPatch of foundFilesToPatch) {
chunkFileContents =
`import ${foundFileToPatch.importName} from "../../../../../.strapi/dist/patches/${foundFileToPatch.importFileName}"\n` +
chunkFileContents;
}
fs.writeFileSync(targetFilePath, chunkFileContents);
consola.info('Patching file ' + targetFilePath);
}
async function patchAdmin() {
// Check if our dist directory exists
if (!fs.existsSync(distFolderPathAbs)) {
fs.mkdirSync(distFolderPathAbs, { recursive: true });
} else {
// Clean it up
fs.rmSync(distFolderPathAbs, { recursive: true, force: true });
fs.mkdirSync(distFolderPathAbs, { recursive: true });
}
// Go through all chunk files and replace the imports
await Promise.all(chunkFiles.map(async chunkFile => patchChunkFile(chunkFile)));
if (filesPatched === 0) {
consola.info('No files were patched.');
}
}
patchAdmin();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment