Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with webpack #395

Closed
roman01la opened this issue Mar 28, 2015 · 26 comments
Closed

Integration with webpack #395

roman01la opened this issue Mar 28, 2015 · 26 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@roman01la
Copy link

The most painless way I've found is to tell webpack to ignore native modules using externals config, like this. It seems good enough, but you need to keep a list of native components up-to-date and run webpack as separate process.

The simplest solution is to let React Native expose a list of names of all native components, including user-defined. So it can be then used in webpack config like this:

externals: require('react-native').getComponents()

Also I can think of a webpack loader which is a thin wrapper around packager. It should be declared as the last loader in loaders pipeline (e.g. loaders: [ 'react-native-loader', 'babel-loader' ]). In this case packager should only do packaging and webpack-dev-server will be responsible of serving bundled output, thus it should be easier to integrate React Hot Loader, which is really cool!

Any thoughts?

@gaearon
Copy link
Collaborator

gaearon commented Mar 28, 2015

Related: #5

@pilwon
Copy link
Contributor

pilwon commented Mar 28, 2015

@roman01la You can dynamically build a react-native component list with this webpack config file.

I like your approach more than what I've tried here and there.

@roman01la
Copy link
Author

@pilwon Thanks for this gist! I've found that calling ReactPackager.getDependencies directly does some unnecessary stuff from the inside.

There's DependencyGraph module, which does exactly what I need. I've created a separate branch, check this code. I believe it also can handle user-defined native modules as long as you pass a path to dir with your native modules into DependencyGraph config.

@pilwon
Copy link
Contributor

pilwon commented Mar 29, 2015

@roman01la I tried to use the DependencyGraph as well but ended up going with ReactPackager's top-level API as it'd be easier to maintain with future releases. The react-native team may change the internal file structure & API. I'm wondering though, does calling DependencyGraph directly make it faster? There's always several seconds of delay every time you run ReactPackager.getDependencies so I was hoping to find a better solution that speeds it up.

@roman01la
Copy link
Author

One more thing. In order to be able to pick up new native modules while webpack is running, you need to load DependencyGraph on every change detected by webpack. DependencyGraph takes around 10 seconds to load everything, so this is not as good as it sounds. However this can be optimized: if you keep your native components inside of another dir, the directory can be just ignored by webpack.

@roman01la
Copy link
Author

@pilwon Nope, DependencyGraph itself is slow, because of IO stuff, but everything wrapped around is ok.

For me it looks like the whole React Native is nicely divided into separate modules, so probably some of them will go standalone to npm, Packager for example, but I'm not sure about DependencyGraph. Anyway it literally does just scan for modules, so it should not be hard to implement a standalone solution.

@pilwon
Copy link
Contributor

pilwon commented Mar 29, 2015

@roman01la Thanks. There's a plan to publish packager as a standalone NPM package: #363

@glenjamin
Copy link

Is packager intended to live on?
Will it just grow to support the features of browserify/webpack?
Will it still be faster once it does?

Personally I'd rather see packager shrink to be the bare minimum required to load a JS file into native, and then the existing features could be spun out separately and be replaceable by other existing bundling solutions.

At the moment it's not entirely clear to me what is in scope / not in scope for packager - I can't even figure out how you're getting Xcode to launch it on build! 😕

@amasad
Copy link
Contributor

amasad commented Mar 29, 2015

Is packager intended to live on?

If we can use webpack we will. For our codebase webpack is 10 times slower for us. 8 seconds per file change is a no go. I suggested to the maintainers here what could be done to make perform better #5

Will it just grow to support the features of browserify/webpack?

Ideally, we'll get to a point where you can use your tools and infrastructure regardless of what we use for core.

Will it still be faster once it does?

I assure it's a lot faster than webpack/browserify combined for bundling and sourcemaps. The only slow part if the initial file crawl. Which we have to do -- and they don't -- because our module format isn't tied to the file system.

Personally I'd rather see packager shrink to be the bare minimum required to load a JS file into native, and then the existing features could be spun out separately and be replaceable by other existing bundling solutions.

This is the plan :)

At the moment it's not entirely clear to me what is in scope / not in scope for packager - I can't even figure out how you're getting Xcode to launch it on build! 😕

The readme is a great place to start https://github.com/facebook/react-native/blob/master/packager/README.md

@pilwon
Copy link
Contributor

pilwon commented Mar 29, 2015

@glenjamin Xcode has a build phase shell script command that launches packager if there's no server listening port 8081.

nc -w 5 -z localhost 8081 > /dev/null 2>&1 || open $SRCROOT/../packager/launchPackager.command || echo \"Can't start packager automatically\"

@glenjamin
Copy link

@amasad awesome answers - thanks!

The faster question was whether it'd still be fast if it had all other features, but if that's a non-goal the question is irrelevant :)

@glenjamin
Copy link

@pilwon - the bit I strugged to find was where they script is initiated from, probably just unfamiliarity with Xcode on my part

@pilwon
Copy link
Contributor

pilwon commented Mar 30, 2015

@amasad Is MessageQueue module used to bridge Obj-C to JS? It uses dynamic require that causes an issue when trying to build everything with webpack. Webpack supports dynamic require feature with context module but I believe the request string needs to start with ./. I tried hacking this behavior with ContextReplacementPlugin as well as my custom plugin but I had no luck. Can MessageQueue avoid the use of dynamic require so all requires are static?

@vjeux
Copy link
Contributor

vjeux commented Mar 30, 2015

