Repository navigation
fix: inject import.meta.hot into every module using import.meta - #20
Merged
Merged
Conversation
ed28a8c only injected the helpers into modules containing `import.meta.hot`. @adonisjs/fold re-imports controllers only when `"hot" in import.meta`, so AdonisJS stopped hot reloading controllers. A module can only reach its `import.meta` by writing it in its own source, so inject into every module containing `import.meta` and leave the others unchanged. To keep positions exact in injected modules, shift their inline source map (tsx, ts-node, @poppinss/ts-exec) by the length of the injected code. Also decode `source` with TextDecoder: `toString()` on a Uint8Array returns its comma-separated bytes. Refs #15 Amp-Thread-ID: https://ampcode.com/threads/T-01a1b212-dc0a-7380-bad5-624903b77b96
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes a regression from ed28a8c (#15), which is on
mainbut not released yet.Why
ed28a8c only injects the
import.meta.hothelpers into modules whose source containsimport.meta.hot.@adonisjs/fold(and@adonisjs/auth) decide whether to re-import a controller with"hot" in import.meta, which doesn't match, so onmainAdonisJS keeps serving the cached controller after an edit. Reproduced in a fresh Adonis 7 app: controller edit stays at v1 onmain, v1 → v2 with this PR. Any other way of readinghot(minified code,import.meta\n.hot,const { hot } = import.meta,import.meta['hot']) is missed the same way.What changes
import.meta. A module can only reach itsimport.metaby writing it in its own source (evalandnew FunctionthrowCannot use 'import.meta' outside a module), so modules without it still load unchanged, and no access tohotcan be missed.import.meta.hot#15: injected modules keep exact positions when they have an inline source map (tsx, ts-node,@poppinss/ts-exec). The injected code is on line 1 only, so hot-hook shifts the first generated column of the map by its length (source_map.ts, a single VLQ value). Costs 0.03 ms for a controller, 0.25 ms for a 26 KB file.sourceis decoded withTextDecoder:toString()on aUint8Array(returned when an async loader is in the chain) gives comma-separated bytes.Limitations
import.metaand have no source map (or an external.mapfile) still get line 1 shifted, as before ed28a8c. A per-column identity map would be ~5x the file size.module.register()), a sync TS loader such as@poppinss/ts-execreads the source through hot-hook, so hot-hook sees untranspiled TS without a map and can't shift it (same as the published 1.0.0). With in-thread hooks (feat: use module.registerHooks() instead of deprecated module.register() #19), hot-hook wraps the loader output and the map is shifted.node file.tswithout a loader,format: 'module-typescript') still doesn't getimport.meta.hot, as before. Injecting there would shift TS loaders' maps in the case above, since hot-hook can't tell whether a transpiler runs after it.Verification
"hot" in import.metagets the helpers (fails with ed28a8c's filter), an inline map keepsoriginal.ts:1:11(fails without the shift), a module withoutimport.metakeeps its positions (fails without a filter).pnpm quick:test29/29 on Node 22.14, 22.15, 22.22.3, 24.22.2, 26.12.1.create-adonisjsapps drivingnode ace serve --hmr(boot, controller and service HMR, runtime error and recovery, full reload on routes, restart on.env, HMR after restart): 9/9 for Adonis 7 on Node 26, Adonis 6 on Node 26 and 22.15.--enable-source-maps, without hot-hook vs with: tsx1:51/1:51, ts-node1:51/1:51.