Git Product home page Git Product logo

packherd's Introduction

packherd

Herds all dependencies reachable from an entry and packs them.

API Documentation

Table of Contents generated with DocToc

Summary

packherd has three main tasks:

  1. bundling application files and providing related metadata
  2. 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
  3. transpiling TypeScript modules on demand and maintaining a cache of them

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 that requires to intercept module loads.

Creating a Bundle with Packherd

Calling the packherd function and providing the desired packherd opts will return the Buffer of the bundle, a meta esbuild metafile, a Buffer containing the sourceMap if it was generated as well as any warnings that esbuild emitted.

The caller can then store this data or use it for further operations, i.e. to generate a snapshot as is the case for the v8-snapshot module.

Loading Bundled/Snapshotted Modules with Packherd

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 by require ing each module previously or by having them snapshotted into the application
  • moduleDefinitions: similar to moduleExports except that these are functions that need to be invoked in order to obtain the module.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 the getModuleKey implementation 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.

Transpiling TypeScript Modules on Demand

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.

Transpile Cache

I 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 })

Sourcemap Support

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

Implementation

Please find more implementation details regarding transpilation inside ./src/transpile-ts.ts.

Import Caveats

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 I recommend doing this properly via a tool like proxyquire, but attempts have been made to work around this by rewriting the JS that esbuild emits.

Please see the ongoing work inside the feat/stubbable branch, particularly the transpile-ts-rewrite.ts module.

Env Vars

  • PACKHERD_CODE_FRAMES if set will include code snippets for error messages that have been sourcemapped

LICENSE

MIT

packherd's People

Contributors

forivall avatar thlorenz avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.