Can MessageQueue avoid the use of dynamic require so all requires are static?

Yeah we want to do that, but haven't had the time to figure out a better way to do it so far. Suggestions are welcome

@pilwon
Copy link
Contributor

pilwon commented Mar 30, 2015

@vjeux Supporting UMD would make it trivial to integrate react-native with other existing bundlers & their ecosystems. It should be possible to support both UMD and react-pacakger module patterns at the same time, if switching completely to UMD is not an option. But we probably need to do something with dynamic requires even with UMD.

@amasad
Copy link
Contributor

amasad commented Mar 30, 2015

UMD might be a good solution, might be helpful in removing the few globals that we have, like __fbBatchedBridgeConfig

@amasad
Copy link
Contributor

amasad commented Apr 16, 2015

Just saw this project, anyone wants to give a shot and report back?
https://github.com/mjohnston/react-native-webpack-server

cc @mjohnston

@mjohnston
Copy link

react-native-webpack-server basically fronts the react-native packager with webpack. The react-native code is complied with the built-in React packager, and your app code is compiled with webpack. There's a simple build phase that combines the 2 and concats source maps. The nice thing about this setup is that it opens the door for things like react hot loader.

One thing that might be worth exploring for react-native is concat'ing source maps for code from an external complier (babel, typescript, etc.). I think a fairly common use case is people who want to reuse some of their existing code in a react native app, but that code requires transforms not currently supported by jstransform (let/const and property initializers come to mind).

@amasad
Copy link
Contributor

amasad commented Apr 16, 2015

Thanks @mjohnston! There is an open issue for consuming source maps from custom transformers and I'll get to it soon.

Your project sounds awesome, I'm going to start pointing people interested in using webpack to your project. My only minor concern is that we're currently working on a platform-independent solution for assets and the packager will play a role in that. Meaning, we don't want React Native developers to learn to have to learn the different ways to manage assets (for every platform they want to target) and just use the same method everywhere, and be able to put images with the code and even publish components to npm with images. We're still hammering out the details, but I'm sure you can follow the same approach where you're delegating to react-packager. I'll ping you once we start rolling this out and I'll write some docs.

@mjohnston
Copy link

Sounds good @amasad. I'll try and stay in the loop with regards to the packager.

I imagine that once react packager supports custom transformers (or when you switch to babel) that will satisfy the majority of webpack users.

@amccloud
Copy link

@mjohnston Installing 3rd party modules is the only issue i've run into with your webpack server. Most react-native modules appear to be ES6 but node_modules is ignored by the babel loader.

@mjohnston
Copy link

@amccloud I believe you're talking about the example project which excludes node_modules from the babel loader in the webpack config. It's there in the example so babel doesn't spend time processing all of your npm installed packages, but you can either remove the exclude directive or add an include for your sources plus the ES6 modules you have installed.

@amccloud
Copy link

@mjohnston I tried that. Whitelisting the module but then webpack/babel tries to resolve the require statements in the module. Specifically i'm trying to use https://github.com/lwansbrough/react-native-camera

@mjohnston
Copy link

@amccloud Moving the discussion over to mjohnston/react-native-webpack-server#13

@amasad
Copy link
Contributor

amasad commented Jun 2, 2015

wrt consuming source maps. Now, if you return a map from your transformer the packager would use it to generate the end source map

facebook-github-bot pushed a commit that referenced this issue Feb 16, 2017
Summary:
This PR removes some duplicate code by calculating with ```mainSize```/```crossSize``` and converting that to ```width``` or ```height``` at the end. See #395 .
Closes facebook/yoga#396

Reviewed By: astreet

Differential Revision: D4564713

Pulled By: emilsjolander

fbshipit-source-id: 0b24e69cc9dc75cdf93deeb6c076dcacf134c6d8
GaborWnuk pushed a commit to GaborWnuk/react-native that referenced this issue Feb 28, 2017
Summary:
This PR removes some duplicate code by calculating with ```mainSize```/```crossSize``` and converting that to ```width``` or ```height``` at the end. See facebook#395 .
Closes facebook/yoga#396

Reviewed By: astreet

Differential Revision: D4564713

Pulled By: emilsjolander

fbshipit-source-id: 0b24e69cc9dc75cdf93deeb6c076dcacf134c6d8
dudeinthemirror pushed a commit to dudeinthemirror/react-native that referenced this issue Mar 1, 2017
Summary:
This PR removes some duplicate code by calculating with ```mainSize```/```crossSize``` and converting that to ```width``` or ```height``` at the end. See facebook#395 .
Closes facebook/yoga#396

Reviewed By: astreet

Differential Revision: D4564713

Pulled By: emilsjolander

fbshipit-source-id: 0b24e69cc9dc75cdf93deeb6c076dcacf134c6d8
dudeinthemirror pushed a commit to dudeinthemirror/react-native that referenced this issue Mar 1, 2017
Summary:
This PR removes some duplicate code by calculating with ```mainSize```/```crossSize``` and converting that to ```width``` or ```height``` at the end. See facebook#395 .
Closes facebook/yoga#396

Reviewed By: astreet

Differential Revision: D4564713

Pulled By: emilsjolander

fbshipit-source-id: 0b24e69cc9dc75cdf93deeb6c076dcacf134c6d8
@iddan
Copy link

iddan commented Mar 20, 2017

Custom loaders is another great advantage of Webpack React Native could benefit from

@facebook facebook locked as resolved and limited conversation to collaborators May 31, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests