first working version

This commit is contained in:
Philipp Kunz 2016-10-12 14:01:15 +02:00
parent 7e65012621
commit f97c97f41a
11 changed files with 71 additions and 18 deletions

View File

@ -21,17 +21,24 @@ simplifies lazy loading with TypeScript
We recommend the use of TypeScript for best Intellisense We recommend the use of TypeScript for best Intellisense
```typescript ```typescript
import {LazyModule, loadNow } from 'smartsystem' import { LazyModule } from 'smartsystem'
import * as myPluginType from 'myPlugin' // plugin does not get loaded here at runtime import * as myPluginType from 'myPlugin' // plugin does not get loaded here at runtime
let myPluginPromised = LazyModule<typeof myPlugin>('myPlugin') let myPluginLazy = new LazyModule<typeof myPlugin>('myPlugin')
import * as anotherPluginType from 'anotherPlugin' // plugin does not get loaded here at runtime import * as anotherPluginType from 'anotherPlugin' // plugin does not get loaded here at runtime
let anotherPluginPromised = LazyModule<typeof anotherPlugin>('anotherPlugin') let anotherPluginPromised = LazyModule<typeof anotherPlugin>('anotherPlugin')
myPluginPromised.then(myPlugin => { /* do something with myPlugin */ }) myPluginLazy.whenLoaded.then(myPlugin => {
myPlugin.also(anotherPluginPromised).then((m,a) => {}) // also takes multiple other plugins /* do something with myPlugin.
myPlugin receives the typings flow from LazyModule class
This does NOT load the module during runtime
The promise whenLoaded will be resolved whenever load() is called for the first time */
})
loadNow.only('myPlugin') // loads myPlugin and resolved the lazy promise myPluginLazy.load().then(myPlugin => {
loadNow.also('myPlugin') // loads myPlugin and any chained 'also' modules /* do something with myPlugin.
myPlugin receives the typings flow from LazyModule class
This DOES LOAD the module */
})
``` ```

3
dist/index.d.ts vendored
View File

@ -5,7 +5,10 @@ import * as q from 'q';
*/ */
export declare class LazyModule<T> { export declare class LazyModule<T> {
name: string; name: string;
nameIsPath: boolean;
cwd: string; cwd: string;
whenLoaded: q.Promise<T>;
private whenLoadedDeferred;
constructor(nameArg: string, cwdArg?: string); constructor(nameArg: string, cwdArg?: string);
/** /**
* loads the module * loads the module

10
dist/index.js vendored
View File

@ -22,7 +22,10 @@ class LazyModule {
constructor(nameArg, cwdArg = process.cwd()) { constructor(nameArg, cwdArg = process.cwd()) {
this.name = nameArg; this.name = nameArg;
this.cwd = cwdArg; this.cwd = cwdArg;
smartsystem.addLazyModule(this); smartsystem.addLazyModule(this); // add module to smartsystem instance
this.nameIsPath = /\.\//.test(this.name); // figure out if name is path
this.whenLoadedDeferred = q.defer();
this.whenLoaded = this.whenLoadedDeferred.promise;
} }
/** /**
* loads the module * loads the module
@ -32,8 +35,9 @@ class LazyModule {
let loadedModule; let loadedModule;
systemjs.import(this.name).then((m) => { systemjs.import(this.name).then((m) => {
loadedModule = m; loadedModule = m;
this.whenLoadedDeferred.resolve(loadedModule);
done.resolve(loadedModule); done.resolve(loadedModule);
}); }).catch(err => { console.log(err); });
return done.promise; return done.promise;
} }
/** /**
@ -43,4 +47,4 @@ class LazyModule {
} }
} }
exports.LazyModule = LazyModule; exports.LazyModule = LazyModule;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBRUEsdUJBQXNCO0FBQ3RCLDZCQUErQjtBQUMvQixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFFbEM7SUFBQTtRQUNJLGdCQUFXLEdBQUcsSUFBSSxlQUFTLEVBQWMsQ0FBQTtJQVU3QyxDQUFDO0lBUkc7O09BRUc7SUFDSCxhQUFhLENBQUMsYUFBeUI7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDdkMsQ0FBQztDQUdKO0FBRUQsa0NBQWtDO0FBQ2xDLElBQUksV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUE7QUFFbkM7O0dBRUc7QUFDSDtJQUdJLFlBQVksT0FBZSxFQUFFLE1BQU0sR0FBVyxPQUFPLENBQUMsR0FBRyxFQUFFO1FBQ3ZELElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFBO1FBQ25CLElBQUksQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFBO1FBQ2pCLFdBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSTtRQUNBLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUssQ0FBQTtRQUN2QixJQUFJLFlBQWUsQ0FBQTtRQUNuQixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzlCLFlBQVksR0FBRyxDQUFDLENBQUE7WUFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUM5QixDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVEsQ0FBQyxHQUFHLElBQXVCO0lBRW5DLENBQUM7Q0FDSjtBQTVCRCxnQ0E0QkMifQ== //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBRUEsdUJBQXNCO0FBQ3RCLDZCQUErQjtBQUMvQixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFFbEM7SUFBQTtRQUNJLGdCQUFXLEdBQUcsSUFBSSxlQUFTLEVBQW1CLENBQUE7SUFRbEQsQ0FBQztJQU5HOztPQUVHO0lBQ0gsYUFBYSxDQUFDLGFBQThCO1FBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3ZDLENBQUM7Q0FDSjtBQUVELGtDQUFrQztBQUNsQyxJQUFJLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBRW5DOztHQUVHO0FBQ0g7SUFNSSxZQUFZLE9BQWUsRUFBRSxNQUFNLEdBQVcsT0FBTyxDQUFDLEdBQUcsRUFBRTtRQUN2RCxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQTtRQUNuQixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQTtRQUNqQixXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFBLENBQUMscUNBQXFDO1FBQ3JFLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUEsQ0FBQyw2QkFBNkI7UUFDdEUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUssQ0FBQTtRQUN0QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUE7SUFDckQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSTtRQUNBLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUssQ0FBQTtRQUN2QixJQUFJLFlBQWUsQ0FBQTtRQUNuQixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzlCLFlBQVksR0FBRyxDQUFDLENBQUE7WUFDaEIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtZQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQzlCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3JDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVEsQ0FBQyxHQUFHLElBQXVCO0lBRW5DLENBQUM7Q0FDSjtBQW5DRCxnQ0FtQ0MifQ==

View File

@ -25,6 +25,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/should": "^8.1.30", "@types/should": "^8.1.30",
"should": "^11.1.1" "should": "^11.1.1",
"typings-test": "^1.0.3"
} }
} }

1
test/moduleExample.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export declare let exportedTestBoolean: boolean;

4
test/moduleExample.js Normal file
View File

@ -0,0 +1,4 @@
"use strict";
exports.exportedTestBoolean = true;
console.log('moduleExample loaded successfully');
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlRXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1vZHVsZUV4YW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFXLFFBQUEsbUJBQW1CLEdBQUcsSUFBSSxDQUFBO0FBQ3JDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLENBQUMsQ0FBQSJ9

2
test/moduleExample.ts Normal file
View File

@ -0,0 +1,2 @@
export let exportedTestBoolean = true
console.log('moduleExample loaded successfully')

1
test/test.d.ts vendored
View File

@ -0,0 +1 @@
import 'typings-test';

View File

@ -1,2 +1,13 @@
"use strict"; "use strict";
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9 require("typings-test");
const smartsystem = require("../dist/index");
describe('smartsystem', function () {
it('should load a module lazily', function (done) {
let lazyModuleExample = new smartsystem.LazyModule('./test/moduleExample.js');
lazyModuleExample.load().then(m => {
console.log(m.exportedTestBoolean);
done();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUVyQiw2Q0FBNEM7QUFJNUMsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUNwQixFQUFFLENBQUMsNkJBQTZCLEVBQUUsVUFBVSxJQUFJO1FBQzVDLElBQUksaUJBQWlCLEdBQUcsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUF3Qix5QkFBeUIsQ0FBQyxDQUFBO1FBRXBHLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUE7WUFDbEMsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ==

View File

@ -1,2 +1,16 @@
import 'typings-test'
import * as should from 'should' import * as should from 'should'
import * as smartsystem from '../dist/index' import * as smartsystem from '../dist/index'
import * as _moduleExample from './moduleExample'
describe('smartsystem', function () {
it('should load a module lazily', function (done) {
let lazyModuleExample = new smartsystem.LazyModule<typeof _moduleExample>('./test/moduleExample.js')
lazyModuleExample.load().then(m => {
console.log(m.exportedTestBoolean)
done()
})
})
})

View File

@ -5,16 +5,14 @@ import { Objectmap } from 'lik'
let systemjs = require('systemjs') let systemjs = require('systemjs')
class Smartsystem { class Smartsystem {
lazyModules = new Objectmap<LazyModule>() lazyModules = new Objectmap<LazyModule<any>>()
/** /**
* add lazyModule to Smartsystem * add lazyModule to Smartsystem
*/ */
addLazyModule(lazyModuleArg: LazyModule) { addLazyModule(lazyModuleArg: LazyModule<any>) {
this.lazyModules.add(lazyModuleArg) this.lazyModules.add(lazyModuleArg)
} }
loadLazyModule(lazyModuleArg: LazyModule)
} }
// create the internal smartsystem // create the internal smartsystem
@ -25,11 +23,17 @@ let smartsystem = new Smartsystem()
*/ */
export class LazyModule<T> { export class LazyModule<T> {
name: string name: string
nameIsPath: boolean
cwd: string cwd: string
constructor(nameArg: string, cwdArg: string = process.cwd()){ whenLoaded: q.Promise<T>
private whenLoadedDeferred: q.Deferred<T>
constructor(nameArg: string, cwdArg: string = process.cwd()) {
this.name = nameArg this.name = nameArg
this.cwd = cwdArg this.cwd = cwdArg
smartsystem.addLazyModule(this) smartsystem.addLazyModule(this) // add module to smartsystem instance
this.nameIsPath = /\.\//.test(this.name) // figure out if name is path
this.whenLoadedDeferred = q.defer<T>()
this.whenLoaded = this.whenLoadedDeferred.promise
} }
/** /**
@ -40,8 +44,9 @@ export class LazyModule<T> {
let loadedModule: T let loadedModule: T
systemjs.import(this.name).then((m) => { systemjs.import(this.name).then((m) => {
loadedModule = m loadedModule = m
this.whenLoadedDeferred.resolve(loadedModule)
done.resolve(loadedModule) done.resolve(loadedModule)
}) }).catch(err => { console.log(err) })
return done.promise return done.promise
} }