Skip to content

Conversation

thorbenprimke
Copy link
Collaborator

Adds the option --generate-example that generate an example project and links the newly created to it.

This addresses #28.

Due to react-native init project_name not executing in a folder that already contains a package.json file, the example is generated first, then all the files are created and last the library is linked to the example.

Copy link
Owner

@frostney frostney left a comment

Choose a reason for hiding this comment

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

Amazing work 🎉
I really love this feature, I just have a few small questions.

lib.js Outdated
// Adds and links the created library project
const pathExampleApp = './' + name + '/example';
const options = { cwd: pathExampleApp, stdio:'inherit'};
execSync('yarn add file:../', options);
Copy link
Owner

Choose a reason for hiding this comment

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

Would it be possible to check first if yarn is available here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure. I guess fallback would be npm or shall it just throw an error?

I think npm you may not be able to link locally (or I could be totally wrong - maybe it was the point at a commit that didn't work with npm).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added a try/catch around yarn and added fallback support for npm.

lib.js Outdated
return;
}
// Adds and links the created library project
const pathExampleApp = './' + name + '/example';
Copy link
Owner

Choose a reason for hiding this comment

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

Nitpick: What do you think about using template literals here? (It's just a personal preference on my part.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure. Will look at updating this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated to use template literals.

dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
classpath 'com.android.tools.build:gradle:2.2.3'
Copy link
Owner

Choose a reason for hiding this comment

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

I'm a bit concerned that this change doesn't have a lot of to do with the rest of pull request. Am I missing something or could this be delivered separately?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, resolved this in #59

@thorbenprimke
Copy link
Collaborator Author

@maicki - could you give this a review? It's good to go.

lib.js Outdated
authorEmail,
license,
};
return Promise
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we don't need the Promise.resolve here, just return the createFolder

Furthermore I think in all of the early returns for the !generateExample checks we should return a Promise.reject if we consume the promise that is returned from this funciton or a Promise.resolve in case we see it as success.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, that's a good improvement. I move the createFolder out.

Copy link
Collaborator Author

@thorbenprimke thorbenprimke left a comment

Choose a reason for hiding this comment

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

I'll make these change and then merge it.

lib.js Outdated
authorEmail,
license,
};
return Promise
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, that's a good improvement. I move the createFolder out.

lib.js Outdated
.resolve()
.then(() => {
if (!generateExample) {
return
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, this should be a Promise.resolve()

lib.js Outdated
})
.then(() => {
if (!generateExample) {
return;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same here Promise.resolve()

@thorbenprimke
Copy link
Collaborator Author

Verified that both with and without generate parameter it works as expected.

@thorbenprimke thorbenprimke merged commit 2b04cfc into frostney:master Mar 18, 2018
@thorbenprimke thorbenprimke deleted the generate_example branch March 18, 2018 17:59
@pvh
Copy link

pvh commented Mar 20, 2018

This is a really great feature, but on a totally fresh install it causes Metro to get terribly confused.

I see an "Ambiguous Module Resolution Error" caused by metro picking up both the package.json in the example/package.json directory but ALSO the same package.json a second time when it's installed in node_modules/$MODULE_NAME/example!

I've worked around this by moving the example app out of the tree, but I'm not really sure what a good way to solve this would be at the tool level.

@thorbenprimke
Copy link
Collaborator Author

@pvh - Hmm. I did not run into this and we always have an example folder inside a lib project (for testing purposes and to provide usage examples of a lib).

What are the commands that you are running?

Perhaps we could make the path for the example app configurable. The reason it's inside the project is because one would ideally push both the lib and example to a single repo on github.

@maxme
Copy link

maxme commented Mar 23, 2018

This is a really great feature, but on a totally fresh install it causes Metro to get terribly confused.

I see an "Ambiguous Module Resolution Error" caused by metro picking up both the package.json in the example/package.json directory but ALSO the same package.json a second time when it's installed in node_modules/$MODULE_NAME/example!

I get the same problem, steps to reproduce the issue:

$ react-native-create-library --generate-example mytest
$ cd mytest/
$ yarn install
$ cd example
$ react-native run-android

Metro bundler fails with the error:

Loading dependency graph, done.
error: bundling failed: ambiguous resolution: module `/private/tmp/mytest/example/index.js` tries to require `react-native`, but there are several files providing this module. You can delete or fix them:

  * `/private/tmp/mytest/example/node_modules/react-native-mytest/example/node_modules/react-native/package.json`
  * `/private/tmp/mytest/example/node_modules/react-native/package.json`

@maxme
Copy link

maxme commented Mar 23, 2018

I tried to add a metro bundler configuration file to exclude the directory mytest/example/node_modules/ from the resolution map but I ran into other issues after that. I finally moved the library in its own directory and now I have something like:

.
├── example
│   ├── android
│   ├── ios
│   ├── node_modules
│   ├── App.js
│   ├── app.json
│   ├── index.js
│   └── package.json
├── library
│   ├── android
│   ├── ios
│   ├── node_modules
│   ├── windows
│   ├── RNMytest.podspec
│   ├── index.js
│   └── package.json
└── README.md

@thorbenprimke
Copy link
Collaborator Author

@maxme - thanks for the steps. I'll try to repro this later.

I see where my workflow differs. Instead of your last command react-native run-android, I would normally just do

yarn install
yarn start

which theoretically should do the same.

And I built out of AS or XCode.

@maxme
Copy link

maxme commented Mar 23, 2018

FWIW, I also tried:

react-native-create-library --generate-example mytest \
 && cd mytest/ \
 && yarn install \
 && cd example \
 && pushd android \
 && ./gradlew installDebug \
 && popd \
 && adb shell am start -n com.example/.MainActivity \
 && yarn start

And it fails with the same error.

I'm far from being an RN veteran so I'm not sure what's the best way to setup the library and example directories. Having the example directory as a library sub directory seems to be a source of issues.

@iamcxa
Copy link

iamcxa commented May 21, 2018

that's great! it will save lot's time when making a native module at the beginning. when will this merged version will be sent to npm? because now still has no this feature in npm version yet.

@maicki maicki mentioned this pull request Jun 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants