mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 11:56:01 +01:00 
			
		
		
		
	* moved the running of npm ci from copy-dist to cleanupNodeModules * added flag to disable it (necessary for electron-forge)
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import fs from "fs-extra";
 | 
						|
import path from "path";
 | 
						|
import type { Dirent } from "fs-extra";
 | 
						|
import { execSync } from "node:child_process";
 | 
						|
 | 
						|
/**
 | 
						|
 * Example usage with node >= v22:
 | 
						|
 *    node --experimental-strip-types bin/cleanupNodeModules.ts /path/to/build/folder [--skip-prune-dev-deps]
 | 
						|
 * Example usage with tsx:
 | 
						|
 *    tsx bin/cleanupNodeModules.ts /path/to/build/folder [--skip-prune-dev-deps]
 | 
						|
 */
 | 
						|
function main() {
 | 
						|
 | 
						|
    if (process.argv.length > 4 || process.argv.length < 3) {
 | 
						|
        console.error("Usage: cleanupNodeModules.ts [path-to-build-folder] [--skip-prune-dev-deps]");
 | 
						|
        process.exit(1);
 | 
						|
    }
 | 
						|
 | 
						|
    const basePath = process.argv[2];
 | 
						|
    const pruneDevDeps = process.argv[3] !== "--skip-prune-dev-deps";
 | 
						|
 | 
						|
    if (!fs.existsSync(basePath)) {
 | 
						|
        console.error(`Supplied path '${basePath}' does not exist. Aborting.`);
 | 
						|
        process.exit(1);
 | 
						|
    }
 | 
						|
 | 
						|
    console.log(`Starting pruning of node_modules ${!pruneDevDeps ? '(skipping npm pruning)' : ''} in '${basePath}'...`);
 | 
						|
    cleanupNodeModules(basePath, pruneDevDeps);
 | 
						|
    console.log("Successfully pruned node_modules.");
 | 
						|
}
 | 
						|
 | 
						|
function cleanupNodeModules(basePath: string, pruneDevDeps: boolean = true) {
 | 
						|
 | 
						|
    // This needs to run for the server and Docker build,
 | 
						|
    // but needs to be skipped for electron-forge: its
 | 
						|
    // built-in pruning takes care of it already
 | 
						|
    if (pruneDevDeps) {
 | 
						|
        execSync(`npm ci --omit=dev --prefix ${basePath}`);
 | 
						|
    }
 | 
						|
 | 
						|
    const nodeModulesDirPath = path.join(basePath, "node_modules");
 | 
						|
    const nodeModulesContent = fs.readdirSync(nodeModulesDirPath, { recursive: true, withFileTypes: true });
 | 
						|
    //const libDir = fs.readdirSync(path.join(basePath, "./libraries"), { recursive: true, withFileTypes: true });
 | 
						|
 | 
						|
    /**
 | 
						|
     * Delete unnecessary folders
 | 
						|
     */
 | 
						|
    const filterableDirs = new Set([
 | 
						|
        "demo",
 | 
						|
        "demos",
 | 
						|
        "doc",
 | 
						|
        "docs",
 | 
						|
        "example",
 | 
						|
        "examples",
 | 
						|
        "test",
 | 
						|
        "tests"
 | 
						|
    ]);
 | 
						|
 | 
						|
    nodeModulesContent
 | 
						|
        .filter(el => el.isDirectory() && filterableDirs.has(el.name))
 | 
						|
        .forEach(dir => removeDirent(dir));
 | 
						|
 | 
						|
    /**
 | 
						|
     * Delete unnecessary files based on file extension
 | 
						|
     * TODO filter out useless (README).md files
 | 
						|
     */
 | 
						|
    const filterableFileExt = new Set([
 | 
						|
        "ts",
 | 
						|
        "map"
 | 
						|
    ]);
 | 
						|
 | 
						|
    nodeModulesContent
 | 
						|
        // TriliumNextTODO: check if we can improve this naive file ext matching, without introducing any additional dependency
 | 
						|
        .filter(el => el.isFile() && filterableFileExt.has(el.name.split(".").at(-1) || ""))
 | 
						|
        .forEach(dir => removeDirent(dir));
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Delete specific unnecessary folders
 | 
						|
     * TODO: check if we want removeSync to throw an error, if path does not exist anymore -> currently it will silently fail
 | 
						|
     */
 | 
						|
    const extraFoldersDelete = new Set([
 | 
						|
        path.join(nodeModulesDirPath, ".bin"),
 | 
						|
        path.join(nodeModulesDirPath, "@excalidraw", "excalidraw", "dist", "dev"),
 | 
						|
        path.join(nodeModulesDirPath, "boxicons", "svg"),
 | 
						|
        path.join(nodeModulesDirPath, "boxicons", "node_modules"),
 | 
						|
        path.join(nodeModulesDirPath, "boxicons", "src"),
 | 
						|
        path.join(nodeModulesDirPath, "boxicons", "iconjar"),
 | 
						|
        path.join(nodeModulesDirPath, "@jimp", "plugin-print", "fonts"),
 | 
						|
        path.join(nodeModulesDirPath, "jimp", "dist", "browser") // missing "@" in front of jimp is not a typo here
 | 
						|
    ]);
 | 
						|
 | 
						|
    nodeModulesContent
 | 
						|
        .filter(el => el.isDirectory() && extraFoldersDelete.has(path.join(el.parentPath, el.name)))
 | 
						|
        .forEach(dir => removeDirent(dir))
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function removeDirent(el: Dirent) {
 | 
						|
    const elementToDelete = path.join(el.parentPath, el.name);
 | 
						|
    fs.removeSync(elementToDelete);
 | 
						|
 | 
						|
    if (process.env.VERBOSE) {
 | 
						|
        console.log(`Deleted ${elementToDelete}`);
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
main() |