Expo support upgrade#478
Conversation
|
@itoys, |
4c58811 to
4f7b30b
Compare
| const reactCommand = HostPlatform.getNpmCliCommand(CommandExecutor.ReactNativeCommand); | ||
| return this.spawnChildProcess(reactCommand, this.combineArguments(command, args), options); | ||
| const reactCommand = CommandExecutor.ReactNativeCLI; | ||
| return this.spawnChildProcess("node", [reactCommand, command, ...args], options); |
There was a problem hiding this comment.
@itoys is it really required to spawn cli.js directly rather than via react-native-cli?
There was a problem hiding this comment.
That's exactly like exp run builder
There was a problem hiding this comment.
Packager, you meant. Anyway, this call is effectively has the same result as this.spawnChildProcess(reactCommand, this.combineArguments(command, args), options) so I wonder if the change was really required.
| return Q.reject<void>(ErrorHelper.getNestedError(reason, InternalErrorCode.CommandFailed, command)); | ||
| } | ||
|
|
||
| private combineArguments(firstArgument: string, otherArguments: string[] = []) { |
| return this.monkeyPatchOpnForRNPackager() | ||
| .then(() => { | ||
| let args = ["--port", port.toString()]; | ||
| let args: any = ["--port", port.toString()]; |
There was a problem hiding this comment.
It shouldn't contain anything other than strings - semantically args is an array of parameters passed to the packages and commandline parameters are always strings.
The line that you pointing me to (args.push("--assetExts", ["ttf"])) is also very confusing and probably would look better if rewritten to args.push("--assetExts", ["ttf"].toString())
Another argument is that I perfectly remember that you've had a lot of troubles you could avoid if array value was converted to string explicitly
There was a problem hiding this comment.
child_process.spawn is flatted nested arrays, we can get array from app.json or exp.json
Otherwise we should check typeof value and join it (Array.prototype.join)
|
|
||
| declare class ExpConfig { | ||
| public name: string; | ||
| public slug: string; |
There was a problem hiding this comment.
Are name and slug required? IIRC CRNA app doesn't have them defined in package.json
| let commandExecutor = new CommandExecutor(); | ||
| xdlPackage = commandExecutor.spawnWithProgress(HostPlatform.getNpmCliCommand("npm"), | ||
| ["install", `xdl@${XDL_VERSION}`, "--verbose"], | ||
| ["install", EXPO_DEPS.join(", "), "--verbose"], |
There was a problem hiding this comment.
Please don't use , to join CLI arguments. The common practice is to delimit using just space
| }) | ||
| args.push("--root", path.resolve(this.projectPath + "/.vscode/")); | ||
|
|
||
| let helper = new ExponentHelper(this.projectPath); |
There was a problem hiding this comment.
For these two lines please see my comment to rn-extension.ts and #359
| */ | ||
| private pathToFileInWorkspace(filename: string): string { | ||
| return path.join(this.projectRootPath, filename); | ||
| return path.join(this.projectRootPath, filename).replace(DBL_SLASHES, "/"); |
There was a problem hiding this comment.
Please don't use string replace to normalize paths. Use path.posix.join instead
There was a problem hiding this comment.
replace is faster than split + path.posix.join, and with leading slash
There was a problem hiding this comment.
Ok, It appears that path.join would not correct path separators.
| // Not in a react-native project | ||
| return false; | ||
| }); | ||
| private getFromExpConfig<T>(key: string): Q.Promise<T> { |
There was a problem hiding this comment.
I'm curious why is it really required to use generics? Semantically I'd rather return any and then cast result to expected type
| private detectEntry(): Q.Promise<string> { | ||
| this.lazilyInitialize(); | ||
| return Q.all([ | ||
| this.fs.exists(this.pathToFileInWorkspace(DEFAULT_EXPONENT_INDEX)), |
There was a problem hiding this comment.
Instead of checking some predefined "magic" locations you might want to look at "main" entry in package.json. I ddn't find any documentation but from my experience it always points to the main entry point. Also note the case when for example "main" points to non-existent file - in that case you'll need to check for ios and adroid variants of that file, i.e.
index.js (doesn't exist) -> index.ios.js / index.android.js
There was a problem hiding this comment.
It's just a bit refactoring for legacy code. And we discussed about that.
| const expJsonPath = this.pathToFileInWorkspace(EXP_JSON); | ||
| if (!this.fileSystem.existsSync(expJsonPath) || exponentJson.overwriteExpJson) { | ||
| private patchAppJson(isExpo: boolean = true): Q.Promise<void> { | ||
| return this.readAppJson() |
There was a problem hiding this comment.
I can't find .catch for this. What happens if neither app.json nor exp.json exists
There was a problem hiding this comment.
It's incorrect app, and we'll crash, i think it's ok
There was a problem hiding this comment.
I can see at least one code path where the exception here will not be caught by caller code which likely would lead to extension crash - this is a bad UX and must be avoided if possible.
Have you tested this scenario?
#427