222 lines
9.7 KiB
HTML
222 lines
9.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Session Summary — 3 July 2026</title>
|
|
<link rel="stylesheet" href="../../../../_assets_/styles.css">
|
|
<link rel="stylesheet" href="../../../../_assets_/nav.css">
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
|
|
<header>
|
|
<p class="date">Friday, 3 July 2026</p>
|
|
<h1>Roject — ES Modules & Library Integration</h1>
|
|
<p class="subtitle">Session summary: confirm-dialog fix, ES module refactor, shared library submodule, TypeScript project references.</p>
|
|
</header>
|
|
|
|
<section>
|
|
<h2>What we fixed</h2>
|
|
|
|
<div class="card">
|
|
<h3>Confirm Dialog & Build Workflow</h3>
|
|
<p>
|
|
The project delete confirm dialog was not working because <code>npm run build</code>
|
|
had not been run after the last code change, and the server had not been restarted.
|
|
The compiled <code>.js</code> in <code>public/</code> was stale. No code change
|
|
was needed — the fix was running the build and restart. Established that debugging
|
|
frontend issues always requires a fresh build first.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">npm run build</span>
|
|
<span class="tag">stale compiled output</span>
|
|
<span class="tag">confirm-dialog</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>What we built</h2>
|
|
|
|
<div class="card">
|
|
<h3>ES Module Refactor</h3>
|
|
<p>
|
|
The frontend was rewritten from <code>module: none</code> (global scripts) to
|
|
proper ES modules. <code>tsconfig.client.json</code> now uses
|
|
<code>module: ESNext</code> and <code>moduleResolution: bundler</code>.
|
|
All HTML pages switched from <code><script src></code> to
|
|
<code><script type="module" src></code>. Components now use
|
|
<code>import</code> / <code>export</code> and no longer rely on global scope.
|
|
The browser deduplicates shared module imports automatically.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">module: ESNext</span>
|
|
<span class="tag">moduleResolution: bundler</span>
|
|
<span class="tag">script type="module"</span>
|
|
<span class="tag">import / export</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>EditorState as a Proper Module</h3>
|
|
<p>
|
|
<code>EditorState</code> was extracted from <code>editor-shell.ts</code> into its
|
|
own module at <code>src/components/editor-state.ts</code>. It exports
|
|
<code>setEditorState()</code> (called by <code>editor-shell</code> on init) and
|
|
<code>getEditorState()</code> (called by any component that needs it).
|
|
The <code>window.editorState</code> global is gone. Components import what they
|
|
need directly.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">editor-state.ts</span>
|
|
<span class="tag">getEditorState()</span>
|
|
<span class="tag">setEditorState()</span>
|
|
<span class="tag">no window globals</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Confirm Dialog Export</h3>
|
|
<p>
|
|
<code>showConfirmDialog</code> and <code>ConfirmDialogOptions</code> are now
|
|
properly exported from <code>confirm-dialog.ts</code>.
|
|
<code>project-editor.ts</code> imports <code>showConfirmDialog</code> directly
|
|
instead of using a <code>/// <reference path></code> directive. The
|
|
redundant <code><script></code> tag for <code>confirm-dialog.js</code> in
|
|
<code>projects.html</code> was removed — the browser loads it via the import graph.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">export showConfirmDialog</span>
|
|
<span class="tag">import instead of reference</span>
|
|
<span class="tag">no redundant script tag</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Shared Library as Git Submodule</h3>
|
|
<p>
|
|
A personal TypeScript library was added as a git submodule at
|
|
<code>src/library-ts/</code>. The library has two parts:
|
|
<code>browser/</code> (DOM-capable, usable with shims on Node) and
|
|
<code>node/</code> (Node.js only). Placing the submodule inside <code>src/</code>
|
|
keeps <code>rootDir: "src"</code> intact so the output URL structure in
|
|
<code>public/</code> is unchanged.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">git submodule</span>
|
|
<span class="tag">src/library-ts/</span>
|
|
<span class="tag">browser/ + node/</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>TypeScript Project References</h3>
|
|
<p>
|
|
The library was written without <code>strict: true</code>, causing hundreds of
|
|
errors when compiled with Roject's strict settings. TypeScript project references
|
|
solve this: a new <code>tsconfig.roject.json</code> inside
|
|
<code>src/library-ts/browser/</code> compiles the browser part separately with
|
|
<code>strict: false</code>, <code>composite: true</code>, and
|
|
<code>declaration: true</code>. Roject's <code>tsconfig.client.json</code>
|
|
excludes <code>src/library-ts/**/*</code> and references the library project.
|
|
Build now runs as <code>tsc --build tsconfig.client.json</code>.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">project references</span>
|
|
<span class="tag">composite: true</span>
|
|
<span class="tag">declaration: true</span>
|
|
<span class="tag">tsc --build</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Server-Side Library Configuration</h3>
|
|
<p>
|
|
The node part of the library caused the same strict errors when compiled by
|
|
<code>ts-node</code>. A dedicated <code>tsconfig.ts-node.json</code> extends the
|
|
server tsconfig but turns off <code>strictNullChecks</code> (the only check the
|
|
library violates) and adds <code>src/library-ts/node/**/*</code> to the include.
|
|
The start script now passes <code>--project tsconfig.ts-node.json</code> to
|
|
<code>ts-node</code>.
|
|
</p>
|
|
<div class="tags">
|
|
<span class="tag">tsconfig.ts-node.json</span>
|
|
<span class="tag">strictNullChecks: false</span>
|
|
<span class="tag">ts-node --project</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Key Decisions</h2>
|
|
|
|
<div class="decision">
|
|
<strong>ES modules over global scripts</strong>
|
|
<p>
|
|
<code>module: none</code> was originally chosen to avoid a bundler, but it also
|
|
ruled out <code>import</code> / <code>export</code> and forced the
|
|
<code>window.editorState</code> workaround. Browsers support ES modules natively
|
|
via <code>type="module"</code> scripts — no bundler needed. The switch removes
|
|
all global-scope workarounds and makes the library integration straightforward.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="decision">
|
|
<strong>Submodule inside <code>src/</code>, not at project root</strong>
|
|
<p>
|
|
Placing the submodule at <code>src/library-ts/</code> keeps
|
|
<code>rootDir: "src"</code> in the client tsconfig unchanged. A submodule at the
|
|
project root would require either changing rootDir (breaking the
|
|
<code>/components/...</code> URL structure) or setting up path aliases.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="decision">
|
|
<strong>Separate tsconfig per compilation unit, not a single monolithic one</strong>
|
|
<p>
|
|
Three tsconfigs now serve distinct purposes: <code>tsconfig.json</code> (server,
|
|
strict), <code>tsconfig.client.json</code> (frontend, strict, references library),
|
|
<code>tsconfig.ts-node.json</code> (runtime, relaxed for library compatibility).
|
|
This keeps strict checking on all first-party code without patching the library.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="decision">
|
|
<strong>Only <code>strictNullChecks</code> turned off for ts-node</strong>
|
|
<p>
|
|
All three errors in the node library were <code>strictNullChecks</code> violations.
|
|
Rather than disabling all of <code>strict</code>, only that one flag is overridden
|
|
in <code>tsconfig.ts-node.json</code>. Server code retains
|
|
<code>noImplicitAny</code>, <code>strictFunctionTypes</code>,
|
|
<code>strictPropertyInitialization</code>, and all other strict checks.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Project Structure</h2>
|
|
<div class="card">
|
|
<p>
|
|
<code>src/components/editor-state.ts</code> — EditorState module (getEditorState / setEditorState)<br>
|
|
<code>src/library-ts/browser/</code> — shared browser library (git submodule)<br>
|
|
<code>src/library-ts/node/</code> — shared node library (git submodule)<br>
|
|
<code>src/library-ts/browser/tsconfig.roject.json</code> — library browser tsconfig (strict: false, composite)<br>
|
|
<code>tsconfig.client.json</code> — frontend: ESNext modules, references library<br>
|
|
<code>tsconfig.ts-node.json</code> — ts-node runtime: extends server tsconfig, strictNullChecks: false<br>
|
|
<code>public/library-ts/browser/</code> — compiled library output with .d.ts files
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
Roject — session log — 3 July 2026
|
|
</footer>
|
|
|
|
</div>
|
|
<script>var NAV_ROOT = '../../../../';</script>
|
|
<script src="../../../../_assets_/nav-data.js"></script>
|
|
<script src="../../../../_assets_/nav.js"></script>
|
|
</body>
|
|
</html>
|