-
Notifications
You must be signed in to change notification settings - Fork 36
Requiring Aliases, Services & HTML Templates
We need to add support for detecting when an alias is used in a CommonJs module, and this could be done in one of two ways:
- Scan CommonJs modules with a trie containing all possible aliases.
- Allow
require()
to be passed alias references.
The former would be far less performant due to the need to re-scan all CommonJs modules each time an 'aliases.xml' or 'aliasDefinitions.xml' file changes, which due to how MemoizedValue
works, would effectively mean we would re-scan when any file in the app changes. The latter also looks better to the eye, and fits in With Adam Iley's vision that require()
should be used for other things, like services and HTML templates.
Vanilla CommonJs supports three types of require path:
require('absolute-require-path')
require('./relative-require-path')
require('/file-path')
So that we could add support for aliases, services and HTML templates by introducing special leading characters, for example:
require("@the-alias")
require("#the-service")
require("$html-template")
or we could adopt the RequireJs plug-in syntax, for example:
require("alias!the-alias")
require("service!the-service")
require("html!html-template")
Whereas RequireJs plug-ins are just regular JavaScript modules, but conforming to a special API, BladeRunnerJS require plug-ins would need to be implemented on the server. In fact, the browser-modules library need have no knowledge of these plug-ins, as it merely allows modules to be required using either an absolute require-path (simple key lookup), or using a relative require-path (key normalization followed by a lookup). Given that the key normalization is affected only by the use of '/' characters, 'browser-modules' can remain unaware of plug-ins provided this character is disallowed within plug-in names.
The plug-in API will look something like this, making it possible to know which asset a require-path is actually pointing at:
public interface RequirePlugin extends Plugin {
String getPluginName();
Asset getAsset(String requirePathSuffix);
}
The requirePathSuffix
will be the require-path minus the plug-in prefix, and getPluginName()
will be a an identifer-method, allowing it to be invoked before setBRJS()
is invoked.
A RequirePathUtility
class will be made available to centralize this code, so it doesn't need to be re-written by different plug-ins, and will have the interface:
public class RequirePathUtility {
public static Asset getAsset(String requirePath);
}
This utility class will be made available for public consumption via App.asset(String requirePath)
, a method that should have existed even before we added support for require plug-ins anyway.