Skip to content

Commit

Permalink
Watch mode (#4)
Browse files Browse the repository at this point in the history
* Watch mode

* Restart

* Make it work!
  • Loading branch information
jodosha authored Sep 7, 2023
1 parent f8528dd commit aa64a47
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 42 deletions.
73 changes: 53 additions & 20 deletions dist/hanami-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const glob_1 = require("glob");
const node_process_1 = require("node:process");
Expand Down Expand Up @@ -53,8 +54,15 @@ const externalEsbuildDirectories = () => {
return [];
}
};
const touchManifest = (dest) => {
const manifestPath = path_1.default.join(dest, "public", "assets.json");
const manifestDir = path_1.default.dirname(manifestPath);
fs_extra_1.default.ensureDirSync(manifestDir);
fs_extra_1.default.writeFileSync(manifestPath, JSON.stringify({}, null, 2));
};
const args = parseArgs(node_process_1.argv);
const dest = process.cwd();
const watch = args.hasOwnProperty("watch");
const outDir = path_1.default.join(dest, 'public', 'assets');
const loader = {
'.tsx': 'tsx',
Expand Down Expand Up @@ -87,23 +95,48 @@ if (args['sri']) {
sriAlgorithms = args['sri'].split(',');
}
const options = { ...hanami_esbuild_plugin_2.defaults, sriAlgorithms: sriAlgorithms };
const config = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "silent",
minify: true,
sourcemap: true,
entryNames: "[dir]/[name]-[hash]",
plugins: [(0, hanami_esbuild_plugin_1.default)(options)],
};
// FIXME: add `await` to esbuild.build
esbuild_1.default.build({
...config,
entryPoints: mappedEntryPoints,
}).catch(err => {
console.log(err);
process.exit(1);
});
if (watch) {
touchManifest(dest);
const watchBuildOptions = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "info",
minify: false,
sourcemap: false,
entryNames: "[dir]/[name]",
entryPoints: mappedEntryPoints,
plugins: [(0, hanami_esbuild_plugin_1.default)(options)],
};
esbuild_1.default.context(watchBuildOptions).then((ctx) => {
// FIXME: add `await` to ctx.watch
ctx.watch();
}).catch(err => {
console.log(err);
process.exit(1);
});
}
else {
const config = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "silent",
minify: true,
sourcemap: true,
entryNames: "[dir]/[name]-[hash]",
plugins: [(0, hanami_esbuild_plugin_1.default)(options)],
};
// FIXME: add `await` to esbuild.build
esbuild_1.default.build({
...config,
entryPoints: mappedEntryPoints,
}).catch(err => {
console.log(err);
process.exit(1);
});
}
78 changes: 58 additions & 20 deletions src/hanami-assets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node

import fs from 'fs-extra';
import path from 'path';
import { globSync } from 'glob'
import { argv } from 'node:process';
Expand Down Expand Up @@ -61,8 +62,18 @@ const externalEsbuildDirectories = (): string[] => {
}
};

const touchManifest = (dest: string): void => {
const manifestPath = path.join(dest, "public", "assets.json");
const manifestDir = path.dirname(manifestPath);

fs.ensureDirSync(manifestDir);

fs.writeFileSync(manifestPath, JSON.stringify({}, null, 2));
}

const args = parseArgs(argv);
const dest = process.cwd();
const watch = args.hasOwnProperty("watch");
const outDir = path.join(dest, 'public', 'assets');
const loader: { [ext: string]: Loader } = {
'.tsx': 'tsx',
Expand Down Expand Up @@ -98,24 +109,51 @@ if (args['sri']) {
}

const options: HanamiEsbuildPluginOptions = { ...defaults, sriAlgorithms: sriAlgorithms };
const config: Partial<BuildOptions> = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "silent",
minify: true,
sourcemap: true,
entryNames: "[dir]/[name]-[hash]",
plugins: [hanamiEsbuild(options)],
}

// FIXME: add `await` to esbuild.build
esbuild.build({
...config,
entryPoints: mappedEntryPoints,
}).catch(err => {
console.log(err);
process.exit(1);
});
if (watch) {
touchManifest(dest);

const watchBuildOptions: Partial<BuildOptions> = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "info",
minify: false,
sourcemap: false,
entryNames: "[dir]/[name]",
entryPoints: mappedEntryPoints,
plugins: [hanamiEsbuild(options)],
}

esbuild.context(watchBuildOptions).then((ctx) => {
// FIXME: add `await` to ctx.watch
ctx.watch();
}).catch(err => {
console.log(err);
process.exit(1);
});
} else {
const config: Partial<BuildOptions> = {
bundle: true,
outdir: outDir,
absWorkingDir: dest,
loader: loader,
external: externalDirs,
logLevel: "silent",
minify: true,
sourcemap: true,
entryNames: "[dir]/[name]-[hash]",
plugins: [hanamiEsbuild(options)],
}

// FIXME: add `await` to esbuild.build
esbuild.build({
...config,
entryPoints: mappedEntryPoints,
}).catch(err => {
console.log(err);
process.exit(1);
});
}
52 changes: 50 additions & 2 deletions test/hanami-assets.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import fs from 'fs-extra';
import path from 'path';
import { globSync } from 'glob'
import { execFileSync, execSync } from 'child_process';
import { ChildProcess, execFileSync, execSync, spawn } from 'child_process';
import crypto from 'node:crypto';

const originalWorkingDir = process.cwd();
const binPath = path.join(originalWorkingDir, 'dist', 'hanami-assets.js');

const dest = path.resolve(__dirname, '..', 'tmp', crypto.randomUUID());
const watchTimeout = 60000; // ms (60 seconds)
let watchProcess : ChildProcess;

// Helper function to create a test environment
async function createTestEnvironment() {
Expand All @@ -23,6 +25,10 @@ async function createTestEnvironment() {

// Helper function to clean up the test environment
async function cleanTestEnvironment() {
if (watchProcess) {
watchProcess.kill();
}

process.chdir(originalWorkingDir);
await fs.remove(dest); // Comment this line to manually inspect precompile results
}
Expand Down Expand Up @@ -159,6 +165,48 @@ describe('hanami-assets', () => {
]
}
});

});

test("watch", async () => {
const entryPoint = path.join(dest, "app", "assets", "javascripts", "app.js");
await fs.writeFile(entryPoint, "console.log('Hello, World!');");

const appAsset = path.join(dest, "public", "assets", "app.js");

watchProcess = spawn(binPath, ["--watch"], {cwd: dest});
await fs.writeFile(entryPoint, "console.log('Hello, Watch!');");

const appAssetExists = (timeout = watchTimeout): Promise<boolean> => {
return new Promise((resolve, reject) => {
let elapsedTime = 0;
const intervalTime = 100;

const interval = setInterval(() => {
if (fs.existsSync(appAsset)) {
clearInterval(interval);
resolve(true);
}

// console.log("Waiting for asset to be generated...", elapsedTime, dest, appAsset);

elapsedTime += intervalTime;
if (elapsedTime >= timeout) {
clearInterval(interval);
reject(false);
}
}, intervalTime);
});
}

const found = await appAssetExists();
expect(found).toBe(true);

// Read the asset file
const assetContent = await fs.readFile(appAsset, "utf-8");

// Check if the asset has the expected contents
expect(assetContent).toMatch("console.log(\"Hello, Watch!\");");

// childProcess.kill("SIGHUP");
}, watchTimeout + 1000);
});

0 comments on commit aa64a47

Please sign in to comment.