Skip to content

Commit 9b0f965

Browse files
Allow require of nativescript-cli as library (#2468)
The entry point of current cli is used only from `bin/tns`. In fact the `main` entry in package.json is used when you want to require the module, but CLI is never required. It's installed globally and spawned from it's bin dir (`bin` key in package.json defines which is the "entry" point when package is installed globally). So I've changed the entry point to a file, that does not use commandDispatcher - when requiring {N} CLI as library, we'll not execute commands. In order to allow executing specific device operations (like device detection through events), require the mobile-cli-lib's appbuilder bootstrap in the entry point. This will be fixed with other PR's and finally we'll not have to require this bootstrap.
1 parent 68679f2 commit 9b0f965

5 files changed

+37
-2
lines changed

lib/nativescript-cli-lib-bootstrap.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require("./bootstrap");
2+
3+
$injector.overrideAlreadyRequiredModule = true;
4+
5+
// Temporary!!! Should not require appbuilder's entry point of mobile-cli-lib,
6+
// but once we separate logics in mobile-cli-lib, we should be able to require only specific bootstrap.
7+
// Use this hack for now, as this will allow requiring {N} CLI as library directly and executing some device specific operations.
8+
require("./common/appbuilder/proton-bootstrap");

lib/nativescript-cli-lib.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require("./nativescript-cli-lib-bootstrap");
2+
3+
module.exports = $injector.publicApi;

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"tns": "./bin/tns",
99
"nativescript": "./bin/tns"
1010
},
11-
"main": "./lib/nativescript-cli.js",
11+
"main": "./lib/nativescript-cli-lib.js",
1212
"scripts": {
1313
"test": "node test-scripts/istanbul.js",
1414
"postinstall": "node postinstall.js",

test/nativescript-cli-lib.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { assert } from "chai";
2+
import * as fs from "fs";
3+
import * as path from "path";
4+
import * as childProcess from "child_process";
5+
const nodeArgs = require(path.join(__dirname, "..", "lib", "common", "scripts", "node-args")).getNodeArgs();
6+
7+
describe("nativescript-cli-lib", () => {
8+
it("is main entry of the package", () => {
9+
const packageJsonContent = fs.readFileSync(path.join(__dirname, "..", "package.json")).toString();
10+
const jsonContent = JSON.parse(packageJsonContent);
11+
const expectedEntryPoint = "./lib/nativescript-cli-lib.js";
12+
assert.deepEqual(jsonContent.main, expectedEntryPoint);
13+
});
14+
15+
it("resolves publicly available module - deviceEmitter, when it is required", () => {
16+
const pathToEntryPoint = path.join(__dirname, "..", "lib", "nativescript-cli-lib.js").replace(/\\/g, "\\\\");
17+
// HACK: If we try to require the entry point directly, the below code will fail as mocha requires all test files before starting the tests.
18+
// When the files are required, $injector.register adds each dependency to $injector's cache.
19+
// For example $injector.register("errors", Errors) will add the errors module with its resolver (Errors) to $injector's cache.
20+
// Calling $injector.require("errors", <path to errors file>), that's executed in our bootstrap, will fail, as the module errors is already in the cache.
21+
// In order to workaround this problem, start new process and assert there. This way all files will not be required in it and $injector.require(...) will work correctly.
22+
childProcess.execSync(`"${process.execPath}" ${nodeArgs.join(" ")} -e "var assert = require('chai').assert; var result = require('${pathToEntryPoint}'); assert.ok(result.deviceEmitter);"`);
23+
});
24+
});

0 commit comments

Comments
 (0)