RequireJsResolver.ts
100 lines
| 2.9 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r34 | import { ModuleResolverBase } from "./ModuleResolverBase"; | ||
| import { Uuid } from "../Uuid"; | ||||
| import { argumentNotEmptyString } from "../safe"; | ||||
| import { TraceSource } from "../log/TraceSource"; | ||||
|
|
r42 | type RequireFn = (modules: string[], cb?: (...args: any[]) => any) => void; | ||
|
|
r34 | |||
|
|
r42 | declare const require: RequireFn; | ||
| declare function define(name: string, modules: string[], cb?: (...args: any[]) => any, eb?: (e) => any): void; | ||||
| declare function define(modules: string[], cb?: (...args: any[]) => any, eb?: (e) => any): void; | ||||
|
|
r34 | |||
|
|
r38 | interface RequireJsResolverParams { | ||
| contextRequire: (modules: string[], cb?: (...args: any[]) => any) => void; | ||||
|
|
r34 | |||
|
|
r38 | base: string; | ||
|
|
r34 | } | ||
|
|
r42 | const trace = TraceSource.get("@implab/core/di/RequireJsResolver"); | ||
|
|
r34 | |||
| export class RequireJsResolver extends ModuleResolverBase { | ||||
|
|
r38 | _contextRequire = require; | ||
|
|
r34 | |||
|
|
r38 | _base: string; | ||
|
|
r34 | |||
|
|
r42 | constructor(opts?: RequireJsResolverParams) { | ||
|
|
r34 | super(); | ||
| if (opts) { | ||||
| if (opts.contextRequire) | ||||
| this._contextRequire = opts.contextRequire; | ||||
| if (opts.base) { | ||||
|
|
r38 | if (opts.base.indexOf("./") === 0) | ||
|
|
r34 | throw new Error(`A module id should be an absolute: '${opts.base}'`); | ||
| this._base = opts.base; | ||||
| } | ||||
| } | ||||
| } | ||||
| async createResolver(moduleName: string): Promise<ModuleResolverBase> { | ||||
| argumentNotEmptyString(moduleName, "moduleName"); | ||||
|
|
r42 | trace.log("createResolver({0})", moduleName); | ||
|
|
r38 | const parts = moduleName.split("/"); | ||
| if (parts[0] === ".") { | ||||
|
|
r34 | if (this._base) | ||
| parts[0] = this._base; | ||||
| else | ||||
| throw new Error(`Can't resolve a relative module '${moduleName}'`); | ||||
| } | ||||
|
|
r38 | if (parts.length > 1) | ||
| parts.splice(-1, 1, Uuid()); | ||||
|
|
r34 | else | ||
| parts.push(Uuid()); | ||||
|
|
r38 | const shim = parts.join("/"); | ||
|
|
r34 | |||
|
|
r42 | trace.debug(`define shim ${shim}`); | ||
|
|
r34 | |||
|
|
r42 | try { | ||
| const contextRequire = await new Promise<RequireFn>( | ||||
| (resolve, reject) => { | ||||
| try { | ||||
| define(shim, ["require"], r => { | ||||
| trace.debug("shim resolved"); | ||||
| resolve(r); | ||||
| }, reject); | ||||
| require([shim]); | ||||
| } catch (e) { | ||||
| reject(e); | ||||
| } | ||||
| } | ||||
| ); | ||||
| trace.debug("creating new moduleResolver"); | ||||
| return new RequireJsResolver({ | ||||
| base: parts.slice(0, -1).join("/"), | ||||
| contextRequire | ||||
| }); | ||||
| } catch (e) { | ||||
| trace.error(e); | ||||
| throw e; | ||||
| } | ||||
|
|
r34 | } | ||
|
|
r38 | async loadModule(moduleName: string): Promise<object> { | ||
|
|
r42 | trace.log(`loadModule(${moduleName})`); | ||
|
|
r38 | return new Promise<object>( | ||
| resolve => this._contextRequire.call(null, [moduleName], resolve) | ||||
|
|
r34 | ); | ||
| } | ||||
|
|
r38 | } | ||
