Skip to content

Instantly share code, notes, and snippets.

@mattwondra
Last active April 11, 2016 17:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattwondra/2a2d9f54b14e5d87e97297fda651d839 to your computer and use it in GitHub Desktop.
Save mattwondra/2a2d9f54b14e5d87e97297fda651d839 to your computer and use it in GitHub Desktop.
Call for ideas on using Webpack with react-stdio

Ref: https://github.com/mjackson/react-stdio

The latest version of react-stdio is agnostic to your specific JS build steps (e.g. what bundler and transforms you use), and instead requires you to provide fully-compiled components that a standard node environment is able to process. This is very smart, since not everyone is using Babel (hard-coded in a previous version).

However, I'm having trouble figuring out the best way to integrate my components that are bundled through Webpack, especially since they have reliance on one another. For example, say I have two components <Button> and <Teaser> (which requires <Button>). My instinct is to put both components as entry points in my Webpack config, so that they will be exported as individual compiled modules for react-stdio. But this causes the Webpack error a dependency to an entry point is not allowed. (See sample Webpack config below).

I'm aware that you can trick Webpack into allowing this by wrapping the entry values in an array (see webpack/webpack#300) but I don't want to rely on a hack like this for core app functionality.

Can anyone think of a good clean way to get around this? How can I use Webpack to export individual components (many of which rely on each other) so that react-stdio can consume them as vanilla JS modules?

// Example Webpack config to bundle universal components for react-stdio
var config = {
entry: {
"Button": "./universal/Button.js",
// <Teaser> requires <Button>, so this causes this Webpack error:
// `Error: a dependency to an entry point is not allowed`
"Teaser": "./universal/Teaser.js"
// The hack solution is to replace the line with:
// "Teaser": ["./universal/Teaser.js"]
// but I don't want to rely on broken behavior to solve this.
},
output: {
path: "./components/server",
filename: "[name].js"
},
// Lots of other config options like custom loaders and resolvers
};
module.exports = config;
@mjackson
Copy link

Instead of listing both Button and Teaser as entry points, just bundle them one at a time:

webpack ./universal/Button.js
webpack ./universal/Teaser.js

@mattwondra
Copy link
Author

@mjackson It's a good thought, but I'd also like to dynamically update the files in dev mode, which would mean a separate webpack --watch running for each file — I suppose I'm not sure without testing it, but this seems likely to cause performance issues when the number of components gets into the dozens.

@sokra
Copy link

sokra commented Apr 11, 2016

I'm aware that you can trick Webpack into allowing this by wrapping the entry values in an array

This is the solution for webpack 1. The problem is fixed in webpack 2.

An alternative is this:

var entries = {
  "Button": "./universal/Button.js",
  "Teaser": "./universal/Teaser.js"
};

module.exports = Object.keys(entries).map(function(name) {
  return {
    name: name,
    entry: entires[name],
    output: {
      path: "...",
      filename: name + ".js"
    },
    // Lots of other config options like custom loaders and resolvers
  }
});

@mattwondra
Copy link
Author

@sokra Oh snap, I think that's exactly what I needed! I had no idea you could export an array to essentially run multiple webpack processes from a single command.

It's very possible it will have the same perf issues I'm wary of from @mjackson's suggestion, but I definitely like keeping the complexity hidden in the webpack conf, so I can watch everything with a single webpack --watch command.

Thanks for the suggestion!

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