Skip to content

Allow starting packager in a sub folder#359

Merged
MSLaguana merged 3 commits into
microsoft:masterfrom
alsorokin:packager-subfolder
Dec 7, 2016
Merged

Allow starting packager in a sub folder#359
MSLaguana merged 3 commits into
microsoft:masterfrom
alsorokin:packager-subfolder

Conversation

@alsorokin

Copy link
Copy Markdown
Contributor

close #312

These changes allow user to specify any folder as a react-native project root in settings.json.

@msftclas

msftclas commented Dec 1, 2016

Copy link
Copy Markdown

Hi @alsorokin, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!


It looks like you're a Microsoft contributor (Alexander Sorokin (Akvelon)). If you're full-time, we DON'T require a Contribution License Agreement. If you are a vendor, please DO sign the electronic Contribution License Agreement. It will take 2 minutes and there's no faxing! https://cla.microsoft.com.

TTYL, MSBOT;

Comment thread README.md Outdated
```
{
"react-native-tools": {
"projectRoot": "your-react-native-project"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a path, relative to workspace's root, right? Could you please make it more clear?

Comment thread src/debugger/nodeDebugWrapper.ts Outdated
let settingsPath = path.resolve(vsCodeRoot, ".vscode/settings.json");
let settingsContent = fs.readFileSync(settingsPath, "utf8");
// strip the json off of comments
settingsContent = settingsContent.replace(/\/\/.*\n/g, "");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to use strip-json-comments to make it parseable

Comment thread src/debugger/nodeDebugWrapper.ts Outdated
settingsContent = settingsContent.replace(/\/\/.*\n/g, "");
let parsedSettings = JSON.parse(settingsContent);
let projectRootPath = parsedSettings["react-native-tools"].projectRoot;
if (path.isAbsolute(projectRootPath)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to check if path is absolute - path.resolve(vsCodeRoot, projectRootPath) would yield back projectRootPath if it's absolute, despite of what is in vsCodeRoot

Comment thread src/debugger/nodeDebugWrapper.ts Outdated
*/
private requestSetup(debugSession: NodeDebugSession, args: any) {
this.projectRootPath = path.resolve(args.program, "../..");
this.setProjectRoot(args);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If the only purpose of setProjectRoot is to set this.projectRootPath, IMO it'd be more transparent and readable to make a function that would return projectRootPath, and use it's result.

Comment thread src/common/exponent/exponentHelper.ts Outdated
import * as path from "path";
import * as Q from "q";
import * as XDL from "./xdlInterface";
import * as vscode from "vscode";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't refer to the vscode package from this file as-is: Sources under src/common can be referenced both from within the vscode extension process and within the external debug adapter process, and the debug adapter process cannot access vscode.

Comment thread src/common/packager.ts Outdated
import * as path from "path";
import * as XDL from "../common/exponent/xdlInterface";
import * as url from "url";
import * as vscode from "vscode";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, we can't directly refer to vscode in here since it is also accessed from within the separate debug adapter process.

Comment thread src/common/reactNativeProjectHelper.ts Outdated
* {operation} - a function that performs the expected operation
*/
public isReactNativeProject(): Q.Promise<boolean> {
if (!fs.existsSync(path.join(this.workspaceRoot, "package.json"))) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right condition? I believe that running react-native foo requires you to be in the folder with the node_modules/react-native folder inside it, so if your folder structure looks something like

root
root/project/package.json
root/project/node_modules/react-native
root/site/<other content>

then workspaceRoot will point to root, but the react-native project is located at root/project and that's where the package.json must be, and where we should start react-native from.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workspaceRoot variable actually is pointing at project root. I'll rename it. Thanks for noticing this inconsistency!

private getProjectRoot(args: any): string {
try {
let vsCodeRoot = path.resolve(args.program, "../..");
let settingsPath = path.resolve(vsCodeRoot, ".vscode/settings.json");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't be the default location where vscode stores workspace settings: If you have the workspace open in root and the project in root/project, then this path I think would be rooot/project/.vscode/settings.json, while opening up the local workspace settings would open up root/.vscode/settings.json. Unless I'm misinterpreting where you intend to place the entry point that we run?

@alsorokin alsorokin Dec 6, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well yes, I guess the entry point is still in root/.vscode/
If that is not the right place for it to be and we put it to root/project/.vscode, then the user would need to manually edit program arg in launch.json.
Currently it looks like this:

{
<...>
    "configurations": [
        {
            ...
            "program": "${workspaceRoot}/.vscode/launchReactNative.js",
            ...
        }]
<...>
}

And as far as I know we can't really use any other variable other than $workspaceRoot here so we don't have any convenient way to point to project root.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I forgot that we have to specify the path in launch.json. Looking at https://code.visualstudio.com/docs/editor/tasks#_variable-substitution it seems that the variables which can be substituted are limited, but it does include environment variables, so we could do something a bit hacky and have the extension set a VSCODE_REACT_NATIVE_PROJECT_ROOT environment variable and reference that, but I don't like that idea much.

Although, looking at the vscode codebase I do see a test with https://github.com/Microsoft/vscode/blob/ea26b957f6c593410724cd341e1db2c7c37170b8/src/vs/workbench/services/configurationResolver/test/node/configurationResolverService.test.ts#L117 which might suggest that we could reference ${config['react-native-tools'].projectRoot} or something and it might work out?

If not, I think the current approach is ok

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried it and it doesn't seem to work 😞

Comment thread src/common/exponent/exponentHelper.ts Outdated
AppRegistry.runApplication('${componentName}', appParameters);
});`;
return this.fileSystem.writeFile(this.dotvscodePath(EXPONENT_INDEX), fileContents);
return this.fileSystem.writeFile(this.pathToFileInWorkspace(EXPONENT_INDEX), fileContents);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that we want to put this file in with the user's sources rather than in the .vscode folder; it's not really part of the end-user's app, it's just an implementation detail of us converting to an exponent app.

Comment thread src/common/packager.ts
}
if (runAs === PackagerRunAs.EXPONENT) {
args = args.concat(["--root", ".vscode"]);
args = args.concat(["--root", path.relative(this.projectPath, path.resolve(this.workspacePath, ".vscode"))]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This path needs to point to wherever the exponentIndex.js file is I believe, otherwise the exponent packager won't find the entry point (or the rest of the app)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the exponentIndex.js file back to root/.vscode folder as you suggested, so this path should be correct.
I've tested it with Exponent and it works.
See f6b41bb

@MSLaguana MSLaguana merged commit 23c027b into microsoft:master Dec 7, 2016
@MSLaguana

Copy link
Copy Markdown
Member

Thanks @alsorokin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow starting packager in a sub folder

4 participants