Skip to content

Commit 255feda

Browse files
Add a globals.registerWebpackModules that can register dynamic require webpack context (NativeScript#5087)
1 parent 71c50b2 commit 255feda

File tree

5 files changed

+50
-2
lines changed

5 files changed

+50
-2
lines changed

tns-core-modules/globals/globals.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,31 @@ global.registerModule = function(name: string, loader: ModuleLoader): void {
3434
modules.set(name, loader);
3535
}
3636

37+
interface Context {
38+
keys(): string[];
39+
(key: string): any;
40+
}
41+
interface ExtensionMap {
42+
[originalFileExtension: string]: string;
43+
}
44+
45+
const defaultExtensionMap = { ".js": ".js", ".ts": ".js", ".css": ".css", ".scss": ".css", ".xml": ".xml" };
46+
global.registerWebpackModules = function registerWebpackModules(context: Context, extensionMap: ExtensionMap = {}) {
47+
context.keys().forEach(key => {
48+
const extDotIndex = key.lastIndexOf(".");
49+
const base = key.substr(0, extDotIndex);
50+
const originalExt = key.substr(extDotIndex);
51+
const registerExt = extensionMap[originalExt] || defaultExtensionMap[originalExt];
52+
const registerName = base + registerExt;
53+
if (registerName.startsWith("./") && registerName.endsWith(".js")) {
54+
const jsNickName = registerName.substr(2, registerName.length - 5);
55+
// This is extremely short version like "main-page" that was promoted to be used with global.registerModule("module-name", loaderFunc);
56+
global.registerModule(jsNickName, () => context(key));
57+
}
58+
global.registerModule(registerName, () => context(key));
59+
});
60+
}
61+
3762
global.moduleExists = function(name: string): boolean {
3863
return modules.has(name);
3964
}

tns-core-modules/module.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ declare namespace NodeJS {
1414
android?: any;
1515
require(id: string): any;
1616
registerModule(name: string, loader: ((name: string) => any)): void;
17+
/**
18+
* Register all modules from a webpack context.
19+
* The context is one created using the following webpack utility:
20+
* https://webpack.github.io/docs/context.html
21+
*
22+
* The extension map is optional, modules in the webpack context will have their original file extension (e.g. may be ".ts" or ".scss" etc.),
23+
* while the built-in module builders in {N} will look for ".js", ".css" or ".xml" files. Adding a map such as:
24+
* ```
25+
* { ".ts": ".js" }
26+
* ```
27+
* Will resolve lookups for .js to the .ts file.
28+
* By default scss, and ts files are mapped.
29+
*/
30+
registerWebpackModules(context: { keys(): string[], (key: string): any }, extensionMap?: { [originalFileExtension: string]: string });
1731
/**
1832
* The NativeScript XML builder, style-scope, application modules use various resources such as:
1933
* app.css, page.xml files and modules during the application life-cycle.

tns-core-modules/ui/builder/builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@ function loadCustomComponent(componentPath: string, componentName?: string, attr
8282

8383
if (xmlFilePath) {
8484
// Custom components with XML
85-
var jsFilePath = resolveFileName(fullComponentPathFilePathWithoutExt, "js");
8685

8786
var subExports = context;
8887
if (global.moduleExists(moduleName)) {
8988
// Component has registered code module.
9089
subExports = global.loadModule(moduleName);
9190
} else {
91+
var jsFilePath = resolveFileName(fullComponentPathFilePathWithoutExt, "js");
9292
if (jsFilePath) {
9393
// Component has code file.
9494
subExports = global.loadModule(jsFilePath)

tns-core-modules/ui/builder/component-builder/component-builder.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { profile } from "../../../profiling";
1111
import * as debugModule from "../../../utils/debug";
1212
import * as platform from "../../../platform";
1313

14+
import * as filesystem from "../../../file-system";
15+
1416
const UI_PATH = "ui/";
1517
const MODULES = {
1618
"TabViewItem": "ui/tab-view",
@@ -119,6 +121,13 @@ const applyComponentCss = profile("applyComponentCss", (instance: View, moduleNa
119121

120122
if (typeof (<any>instance).addCssFile === "function") {//instance instanceof Page) {
121123
if (moduleNamePath && !cssApplied) {
124+
125+
const appPath = filesystem.knownFolders.currentApp().path;
126+
const cssPathRelativeToApp = (moduleNamePath.startsWith(appPath) ? "./" + moduleNamePath.substr(appPath.length + 1) : moduleNamePath) + ".css";
127+
if (global.moduleExists(cssPathRelativeToApp)) {
128+
(<any>instance).addCssFile(cssPathRelativeToApp);
129+
}
130+
122131
let cssFilePath = resolveFileName(moduleNamePath, "css");
123132
if (cssFilePath) {
124133
(<any>instance).addCssFile(cssFilePath);

tns-core-modules/ui/styling/style-scope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ export class StyleScope {
508508
}
509509

510510
this._reset();
511-
let parsedCssSelectors = cssString ? CSSSource.fromSource(cssString, this._keyframes, cssFileName) : CSSSource.fromFile(cssFileName, this._keyframes);
511+
let parsedCssSelectors = cssString ? CSSSource.fromSource(cssString, this._keyframes, cssFileName) : CSSSource.fromURI(cssFileName, this._keyframes);
512512
this._css = this._css + parsedCssSelectors.source;
513513
this._localCssSelectors.push.apply(this._localCssSelectors, parsedCssSelectors.selectors);
514514
this._localCssSelectorVersion++;

0 commit comments

Comments
 (0)