From 648e4d216d9bb3a0ca1fd20c84fe48ed9dafc7d3 Mon Sep 17 00:00:00 2001 From: Hristo Deshev Date: Mon, 14 Dec 2015 14:41:16 +0200 Subject: [PATCH] Add utils/module-loader - a mechanism to resolve modules at runtime. Exposes a module registration API, that webpack users can use to bundle "dynamic" modules that are required through some variable. Falls back to the require API if no module is registered. Reworked dynamic `require` code to use module-loader: - navigation: ui/frame. - XML UI build ui/builder/builder and ui/builder/component-builder. - module on-demand loads in global functions: globals. --- globals/globals.ts | 27 ++- ui/builder/builder.ts | 281 ++++++++++++++++---------------- ui/builder/component-builder.ts | 74 ++++----- ui/frame/frame-common.ts | 91 ++++++----- 4 files changed, 250 insertions(+), 223 deletions(-) diff --git a/globals/globals.ts b/globals/globals.ts index c6006f3e6..0af8f290a 100644 --- a/globals/globals.ts +++ b/globals/globals.ts @@ -6,11 +6,36 @@ global.moduleMerge = function (sourceExports: any, destExports: any) { } } +type ModuleLoader = () => any; +const modules: Map = new Map(); + +global.registerModule = function(name: string, loader: ModuleLoader): void { + modules.set(name, loader); +} + +global.moduleExists = function(name: string): boolean { + return modules.has(name); +} + +global.loadModule = function(name: string): any { + const loader = modules.get(name); + if (loader) { + return loader(); + } else { + return require(name); + } +} + +global.registerModule("timer", () => require("timer")); +global.registerModule("ui/dialogs", () => require("ui/dialogs")); +global.registerModule("../xhr/xhr", () => require("../xhr/xhr")); +global.registerModule("fetch", () => require("fetch")); + function registerOnGlobalContext(name, module) { Object.defineProperty(global, name, { get: function () { // We do not need to cache require() call since it is already cached in the runtime. - let m = require(module); + let m = global.loadModule(module); global.moduleMerge(m, global); // Redefine the property to make sure the above code is executed only once. diff --git a/ui/builder/builder.ts b/ui/builder/builder.ts index 9c0dec3be..573ec2d20 100644 --- a/ui/builder/builder.ts +++ b/ui/builder/builder.ts @@ -1,43 +1,41 @@ -import view = require("ui/core/view"); -import fs = require("file-system"); -import xml = require("xml"); -import types = require("utils/types"); -import componentBuilder = require("ui/builder/component-builder"); -import platform = require("platform"); -import definition = require("ui/builder"); -import page = require("ui/page"); -import fileResolverModule = require("file-system/file-name-resolver"); -import trace = require("trace"); -import debug = require("utils/debug"); -import builder = require("ui/builder"); +import * as trace from "trace"; +import {debug, ScopeError, SourceError, Source} from "utils/debug"; +import * as xml from "xml"; +import {View, Template} from "ui/core/view"; +import {File, path, knownFolders} from "file-system"; +import {isString, isFunction, isDefined} from "utils/types"; +import {ComponentModule, setPropertyValue, getComponentModule} from "ui/builder/component-builder"; +import {platformNames, device} from "platform"; +import {LoadOptions} from "ui/builder"; +import {Page} from "ui/page"; +import {resolveFileName} from "file-system/file-name-resolver"; -export function parse(value: string | view.Template, context: any): view.View { - if (types.isString(value)) { - var viewToReturn: view.View; - - if (context instanceof view.View) { +export function parse(value: string | Template, context: any): View { + if (isString(value)) { + var viewToReturn: View; + + if (context instanceof View) { context = getExports(context); } - + var componentModule = parseInternal(value, context); - + if (componentModule) { viewToReturn = componentModule.component; } - + return viewToReturn; - } else if (types.isFunction(value)) { - return (value)(); + } else if (isFunction(value)) { + return (