mjohnston / react-native-webpack-server

Build React Native apps with Webpack
MIT License
933 stars 84 forks source link

Potential issue fixing, specifying iOS or Android builds with different webpack configs #156

Closed mikehuebner closed 8 years ago

mikehuebner commented 8 years ago

Hey everyone,

I know this is not a maintained library but I came across an issue with this and am trying to figure out a potential fix for this. And this idea was suggested on StackOverflow.

Essentially, I'm having problems where I'm trying to build .ios and .android files and webpack says they don't exist. This is because the webpack server isn't running the React Native Packager, which if I wasted some time figuring this out please let me know. But this was the fix I came up with which I will clean up shortly. Just wanted to propose a potential fix to this.

Now there will be 2 webpack configs: webpack.config.ios.js webpack.config.android.js

What we could do (with magical ES6) is just create an outline with some variables and just modify the resolve based on arguments passed possibly?

And the webpack configs will have to have a resolve similar to this:

resolve: {
    extensions: ['', '.js', '.[platform].js']
},

Platform would obviously be .ios or .android.

Tell me what you think. It works for me currently messing React Native Material Kit, haven't tested with any other libraries yet.

philikon commented 8 years ago

Hi @mikehuebner. Thanks for the PR. If I understand your problem correctly, I don't think it's necessary to make any code changes. However, we should update the docs to explain how react-native-webpack-server can already serve your use case.

Here's my example for a multi-platform webpack.config.js that serves both Android and iOS bundles using React Native's naming convention for .android.js and .ios.js files. The trick is to use Webpack's multi-compiler feature in which you return an array of webpack configs:

var path = require('path');

function makeConfig(platform) {
  var config = {
    debug: true,
    devtool: 'source-map',
    entry: {},
    output: {
      path: path.resolve(__dirname, 'build'),
      filename: '[name].js',
    },
    resolve: {
      extensions: ['', '.js', '.' + platform + '.js'],
    },
    module: {
      loaders: [{
        ... // see e.g. babel loader config in BabelES6 example
      }],
    },
  };
  config.entry['index.' + platform] = ['./index.' + platform + '.js'];
}

var configs = [];
if (process.argv.indexOf('--no-ios') === -1) {
  configs.push(makeConfig('ios'));
}
if (process.argv.indexOf('--no-android') === -1) {
  configs.push(makeConfig('android'));
}
module.exports = configs;

With this, when I run rnws start, I get two entries, one at http://localhost:8080/index.android.bundle, and one at http://localhost:8080/index.ios.bundle, and they each resolve module imports according to the React Native naming convention for platform-specific modules. To speed things up, I can also call rnws --no-ios or rnws --no-android when I'm only working on one particular platform. These are already standard arguments provided by rnws, my config above just happens to not generate the excluded platform config to further speed up Webpack's startup.

I hope this helps you in your case. I'll close this PR for now. Please reopen if you think otherwise. I do think we should document this solution, so if you'd like to submit a PR for that, that would be most appreciated!

mikehuebner commented 8 years ago

Yea I figured this out yesterday, and I was trying to see if I could prevent this for future users that were confused like me. But I soon found out this is a built in feature to webpack (first month using webpack), sorry for the waste of time on this! And thank you for posting that I'm going to use this for future reference as well!