build: make running of npm ci in build scripts configurable

* moved the running of npm ci from copy-dist to cleanupNodeModules
* added flag to disable it (necessary for electron-forge)
This commit is contained in:
Panagiotis Papadopoulos 2025-03-27 00:00:41 +01:00
parent 0b428035ae
commit 75431ca634
6 changed files with 30 additions and 18 deletions

View File

@ -40,6 +40,7 @@ COPY --from=builder /usr/src/app ./
RUN sed -i "/electron/d" package.json && \
npm ci --omit=dev && \
node --experimental-strip-types ./bin/cleanupNodeModules.ts . --skip-prune-dev-deps && \
npm cache clean --force && \
rm -rf /tmp/node-compile-cache

View File

@ -35,8 +35,11 @@ COPY --from=builder /usr/src/app ./
RUN sed -i "/electron/d" package.json && \
npm ci --omit=dev && \
node --experimental-strip-types ./bin/cleanupNodeModules.ts . --skip-prune-dev-deps && \
npm cache clean --force && \
rm -rf /tmp/node-compile-cache
rm -rf \
/tmp/node-compile-cache \
./bin/cleanupNodeModules.ts
# Add application user
RUN adduser -s /bin/false node; exit 0

View File

@ -33,6 +33,7 @@ echo "Build start"
npm run build:prepare-dist
echo "Build finished"
# pruning of unnecessary files and devDeps in node_modules
node --experimental-strip-types $CLEANUP_SCRIPT $BUILD_DIR
NODE_FILENAME=node-v${NODE_VERSION}-linux-${ARCH}

View File

@ -1,30 +1,43 @@
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
* 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
* tsx bin/cleanupNodeModules.ts /path/to/build/folder [--skip-prune-dev-deps]
*/
function main() {
if (process.argv.length !== 3) {
console.error("More than one path was supplied as argument. Aborting.");
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.`)
console.error(`Supplied path '${basePath}' does not exist. Aborting.`);
process.exit(1);
}
console.log(`Starting node_modules pruning in '${basePath}'...`)
cleanupNodeModules(basePath);
console.log("Successfully pruned node_modules.")
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}`);
}
function cleanupNodeModules(basePath: string) {
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 });
@ -82,6 +95,7 @@ function cleanupNodeModules(basePath: string) {
.forEach(dir => removeDirent(dir))
}
function removeDirent(el: Dirent) {
const elementToDelete = path.join(el.parentPath, el.name);
fs.removeSync(elementToDelete);
@ -90,7 +104,6 @@ function removeDirent(el: Dirent) {
console.log(`Deleted ${elementToDelete}`);
}
}
main()

View File

@ -1,6 +1,5 @@
import fs from "fs-extra";
import path from "path";
import { execSync } from "node:child_process";
const DEST_DIR = "./build";
@ -59,11 +58,6 @@ try {
console.log("Copying complete!")
// TriliumNextTODO: for Docker this needs to run separately *after* build-stage
// Disable for now, because this messes with electron-forge as well
//console.log("Pruning npm packages...")
//execSync(`npm ci --omit=dev --prefix ${DEST_DIR}`);
} catch(err) {
console.error("Error during copy:", err)
process.exit(1)

View File

@ -47,7 +47,7 @@ module.exports = {
try {
const cleanupNodeModulesScript = path.join(buildPath, "bin", "cleanupNodeModules.ts");
// we don't have access to any devDeps like 'tsx' here, so use the built-in '--experimental-strip-types' flag instead
const command = `node --experimental-strip-types ${cleanupNodeModulesScript} '${buildPath}'`;
const command = `node --experimental-strip-types ${cleanupNodeModulesScript} '${buildPath}' --skip-prune-dev-deps`;
// execSync throws, if above returns any non-zero exit code
execSync(command);
callback()