interlock
For information about Interlock and how it works, check out our website. To learn how to extend Interlock through plugins, we recommend you read the docs.
JS bundler - inspired by Git, built on Babel.
License: MIT License
For information about Interlock and how it works, check out our website. To learn how to extend Interlock through plugins, we recommend you read the docs.
package.json
Pros:
Cons:
This should be separate from the built-in Interlock.compile
method. Not clear yet what this will look like exactly.
Non-JS requires should result in either 1) transformation into JavaScript and treated like any module, or 2) output of that module with eventual bundles and alternate transformation pipeline.
loc
properties and sourcemapsPlugins should be able to register "module providers". When a request occurs for an uninstalled module (identified by hash), the default behavior is to check the URLs hash and make a request for that script.
However, if a provider is registered, that provider will be called with two arguments, the moduleHash
and the next
callback. moduleHash
is the hash string of the requested module. The next
callback should be invoked by the provider if that provider is unable to fulfill the request. This next
callback will invoke the next provider (if there is one), ultimately terminating with the default behavior (or an error, if that fails).
Providers should be invoked in order of their registration.
This should lead the way to caching mechanisms (like localStorage
and IndexedDb
) and a patch mechanism (to be implemented in interlock-patch).
uri
(ns:nsPath
) to module hashes.modulesPath
property for ingest-module resolution.require
strings containing a matching ns/nsPath
will be replaced with mapped hashes.require
strings mapped to manifest modules should not be recursively inspected.getUrls
, removing any entries where ingest module hashes are the keys, and replacing them with the same key, but the name of the corresponding ingest bundle.emitRawBundles
.Create plugin in interlock-share repo.
Blocked by #18.
package.json
Add feature similar to require.ensure
, but call it require.async
.
require(...)
calls.require.async
has no effect on splitting. That is still managed by the build config itself.require.async
(or compiled equivalent) is invoked at run-time, 1) modules are resolved and invoked, 2) callback is invoked with params matching the require
d modules.const libA = require("./lib-a");
require.async(["./lib-b", "./lib-c"], function (libB, libC) {
// ...
});
{
'aaaaaa': {
deps: [],
fn: function (require, module, exports) {
var libA = require("bbbbbb")
require.async("cccccc"/*["dddddd", "eeeeee"]*/, function (libB, libC) {
// ...
});
}
},
'bbbbbb': {
deps: [],
fn: function (require, module, exports) {
module.exports = "libA";
}
},
'cccccc': {
deps: ["dddddd", "eeeeee"],
fn: function (require, module, exports) {
module.exports = function (cb) {
cb(require("dddddd"), require("eeeeee"));
};
}
},
'dddddd': {
deps: [],
fn: function (require, module, exports) {
module.exports = "libB";
}
},
'eeeeee': {
deps: [],
fn: function (require, module, exports) {
module.exports = "libC";
}
}
}
When the require.async
is invoked within the example module, the Interlock will call the cccccc
module as if it were an entry point - first ensuring that all dependencies are installed and invoked, resolving/installing/invoking any missing dependencies, and finally calling the cccccc
module itself. This module's exports will be a function that invokes a callback, requiring and passing constituent dependencies as parameters.
The require.async
implementation will have recorded the callback passed to it, and pass that to cccccc
's returned function when available.
Haskell's QuickCheck for JavaScript jsVerify seems like it could be really well used here. In short it is a tool where you define the properties of your output rather than the value itself. Doing so allows it to test random inputs and verify their outputs which can help identify edge cases.
This tool/technique lends itself to pure functions and comes from the functional world so it may be well suited to some of the areas of this project.
Blocked by #42.
This was errantly removed, although all the underlying functionality is still there.
This is not dependent on #20. Should provide functionality comparable to:
stylus-loader
- transform Stylus files into raw CSSautoprefixr
- transform raw CSS into vendor-prefixed CSSstyle-loader
- load CSS onto page when required via new <style>
tagMay utilize joi.js or validate.js. Or no third-party dependency.
This issue is meant to track high-level objectives for Interlock v1.0. It is subject to revision as the work progresses.
fs
calls - async Pluggables onlycompile
method (#18, #38).babelrc
and .eslintrc
As modules are recursively resolved and generated, the plugin should track an esImported
value for every module that is found.
The esImported
value will be false
in either of the following conditions:
require
or AMD syntaximport foo from "./bar"
However, the esImported
value will be a truthy array if the module was only ever imported like import { subFeature } from "./bar"
or import { otherFeature } from "./bar"
. In this case, the esImported
value will be an array with string elements "subFeature"
and "otherFeature"
.
After all modules have been resolved and generated, the plugin will take another pass over each module, looking for export
nodes at the root level of the AST. For each module with a truthy esImported
value, any export
nodes that do not match an element in the esImported
array will be removed.
Lastly, sub-dependencies that are no longer needed must be detected and removed from all dependency lists. This is because the function that consumed a particular dependency may have been purged. Some investigation may be necessary to ensure that we don't just implement a minifier. If it proves to be too difficult, we should have a two-stage process - one step before a minifier is applied and one step after, at which point any removed require
s would have to be detected.
Notes:
import { foo } from "./bar"
or var foo = require("./bar").foo
. This will not work with all packages, but may help with common use-cases (like Lodash).Sanity check that changes to build process don't destroy anything when run in supported browsers.
In theory, it should be possible to add full support for webpack loaders in Interlock (see Writing a Loader).
If babelConfig
value is not supplied via config file or command-line flag, the babel config should be loaded on a per-file basis. This means that, whenever a file is about to be transformed (and possibly before parsing), we should:
.babelrc
file in the file's ancestor path,package.json
babel config, and finallyPlugin that will result in UMD bundle output. In addition to supporting AMD, CommonJS, and global variable registration, it should also register itself with an Interlock run-time if present.
As my understanding and experience with Most monadic streams has progressed, I've identified a number of characteristics of those streams that don't align well with the problem space. Unfortunately, they don't seem well suited to Interlock and add subtle complexity.
Goal: Remove most
as a dependency, and replace all previous operations with bluebird
. Promises will be the foundational primitive of Interlock async behavior.
Blocked by #28.
May involve separate utility to generate JS that will:
Implement the interlock-signed
plugin.
This plugin will ensure that bundles have not been tampered with, and allow for trusted use of third-party hosting for bundles (such as a public CDN). The general implementation will be as follows:
alert()
and set internal state such that any requests go to the next
runtime bundle providernext
runtime module provideralert()
<script>
tag with a src
value of data:text/javascript,...
[2]transform
to emitRawBundles
step
bundle.raw
values [1]filename:SHA-1
mapConstraints:
[1] http://www.movable-type.co.uk/scripts/sha1.html
[2] https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Rosetta, line 45 of code sample
New pattern for defining plugins should be:
return function (override, transform, transformInput) {
transformInput("readSource", args => {
// ...
return args;
});
};
๐
Relates to #36.
Whereas under the default HTTP/1 bundle profile, all modules are bundles into the same JS except where split points are defined, under the HTTP/2 profile, no modules will be bundled into the same JS except where split points are defined.
Where the define
function is RequireJS, the below code should result in the inner function being invoked with the modules bundled with Interlock.
define(["interlock!underscore:lib/index.js"], function (_) {
// ...
});
RequireJS config can be configured to alias certain paths with their interlock!
equivalent.
This should take the form of a plugin. See the browserify handbook for details on how transforms work.
Currently, plugin function definitions look like:
function (override, transform, control) {
// maybe do something with control.CONTINUE
};
Instead, remove control
and add pertinent symbols to the related functions. So:
function (override, transform) {
// maybe do something with override.CONTINUE
};
Instead of:
{
entry: {
"./app.js": "app.bundle.js"
},
split: {
"./lib.js": "lib.bundle.js
}
}
do instead:
{
bundles: {
"./app.js": "app.bundle.js",
"./lib.js": { dest: "lib.bundle.js", entry: false }
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.