Recommended Project structure
While React On Rails does not enforce a specific project structure, we do recommend a standard organization. The more we follow standards as a community, the easier it will be for all of us to move between various Rails projects that include React On Rails.
The React on Rails generator uses the standard
rails/webpacker convention of this structure:
The problems with this structure and using rails/webpacker to configure Webpack for you:
- No support for different entry points for server rendering.
- Webpacker adds an extra layer of abstraction over Webpack, which you probably don't want.
This default rails/webpacker configuration is used for the generator because:
- Minimizes the amount of generated code to get up and running with React on Rails.
- Good enough for very simple projects.
- Configuration of Webpack is not the goal of this library, React on Rails.
Thus, the generator structure and using rails/webpacker for Webpack configuration is not recommended for any commercial projects, especially those that will use server rendering. Instead, the recommended structure is shown in this example app: github.com/shakacode/react-webpack-rails-tutorial and described below.
Steps to convert from the generator defaults to use the recommended
/client directory structure.
- Move the directory:
- Edit your
/config/webpacker.ymlfile. Change the
Moving node_modules from
/client with a custom webpack setup.
rails/webpacker probably doesn't support having your main node_modules directory under
/client, so only follow these steps if you want to use your own webpack configuration (which is highly recommended!).
- Move the
- Create a
/package.jsonthat delegates to
/client/package.json. See the example in spec/dummy/package.json.
- See the webpack configuration in spec/dummy/client for a webpack configuration example.
/clientdirectory. Place all the major domains of the client side app under client.
/client/app/bundles: Top level of different app domains. Use a name within this directory for you app domains. For example, if you had a domain called
widget-editing, then you would have:
/client/app/lib: Common code for bundles
Within each bundle directory (or the lib directory), such as a domain named "comments"
/client/app/bundles/comments, use following directory structure:
/actions: Redux actions.
/components: "dumb" components (no connections to Redux or Ajax). These get props and can render themselves and children.
/constants: Constants used by Redux actions and reducers.
/containers: "smart" components. These components are bound to Redux.
/reducers: Reducers for redux.
/routes: Routes for React Router.
/store: Store, which might be configured differently for dev vs. production.
/startup: Component bindings to stores, with registration of components and stores.
/schemas: Schemas for AJAX JSON requests and responses, as used by the Normalizr package.
CSS, Sass, Fonts, and Images
Should you move your styling assets to Webpack? Or stick with the plain Rails asset pipeline. It depends! You have 2 basic choices:
Simple Rails Way
This isn't really any technique, as you keep handling all your styling assets using Rails standard tools, such as using the sass-rails gem. Basically, Webpack doesn't get involved with styling. Your Rails layouts just doing the styling the standard Rails way.
- Much simpler! There's no changes really from your current processes.
Using Webpack to Manage Styling Assets
This technique involves customization of the webpack config files to generate CSS, image, and font assets. See webpack.client.rails.build.config.js for an example how to set the webpack part.
/client/app/assets: Assets for CSS for client app.
- You can use CSS modules, which is super compelling once you seen the benefits.
- You can do hot reloading of your assets. Thus, you do not have to refresh your web page to see asset change, including changing styles.
- You can run your client code on a mocked out express server for super fast prototyping. In other words, your client application can somewhat more easily be move to a different application server.
Updates 2017-03-04 Regarding CSS handled by Webpack
- See article Best practices for CSS and CSS Modules using Webpack.