-
Notifications
You must be signed in to change notification settings - Fork 36
BladeRunnerJS NPM Integration Strawman
We'd like BladeRunnerJS developers to be able to:
- Easily consume the huge number of libraries in NPM.
- Create NPM modules instead of creating BRJS libraries.
- Create multi-asset NPM modules instead of creating BRJS blades.
BladeRunnerJS doesn't currently have a hard dependency on Node.js, and the last time we canvassed our user-base some of them were unable to use Node.js even in development, but this may very well have changed in the intervening period. Clearly though, not needing to have this dependency would be even easier from a bureaucratic point of view, yet integration with NPM is becoming a necessity.
Whereas libraries can currently reside within the application or the SDK, where application libraries take precedence over SDK libraries, we'd additionally like to support NPM modules at these locations:
-
SDK/apps/<app>/node_modulesfor app libraries. -
SDK/node_modulesfor SDK libraries.
The npm install and npm update commands, responsible for populating the node_modules directory, contain all the smarts for determining which versions of each module is to be used, potentially allowing us to avoid having a hard dependency on Node.js if we are willing to parse node_modules, which would invole us re-implementing the functionality present within require.resolve() in Java.
Although we originally imagined that we'd be able to have a mix and match approach, where libraries of all types can co-depend on each other, it's become clear that this approach won't be possible since NPM's installation algorithm can only function correctly when it's able to interpret the semver information for all dependencies. Therefore, although BRJS libraries will be able to depend on NPM modules, NPM modules won't be able to depend on BRJS libraries.
NPM's local-paths or npm link features can be used to allow NPM libraries and blades to be conveniently developed at the same time as the app.
Users that take advantage of the global-install feature to allow the SDK to be independent of the apps will need to set the NODE_PATH environment variable so that it points to SDK/node_modules.
Developers that use NPM modules in their own apps will need to update their package.json to have entries for each of the SDK libraries currently updated to use NPM. Every time we update a library to NPM, this will cause a backwards compatibility issue. Additionally, if they set the version of internal SDK libraries to anything other than latest, then this may cause them not to get updates when they update the SDK.
These problems can be solved by having a brjs npm command that does the following:
- Updates
package.jsonto include valid entries for all of the SDK NPM libraries that the app uses. - Sets the
NODE_PATHenvironment variable if needed (maybe Windows only?). - Invokes
npm updateon your behalf, ensuring theNODE_PATHenvironment variable has been set.
and, by allowing non-NPM apps to forgo the package.json completely, and have us determine the NPM dependencies ourselves.
SystemJS will be used to replace browser-modules because it provides a number of advantages:
- It makes it easier for BRJS & NPM modules to co-exist.
- It can be made to allow multi-asset NPM modules (NPM blades) to be developed.
- It makes it easier for us to avoid a hard dependency on Node.js, since it means we won't need to re-implement browserify in Java.
- It even makes it possible for NPM modules to have hidden dependencies on BRJS modules (via
System.import()), which may be useful as a last resort to hack around problems.
- SDK libraries aren't currently plug-able as the model dictates that libraries are the directories beneath
SDK/sdk/libs/javascriptandSDK/apps/<app>/libs. The asset-location plug-ins are then each given a chance to describe the asset locations within a particular library directory (usinggetAssetLocationDirectories()andgetSeedAssetLocationDirectories()), and can also work together with other plug-ins to provide these asset locations (viaallowFurtherProcessing()).