Loads modules that have been bundled by @tooling/packherd
.
Table of Contents
- Summary
- Loading Bundled/Snapshotted Modules with Packherd
- Transpiling TypeScript Modules on Demand
- Env Vars
packherd has three main tasks:
- bundling application files and providing related metadata
- loading modules that have been bundled previously and are provided via fully instantiated module exports or definition functions that return a module export when invoked
- transpiling TypeScript modules on demand and maintaining a cache of them
1.
is provided by @tooling/packherd
. 2.
and 3.
are provided by this package. While 1.
and 2.
are very related and work hand in hand, 3.
is unrelated to them and was
just added here since it is another feature required to intercept module loads.
In order to hook into the require
process and load from a different source instead of the
file system the packherdRequire function needs to be invoked with the desired
configuration. Note that both this hook and the transpile TypeScript on demand feature can
function together without any problem.
The require opts that are passed to this function allow to configure how packherd resolves and loads the modules that are included via one of the following:
moduleExports
: map of fully instantiated module exports that have been obtained either byrequire
ing each module previously or by having them snapshotted into the applicationmoduleDefinitions
: similar tomoduleExports
except that these are functions that need to be invoked in order to obtain themodule.exports
, thus incurring some overhead
Since packherd cannot know how the modules are keyed inside the maps, you should pass a getModuleKey
function of this type in order to resolve those keys.
For example in the case of v8-snapshot (TODO: Update this link when snapshot module is added) the getModuleKey implementation (TODO: Update this link when snapshot module is added) implementation relies on a resolver map that is embedded inside the app's snapshot. Additionally it knows how modules are keyed via the modified esbuild bundler it uses.
Once the module key has been resolved (or even if not) packherd tries its best to resolve and/or load the module from the most efficient source. It attempts to avoid accessing the file system until no more options remain and only loads it via the Node.js resolution/loader mechanism when all else failed.
For more details on the module resolve/load steps refer to PackherdModuleLoader, in particular tryLoad
and tryResolve
including
the relevant code sections which include detailed comments for each step.
To enable this feature the packherdRequire has to be invoked in order to
have it hook into Node.js require
calls via a Module._extension
. Particularly the
transpileOpts
field of the opts needs to be configured as follows.
supportTS
:true
initTranspileCache
: needs to be a function matching InitTranspileCache
We recommend to use the dirt-simple-file-cache module to provide the transpile cache as it has been developed alongside packherd for just this purpose.
Here is an example of how that option field could be setup with this module.
const dirtSimpleFileCache = require('dirt-simple-file-cache')
const initTranspileCache = () =>
DirtSimpleFileCache.initSync(projectBaseDir, { keepInMemoryCache: true })
In order to show original locations for errors logged to the console, packherd hooks into the generation of error stack traces and maps locations to TypeScript.
For more information please read the sourcemap docs
Please find more implementation details regarding transpilation inside ./src/transpile-ts.ts.
Since esbuild enforces the behaviour of imports being static this caused problems
with tests that relied on being able to patch/sinon.stub
modules even after they were
imported.
In general we would recommend doing this properly via a tool like proxyquire.
PACKHERD_CODE_FRAMES
if set will include code snippets for error messages that have been sourcemapped