Skip to content

Better support for loader plugins #5787

Closed
@kitsonk

Description

Currently TypeScript does not have a good understanding of loader plugins. Both AMD and SystemJS support the concept of loader plugins (though they vary in format). Currently the only way to integrate a loader plugin is specify the full module name as an ambient declaration and describe the shape of what is returned. For some plugins, this is quite a redundant activity (like a text plugin) since all resources returned by the plugin are text resources.

Both with AMD and SystemJS (also proposed for ES6 module loader), plugins do not have to return a consistent shape. Because of this, I think there are two approaches:

  1. Create resolution logic that supports some sort of glob pattern for ambient declarations, with resolution of the most specific declaration.
  2. Integrate more robust functionality in understanding plugins and what shape they return.

For background reading here is the specification of each:

For SystemJS there are four methods that can be overridden the are exposed by the plugin module:

  • locate - Allows a return of an alternative location for the resource.
  • fetch - Allows the plugin to fetch the "raw" resource.
  • translate - Allows the plugin to modify the resource (e.g. translate on the fly from CoffeeScript to JS)
  • instantiate - Called when the loader actually tries to instantiate the module.

For AMD there:

  • normalize - Allows the resource ID to be modified
  • load - Allows hooking into the actual load and instantiation of the module

RequireJS has support for a couple more, which are specifically geared for building code, but they are not officially part of the AMD standard:

  • write - Write out the module
  • onLayerEnd - Allows a hook into when a layer is finished
  • writeFile - Hook when the file is written
  • pluginBuilder - Substitute another module for this module when doing a build

Also there is a big difference between AMD and SystemJS in the format of the MID for plugins, annoyingly (I won't get on my soap box about how we reinvent the wheel in on the web). AMD is [plugin]![resource] and SystemJS is [resource]![plugin].

@mhegazy asked if plugins change their shape. My personal experience is with AMD and in that case, in practice, some plugins do change their shape (for example in Dojo we have a module that loads CommonJS modules called dojo/node) and others that never change their shape (for example dojo/text loads text resources) and ones where the resource ID determines what is loaded (for example dojo/has take a feature flag and a ternary operator to determine what it loads).

My personal feeling is that option 2 would be horribly complex, likely to have all sorts of edge cases, and while highly useful for those using plug-ins, might just become too challenging. If/when the ES6 Loader is finalised and there is plugin support in there, then having a feature rich analysis of those plugins might be worth the effort. Until then, I think option 1 would allow people to achieve the most use cases with a minimum amount of complexity.

This is related to a discussion that came up in #5759.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions