Skip to content

Commit

Permalink
build: Updating source maps when moving them
Browse files Browse the repository at this point in the history
  • Loading branch information
steilerDev committed Sep 25, 2023
1 parent bff641e commit 714c868
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
104 changes: 104 additions & 0 deletions app/build/package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env ts-node
import fs from 'fs/promises';
import path from 'path';

// This script copies the build app from srcPath to targetPath, while updating all '*.js.map' references to the original TS source file
const srcPath = `build/out/src`;
const targetPath = `bin/`;

// Moves a src directory to a target directory
/**
* Recursively copies a directory (and its content) from dirSrc to dirTarget. 'js.map' file references will be updated
* @param dirSrc - Source directory
* @param dirTarget - Target directory
*/
async function copyDir(dirSrc: string, dirTarget: string) {
console.log(`Moving ${dirSrc} to ${dirTarget}`);
const srcStat = await fs.readdir(dirSrc, {withFileTypes: true});
for (const entry of srcStat) {
if (entry.isDirectory()) {
copyDir(path.join(entry.path, entry.name), path.join(dirTarget, entry.name));
continue;
}

if (entry.isFile()) {
await copyFile(path.join(entry.path, entry.name), path.join(dirTarget, entry.name));
}
}
}

/**
* Copies a file from fileSrc to fileTarget - src is validated to be a file and not a directory. Will maintain 'js.map' references to the original TS source file
* @param fileSrc - Src file
* @param fileTarget - Target file
*/
async function copyFile(fileSrc: string, fileTarget: string) {
// Making sure src file exists (we need the dirent anyway)
const srcFile = await (fs.stat(fileSrc)
.catch(() => undefined));
if (!srcFile) {
console.log(`Not moving file ${fileSrc}, because it does not exist`);
return;
}

// Making sure target dir exists, creating it otherwise
const fileTargetDir = path.dirname(fileTarget);
const targetDir = await (fs.stat(fileTargetDir)
.catch(() => undefined));
if (!targetDir) {
console.log(`Creating directory ${fileTargetDir}`);
await fs.mkdir(fileTargetDir, {recursive: true});
}

// Checking if target file exists and is newer than src file
const targetFile = await (fs.stat(fileTarget)
.catch(() => undefined));
if (targetFile && srcFile.mtimeMs < targetFile.mtimeMs) {
console.log(`Skipping ${fileSrc} as it is older than ${fileTarget}`);
return;
}

// Special treatment of 'js.map' files
if (fileSrc.endsWith(`js.map`)) {
await moveSrcMap(fileSrc, fileTarget);
return;
}

console.log(`Copying regular file ${fileSrc} to ${fileTarget}`);
await fs.copyFile(fileSrc, fileTarget);
}

/**
* Moves a source map file, while updating the source map's source reference to the original TS file
* @param fileSrc - Source map file
* @param fileTarget - Target file
*/
async function moveSrcMap(fileSrc: string, fileTarget: string) {
const fileSrcDirectory = path.dirname(fileSrc);
const fileTargetDirectory = path.dirname(fileTarget);

// Getting content
const srcMapContent = JSON.parse(await fs.readFile(fileSrc, {encoding: `utf-8`}));
if (srcMapContent.sources.length !== 1) {
console.warn(`Unexpected number of sources in ${fileSrc}, skipping file`);
return;
}

// Resolves the TS source file path based on the src map's 'sources' entry
const tsFileLocation = path.resolve(fileSrcDirectory, srcMapContent.sources[0]);

// Creates the relative path from the target file to the TS source file
const newReference = path.relative(fileTargetDirectory, tsFileLocation);

console.log(`Moving src map file ${fileSrc} to ${fileTarget}, while still pointing to ${srcMapContent.sources[0]}, by updating it to ${newReference}`);

// Making sure new reference is valid
if (path.resolve(fileTargetDirectory, newReference) !== tsFileLocation) {
throw new Error(`Target mismatch for ${fileSrc} -> ${fileTarget} -> ${newReference} -> ${tsFileLocation}`);
}

srcMapContent.sources = [newReference];
await fs.writeFile(fileTarget, JSON.stringify(srcMapContent), {encoding: `utf-8`});
}

await copyDir(srcPath, targetPath);
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build:dev": "npm run build:schema && npm run build:typescript",
"build": "npm run build:dev",
"dist:clean": "rm -rf bin/ && mkdir -p bin/",
"dist:package": "cp -r ./build/out/src/* bin/ && cp ../README.md ../LICENSE .",
"dist:package": "npx ts-node-esm build/package.ts && cp ../README.md ../LICENSE .",
"dist:sourcemap": "npx backtrace-js process bin/",
"dist": "npm run dist:clean && npm run dist:package && npm run dist:sourcemap",
"test": "NODE_NO_WARNINGS=1 NODE_OPTIONS='--experimental-vm-modules' npx jest --config jest.config.json",
Expand Down

0 comments on commit 714c868

Please sign in to comment.