chore: fix lint warnings

Resolves the remaining eslint warnings across the codebase: dead
non-null assertions in compiler.ts (threaded the log step through as
a param instead of reading a nullable field), unused imports/vars,
empty-function/empty-block stubs, prefer-const violations, and a
definite-assignment issue in boot-nexe.ts's footer parsing.

Also includes incidental prettier reformatting from `eslint --fix`
across files whose logic didn't otherwise change.
This commit is contained in:
2026-07-26 00:04:00 -07:00
parent 7dbe7c4a2b
commit e2909539aa
17 changed files with 178 additions and 97 deletions
+27 -19
View File
@@ -11,7 +11,7 @@ import {
dequote,
isWindows,
bound,
semverGt
semverGt,
} from "./util";
import { NexeOptions, version } from "./options";
import { NexeTarget } from "./target";
@@ -46,7 +46,6 @@ export class NexeCompiler {
* Epoch of when compilation started
*/
private start = Date.now();
private compileStep: LogStep | undefined;
public log = new Logger(this.options.loglevel);
/**
* Copy of process.env
@@ -130,7 +129,7 @@ export class NexeCompiler {
this.env = { ...process.env };
this.env.PATH = python
? (this.env.PATH =
dequote(normalize(python)) + delimiter + originalPath)
dequote(normalize(python)) + delimiter + originalPath)
: originalPath;
process.env.PATH = originalPath;
} else {
@@ -209,9 +208,13 @@ export class NexeCompiler {
return this.nodeSrcBinPath;
}
private _runBuildCommandAsync(command: string, args: string[]) {
private _runBuildCommandAsync(
step: LogStep,
command: string,
args: string[]
) {
if (this.log.verbose) {
this.compileStep!.pause();
step.pause();
}
return new Promise<void>((resolve, reject) => {
spawn(command, args, {
@@ -222,13 +225,13 @@ export class NexeCompiler {
})
.once("error", (e: Error) => {
if (this.log.verbose) {
this.compileStep!.resume();
step.resume();
}
reject(e);
})
.once("close", (code: number) => {
if (this.log.verbose) {
this.compileStep!.resume();
step.resume();
}
if (code != 0) {
const error = `${command} ${args.join(
@@ -241,28 +244,30 @@ export class NexeCompiler {
});
}
private _configureAsync() {
private _configureAsync(step: LogStep) {
if (isWindows && semverGt(this.target.version, "10.15.99")) {
return Promise.resolve();
}
return this._runBuildCommandAsync(this.env.PYTHON || "python", [
return this._runBuildCommandAsync(step, this.env.PYTHON || "python", [
this.configureScript,
...this.options.configure,
]);
}
public async build(): Promise<ReadStream> {
this.compileStep!.log(
`Configuring node build${this.options.configure.length ? ": " + this.options.configure : "..."
public async build(step: LogStep): Promise<ReadStream> {
step.log(
`Configuring node build${
this.options.configure.length ? ": " + this.options.configure : "..."
}`
);
await this._configureAsync();
await this._configureAsync(step);
const buildOptions = this.options.make;
this.compileStep!.log(
`Compiling Node${buildOptions.length ? " with arguments: " + buildOptions : "..."
step.log(
`Compiling Node${
buildOptions.length ? " with arguments: " + buildOptions : "..."
}`
);
await this._runBuildCommandAsync(make, buildOptions);
await this._runBuildCommandAsync(step, make, buildOptions);
return createReadStream(this.getNodeExecutableLocation());
}
@@ -287,7 +292,7 @@ export class NexeCompiler {
}
async compileAsync(target: NexeTarget) {
const step = (this.compileStep = this.log.step("Compiling result"));
const step = this.log.step("Compiling result");
const build = this.options.build;
const location = this.getNodeExecutableLocation(build ? undefined : target);
let binary = (await pathExistsAsync(location))
@@ -295,10 +300,13 @@ export class NexeCompiler {
: null;
if (await this._shouldCompileBinaryAsync(binary, location)) {
binary = await this.build();
binary = await this.build(step);
step.log("Node binary compiled");
}
return this._assembleDeliverable(binary!);
if (!binary) {
throw new NexeError(`Could not locate binary: ${location}`);
}
return this._assembleDeliverable(binary);
}
code() {
+4 -2
View File
@@ -349,7 +349,9 @@ export class SnapshotZipFS extends BasePortableFakeFS {
let fallbackPaths: Array<string | Dirent<PortablePath>> = [];
try {
fallbackPaths = fallback();
} catch (e) { }
} catch (e) {
// no matching real-fs dir — fallbackPaths stays []
}
return fallbackPaths.concat(
uniqReaddir(zipFs.readdirSync(subPath, opts as any))
);
@@ -388,7 +390,7 @@ export class SnapshotZipFS extends BasePortableFakeFS {
return this.opendirSync(p, opts);
}
opendirSync(p: PortablePath, opts?: OpendirOptions) {
opendirSync(p: PortablePath, _opts?: OpendirOptions) {
const zipInfo = this.findZip(p);
let zipFsDir: Dir<PortablePath> | null = null;
if (zipInfo) {
+60 -15
View File
@@ -3,7 +3,7 @@ import { patchFs, PosixFS, NodeFS } from "@yarnpkg/fslib";
import { SnapshotZipFS } from "./SnapshotZipFS";
import * as assert from "assert";
import * as constants from "constants";
import { dirname, relative, sep } from "path";
import { dirname, relative } from "path";
export interface NexeHeader {
blobPath: string;
@@ -16,7 +16,7 @@ export interface NexeHeader {
}
let originalFsMethods: any = null;
let lazyRestoreFs = () => {};
let lazyRestoreFs = () => undefined;
const patches = (process as any).nexe.patches || {};
const originalPatches = { ...patches };
delete (process as any).nexe;
@@ -92,7 +92,9 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
}
// Handle Windows-style snapshot path: e.g., C:\snapshot\src\entry.js
if (filePath.startsWith(drive + "\\snapshot\\")) {
return "/snapshot/" + filePath.slice(drive.length + 9).replace(/\\/g, "/");
return (
"/snapshot/" + filePath.slice(drive.length + 9).replace(/\\/g, "/")
);
}
// Path under original project root
if (filePath.startsWith(projectRoot)) {
@@ -124,7 +126,11 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
patches.internalModuleReadFile = internalModuleReadFile;
// internalModuleReadJSON should return a string (or undefined) in Node 22
patches.internalModuleReadJSON = function (this: any, original: any, ...args: any[]) {
patches.internalModuleReadJSON = function (
this: any,
original: any,
...args: any[]
) {
const content = internalModuleReadFile.call(this, original, ...args);
return content === "" ? undefined : content;
};
@@ -197,7 +203,10 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
}
// Recursive exports resolver following Node's conditional exports
function resolvePackageExports(exports: any, conditions: string[]): string | null {
function resolvePackageExports(
exports: any,
conditions: string[]
): string | null {
if (typeof exports === "string") {
return exports;
}
@@ -280,7 +289,9 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
const idxPath = nodePath.posix.join(mainPath, "index.js");
if (isFileFn(idxPath)) return idxPath;
}
} catch (_) {}
} catch (_) {
// main path doesn't exist, fall through to extension/dist probing
}
for (const ext of [".js", ".json", ".node"]) {
const withExt = mainPath + ext;
@@ -294,9 +305,19 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
}
// 4. dist subdirectory (axios-style)
const distIndex = nodePath.posix.join(basePath, request, "dist", "index.js");
const distIndex = nodePath.posix.join(
basePath,
request,
"dist",
"index.js"
);
if (isFileFn(distIndex)) return distIndex;
const distMain = nodePath.posix.join(basePath, request, "dist", request + ".js");
const distMain = nodePath.posix.join(
basePath,
request,
"dist",
request + ".js"
);
if (isFileFn(distMain)) return distMain;
return null;
@@ -309,7 +330,10 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
const capturedOrigFindPath = (Module as any)._findPath;
if (typeof capturedOrigFindPath === "function") {
_origFindPath = capturedOrigFindPath;
(Module as any)._findPath = function nexeFindPath(this: any, ...args: any[]) {
(Module as any)._findPath = function nexeFindPath(
this: any,
...args: any[]
) {
const request: string = args[0];
// For bare module specifiers, try VFS first. Node 22 removed
@@ -318,7 +342,11 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
// Our code reads package.json via the patched fs.readFileSync which works.
if (request && request[0] !== "." && !nodePath.isAbsolute(request)) {
const basePath = "/snapshot/node_modules";
const pkgJsonPath = nodePath.posix.join(basePath, request, "package.json");
const pkgJsonPath = nodePath.posix.join(
basePath,
request,
"package.json"
);
let pkg: any;
try {
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8") as string);
@@ -326,7 +354,15 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
pkg = null;
}
if (pkg) {
const vfsResult = resolveFromPkg(pkg, basePath, request, nodePath, log, isFile, fs);
const vfsResult = resolveFromPkg(
pkg,
basePath,
request,
nodePath,
log,
isFile,
fs
);
if (vfsResult) {
log(`_findPath VFS resolved ${request} -> ${vfsResult}`);
return vfsResult;
@@ -351,7 +387,11 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
// Use snapshot node_modules as the base for all bare modules
const basePath2 = "/snapshot/node_modules";
const pkgJsonPath2 = nodePath.posix.join(basePath2, request, "package.json");
const pkgJsonPath2 = nodePath.posix.join(
basePath2,
request,
"package.json"
);
log(`_findPath secondary snapshot check: ${pkgJsonPath2}`);
let pkg2: any;
try {
@@ -359,7 +399,10 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
} catch (_) {
return result;
}
return resolveFromPkg(pkg2, basePath2, request, nodePath, log, isFile, fs) ?? result;
return (
resolveFromPkg(pkg2, basePath2, request, nodePath, log, isFile, fs) ??
result
);
};
}
} catch (_) {
@@ -373,10 +416,12 @@ function shimFs(binary: NexeHeader, fs: typeof import("fs") = require("fs")) {
try {
const Module = require("module");
(Module as any)._findPath = _origFindPath;
} catch (_) {}
} catch (_) {
// Module._findPath already restored/unpatchable, ignore
}
_origFindPath = null;
}
lazyRestoreFs = () => {};
lazyRestoreFs = () => undefined;
};
}
+7 -2
View File
@@ -28,7 +28,7 @@ export class Logger {
});
this.ora.stop();
}
const noop = () => { };
const noop = () => undefined;
this.modify = this.silent ? noop : this._modify.bind(this);
this.write = this.silent ? noop : this._write.bind(this);
}
@@ -50,7 +50,12 @@ export class Logger {
step(text: string, method = "succeed"): LogStep {
if (this.silent) {
return { modify() { }, log() { }, pause() { }, resume() { } };
return {
modify: () => undefined,
log: () => undefined,
pause: () => undefined,
resume: () => undefined,
};
}
if (!this.ora.id) {
this.ora.start().text = text;
+4 -2
View File
@@ -83,7 +83,9 @@ const defaults = {
bundle: true,
patches: [],
plugins: [],
remote: `https://github.com/oxmc/nexe/releases/download/v${require('../package.json').version}/`,
remote: `https://github.com/oxmc/nexe/releases/download/v${
require("../package.json").version
}/`,
};
const alias = {
i: "input",
@@ -207,7 +209,7 @@ export function resolveEntry(
input: string,
cwd: string,
maybeEntry: string | undefined,
bundle: boolean | string,
bundle: boolean | string
) {
let result = null;
if (input === "-" || maybeEntry === "-") {
+11 -8
View File
@@ -9,10 +9,9 @@ const fs = require("fs"),
let offset = stat.size,
footerPosition = -1,
footerPositionOffset = 0,
footer: Buffer;
footer: Buffer = Buffer.alloc(0);
while (true) {
for (;;) {
const bytesRead = fs.readSync(fd, tailWindow, 0, tailSize, offset - tailSize);
if (bytesRead === 0) break;
@@ -34,8 +33,8 @@ if (footerPosition == -1) {
throw "Invalid Nexe binary";
}
const contentSize = footer!.readDoubleLE(16),
resourceSize = footer!.readDoubleLE(24),
const contentSize = footer.readDoubleLE(16),
resourceSize = footer.readDoubleLE(24),
contentStart =
offset - tailSize + footerPosition - resourceSize - contentSize,
resourceStart = contentStart + contentSize;
@@ -85,9 +84,13 @@ fs.closeSync(fd);
// wrapper here, before any ESM code can load, so the resolver captures our version.
{
const _origRpSync: any = fs.realpathSync;
const nexeRpSync = function(p: string, opts?: any): string {
try { return _origRpSync(p, opts); }
catch (e: any) { if (e?.code === 'ENOENT') return p; throw e; }
const nexeRpSync = function (p: string, opts?: any): string {
try {
return _origRpSync(p, opts);
} catch (e: any) {
if (e?.code === "ENOENT") return p;
throw e;
}
};
(nexeRpSync as any).native = _origRpSync.native;
(fs as any).realpathSync = nexeRpSync;
+9 -6
View File
@@ -1,9 +1,12 @@
import { NexeCompiler } from '../compiler'
import { NexeCompiler } from "../compiler";
export default async function fsStat(compiler: NexeCompiler, next: () => Promise<void>) {
export default async function fsStat(
compiler: NexeCompiler,
next: () => Promise<void>
) {
await compiler.replaceInFileAsync(
'lib/fs.js',
'function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {',
"lib/fs.js",
"function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {",
`function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {
// If Node passes a file descriptor, we must fstat the REAL fs
if (typeof path === 'number') {
@@ -17,7 +20,7 @@ export default async function fsStat(compiler: NexeCompiler, next: () => Promise
}
}
`
)
);
return next()
return next();
}
+3 -3
View File
@@ -13,9 +13,9 @@ export default async function nodeGyp(
`
${nodeGypMarker}
${files
.filter((x) => x.filename.startsWith("lib"))
.map((x) => `'${x.filename}'`)
.toString()},
.filter((x) => x.filename.startsWith("lib"))
.map((x) => `'${x.filename}'`)
.toString()},
`.trim()
);
}
-1
View File
@@ -6,7 +6,6 @@ import flags from "./flags";
import ico from "./ico";
import rc from "./node-rc";
import snapshot from "./snapshot";
import fsStat from "./fs-stat-debug";
// Patches are applied in order, so if a patch depends on another patch, it should be listed after the patch it depends on.
// For example, if a patch modifies the output of gyp, it should be listed after gyp in this array.
+5 -5
View File
@@ -69,8 +69,8 @@ export default async function main(
location.start.line,
0,
'{{ file("lib/fs/bootstrap.js") }}' +
"\n" +
(semverGt(version, "11.99") ? "expandArgv1 = false;\n" : "")
"\n" +
(semverGt(version, "11.99") ? "expandArgv1 = false;\n" : "")
);
}
file.contents = fileLines.join("\n");
@@ -81,7 +81,7 @@ export default async function main(
bootFile,
"initializeFrozenIntrinsics();",
"initializeFrozenIntrinsics();\n" +
wrap('{{ file("lib/patches/boot-nexe.js") }}')
wrap('{{ file("lib/patches/boot-nexe.js") }}')
);
} else {
await compiler.replaceInFileAsync(
@@ -146,14 +146,14 @@ modulesBinding.readPackageJSON = function(jsonPath, ...rest) {
"src/node.cc",
"if (env->worker_context() != nullptr) {",
"if (env->worker_context() == nullptr) {\n" +
' return StartExecution(env, "internal/main/run_main_module"); } else {\n'
' return StartExecution(env, "internal/main/run_main_module"); } else {\n'
);
} else {
await compiler.replaceInFileAsync(
"src/node.cc",
"MaybeLocal<Value> StartMainThreadExecution(Environment* env) {",
"MaybeLocal<Value> StartMainThreadExecution(Environment* env) {\n" +
' return StartExecution(env, "internal/main/run_main_module");\n'
' return StartExecution(env, "internal/main/run_main_module");\n'
);
}
} else {
+24 -13
View File
@@ -19,9 +19,7 @@ function getModuleName(file: string): string | null {
const name = parts[idx + 1];
if (!name) return null;
return name.startsWith("@")
? parts.slice(idx + 1, idx + 3).join("/")
: name;
return name.startsWith("@") ? parts.slice(idx + 1, idx + 3).join("/") : name;
}
function getModuleBasePath(file: string, moduleName: string): string | null {
@@ -40,16 +38,16 @@ function getModuleBasePath(file: string, moduleName: string): string | null {
}
function getModuleRelativePath(file: string, moduleName: string): string {
const normalizedFile = file.replace(/\\/g, '/');
const normalizedModuleName = moduleName.replace(/\\/g, '/');
const normalizedFile = file.replace(/\\/g, "/");
const normalizedModuleName = moduleName.replace(/\\/g, "/");
const marker = `node_modules/${normalizedModuleName}/`;
const idx = normalizedFile.indexOf(marker);
if (idx === -1) {
return "";
}
return normalizedFile.slice(idx + marker.length);
}
@@ -149,8 +147,13 @@ function getStdIn(stdin: Readable): Promise<string> {
}
export default async function bundle(compiler: NexeCompiler, next: any) {
const { bundle: doBundle, cwd, input: inputPath, bundleRules } = compiler.options;
const {
bundle: doBundle,
cwd,
input: inputPath,
bundleRules,
} = compiler.options;
const rules: Record<string, ModuleRule> =
bundleRules && Object.keys(bundleRules).length ? bundleRules : {};
@@ -222,7 +225,11 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
for (const file of Object.keys(files)) {
const moduleName = getModuleName(file);
if (moduleName && rules[moduleName] && !modulesWithRules.has(moduleName)) {
if (
moduleName &&
rules[moduleName] &&
!modulesWithRules.has(moduleName)
) {
const basePath = getModuleBasePath(file, moduleName);
if (basePath) {
modulesWithRules.set(moduleName, basePath);
@@ -295,7 +302,11 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
if (!rootExport) continue;
for (const target of collectExportStrings(rootExport)) {
if (!target.startsWith("./") || target.endsWith(".d.ts") || target.endsWith(".map")) {
if (
!target.startsWith("./") ||
target.endsWith(".d.ts") ||
target.endsWith(".map")
) {
continue;
}
const absTarget = join(basePath, target);
@@ -348,4 +359,4 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
);
return next();
}
}
+7 -6
View File
@@ -31,7 +31,7 @@ export default async function cli(
const { log } = compiler,
target = compiler.options.targets.shift() as NexeTarget,
deliverable = await compiler.compileAsync(target),
output = normalize(compiler.output!);
output = normalize(compiler.output);
mkdirp.sync(dirname(output));
@@ -60,11 +60,12 @@ export default async function cli(
chmodSync(output, mode.toString(8).slice(-3));
step.log(
`Entry: '${compiler.stdinUsed
? compiler.options.mangle
? STDIN_FLAG
: "[none]"
: inputFileLogOutput
`Entry: '${
compiler.stdinUsed
? compiler.options.mangle
? STDIN_FLAG
: "[none]"
: inputFileLogOutput
}' written to: ${outputFileLogOutput}`
);
compiler.quit();
+3 -2
View File
@@ -6,7 +6,7 @@ import { dirname } from "path";
import { createWriteStream } from "fs";
import { pipeline } from "stream/promises";
import { createGunzip } from "zlib";
import * as tar from 'tar';
import * as tar from "tar";
import fs from "fs/promises";
async function downloadWithProgress(
@@ -141,7 +141,8 @@ export default async function downloadNode(
sourceUrl ||
`https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`,
step = log.step(
`Downloading ${build ? "" : "pre-built"} Node.js ${build ? `source from: ${url}` : ""
`Downloading ${build ? "" : "pre-built"} Node.js ${
build ? `source from: ${url}` : ""
}`
),
exeLocation = compiler.getNodeExecutableLocation(
+4 -4
View File
@@ -58,7 +58,7 @@ class Target implements NexeTarget {
public arch: NodeArch,
public platform: NodePlatform,
public version: string
) { }
) {}
toJSON() {
return this.toString();
}
@@ -78,9 +78,9 @@ export function getTarget(
): NexeTarget {
const currentArch = process.arch;
let arch =
currentArch in prettyArch
? prettyArch[process.arch]
: (process.arch as NodeArch),
currentArch in prettyArch
? prettyArch[process.arch]
: (process.arch as NodeArch),
platform = prettyPlatform[process.platform],
version = process.version.slice(1);
+5 -5
View File
@@ -1,9 +1,7 @@
import { readFile, writeFile, stat } from "fs";
import { execFile } from "child_process";
import { promisify } from "util";
import rimraf = require("rimraf");
const rimrafAsync = promisify(rimraf);
import { rimraf as rimrafAsync } from "rimraf";
export const STDIN_FLAG = "[stdin]";
export async function each<T>(
@@ -72,7 +70,7 @@ const isWindows = process.platform === "win32";
function pathExistsAsync(path: string) {
return statAsync(path)
.then((x) => true)
.then((_x) => true)
.catch(falseOnEnoent);
}
@@ -87,7 +85,9 @@ function isDirectoryAsync(path: string) {
*/
function semverGt(version: string, operand: string) {
const [cMajor, cMinor, cPatch] = version.split(".").map(Number);
let [major, minor, patch] = operand.split(".").map(Number);
const operandParts = operand.split(".").map(Number);
const major = operandParts[0];
let [, minor, patch] = operandParts;
if (!minor) minor = 0;
if (!patch) patch = 0;
return (
+3 -2
View File
@@ -73,7 +73,7 @@ async function build() {
options = {
mangle: false,
build: true,
verbose: Boolean(env.NEXE_VERBOSE!),
verbose: Boolean(env.NEXE_VERBOSE),
target,
make: ["-j" + cpus().length],
output,
@@ -94,7 +94,8 @@ async function build() {
await assertNexeBinary(output);
const gitRelease = await getLatestGitRelease({ headers }),
unbuiltReleases = await getUnBuiltReleases({ headers });
if (!unbuiltReleases.some((x) => targetsEqual(x, target!))) {
const builtTarget: NexeTarget = target;
if (!unbuiltReleases.some((x) => targetsEqual(x, builtTarget))) {
console.log(`${target} already uploaded.`);
process.exit(0);
return;
+2 -2
View File
@@ -1,4 +1,4 @@
import { NexeTarget, architectures } from "../lib/target";
import { NexeTarget } from "../lib/target";
import { writeFileAsync, readFileAsync } from "../lib/util";
import axios from "axios";
import execa = require("execa");
@@ -26,7 +26,7 @@ RUN echo "console.log('hello world')" >> index.js && \
`.trim();
}
function arm(target: NexeTarget) {
export function arm(target: NexeTarget) {
return `
FROM hypriot/rpi-node
ENV NEXE_VERSION=latest