Code Monkey home page Code Monkey logo

react-cosmos's Introduction

Cosmos

React Cosmos ✭ DX tool for designing reusable React components

Build status Coverage status Slack PRs Welcome

Cosmos scans your project for components and loads them inside Component Playground, enabling you to:

  1. Render components under any combination of props, context and state
  2. See state evolve in real-time while interacting with running instances

Component Playground

Working with Cosmos improves component design because it surfaces implicit dependencies. It also forces you to define sane inputs for your components, making them predictable and easier to debug down the road.

Read the story of React Cosmos: Fighting for Component Independence.

Requirements

  • Node >=5 (older versions might work but aren't guaranteed)
  • React >=0.14.9
  • webpack or Browserify (or go rogue and roll your own)
  • Fixtures to define states for your components (you'll do this after you get started)

Usage

The easiest way to use React Cosmos is alongside webpack. Making it work with Browserify takes extra work, but a complete example is available.

Jump to:

Have a question or idea to share? See you on Slack.

react-cosmos-webpack

Extends your existing webpack config (or uses a default config) and starts a dev server for Component Playground tuned to your codebase.

By default, it looks for a __fixtures__ dir next to your components.

src/components/Button.jsx
src/components/__fixtures__/Button/default.js
src/components/__fixtures__/Button/disabled.js

# also works if you have one folder per component
src/components/Button/Button.jsx
src/components/Button/__fixtures__/default.js
src/components/Button/__fixtures__/disabled.js

Follow these steps to get started:

1. Install package

npm i -D react-cosmos-webpack

2. Add cosmos.config.js to your project root

// cosmos.config.js
module.exports = {
  componentPaths: ['src/components'],
};

3. Start and load playground 🎉

node_modules/.bin/cosmos
# or
node_modules/.bin/cosmos --config path/to/cosmos.config.js

Bonus: Create npm run cosmos script for extra sugar

// package.json
"scripts": {
  "cosmos": "NODE_ENV=development cosmos"
}

Voilà! Now you can extend your config, start creating fixtures or be kind and report what went wrong.

Also see:

Configuring index.html

GET http://localhost:8989/loader/index.html 404 (Not Found)

The browser console might greet you with this error when using a custom webpack config. There are two methods for configuring the Loader index.html page:

  1. Use html-webpack-plugin
  2. Put a static index.html file in your public path (see publicPath option below)

Using html-webpack-plugin is recommended because it automatically injects the <script> tag in index.html. If you create your own index.html then make sure the script tag points to "main.js".

<script src="./main.js"></script>

Option dump

Options supported by cosmos.config.js.

// cosmos.config.js
module.exports = {
  // Read components from multiple locations. Useful for including Redux
  // containers or if you split your UI per sections.
  componentPaths: [
    'src/components',
    'src/containers'
  ],

  // Additional paths to search for fixtures, besides the __fixtures__ folder
  // nested inside component paths. Useful if you keep fixture files separated
  // from components files.
  fixturePaths: [
    'test/fixtures'
  ],

  // Additional entry points that should be present along with any component.
  // Sad, but inevitable.
  globalImports: [
    './reset.css',
    './global.css',
  ],

  // Components will not be loaded in the playground if their names match these.
  // There's no excuse for components that can't be loaded independently, but
  // if you store HoCs (which export functions) next to regular components, well,
  // what are you gonna do, not use this wonderful tool?
  ignore: [
    /notATrueComponent/,
    /itsComplicated/,
    /itsNotMeItsYou/,
  ],

  // Where to serve static files from. Like --content-base in webpack-dev-server.
  publicPath: 'src/public',

  // Read more about proxies below
  proxies: [
    './redux-proxy.js',
    './context-proxy.js',
  ],

  // Render inside custom root element. Useful if that root element already
  // has styles attached, but bad for encapsulation.
  containerQuerySelector: '#app',

  // Enable hot module replacement.
  hot: true,

  // These ones are self explanatory
  hostname: 'localhost',
  port: 8989,
  webpackConfigPath: './config/webpack.config.dev',
};

Custom component paths

The componentPaths option supports both dir and file paths. Most of the times using a dir path is enough (e.g. "src/components"), but we might need to target the exact file paths when component files sit next to non-component files. Here's an example for this type of setup:

// cosmos.config.js
componentPaths: [
  'src/components/A.jsx',
  'src/components/B.jsx'
],
getComponentName: componentPath =>
  componentPath.match(/src\/components\/(.+)\.jsx$/)[1]

Note: The getComponentName option needs to be added when using file paths.

We can also use glob instead of adding each component by hand:

// cosmos.config.js
componentPaths: glob.sync('src/components/*.jsx')

Using Create React App

It's preferred to use CRA's own webpack config (instead of duplicating it).

// cosmos.config.js
module.exports = {
  componentPaths: ['src/components'],
  containerQuerySelector: '#root',
  webpackConfigPath: 'react-scripts/config/webpack.config.dev'
};

Also make sure to:

  • Run cosmos with NODE_ENV=development
  • Put proxies in the src dir–the only place included by the CRA Babel loader

CRA + Cosmos example: Flatris

Using React Redux Starter Kit

It's preferred to use the starter kit's own webpack config (instead of duplicating it).

// cosmos.config.js
module.exports = {
  componentPaths: [
    'src/routes/Counter/components',
    'src/routes/Home/components'
  ],
  webpackConfigPath: 'build/webpack.config.js'
}

Also make sure to:

  • Run cosmos with NODE_ENV=development
  • Set up the Redux proxy :)

Using Next.js

Next.js apps run on both client & server, so compilation is done via Babel plugins instead of webpack loaders. This means we can rely on Cosmos' default webpack config.

// cosmos.config.js
module.exports = {
  componentPaths: ['components'],
};

Define .babelrc for the Cosmos webpack config to rely on the Next.js preset.

{
  "presets": ["next/babel"],
}

Next.js + Cosmos example: Illustrated Algorithms

Using babel-node

Unless you pass it the --plain param, react-cosmos-webpack runs with babel-node by default. This is nice because it allows you to write your configs using the same syntax as your source code.

Proxies

Proxies are a plugin system for React Cosmos, allowing fixtures to go beyond mocking props and state. As regular React components, they compose in the order they are listed in your config and decorate the functionality of the loaded component, while respecting the contract to render the next proxy in the chain.

The added functionality can range from mocking Redux state (or server requests made from your components) to creating a resizable viewport for seeing how components behave at different scales.

react-cosmos-redux-proxy

Most components in a Redux app depend on Redux state–either they're a container or one of their descendants is. This proxy creates the store context required for any component you load, just like Provider does for your root component. Writing Redux fixtures almost feels too easy. Because Redux state is global, once you have one state mock you can render any component you want!

// redux-proxy.js
import createReduxProxy from 'react-cosmos-redux-proxy';

export default () => {
  return createReduxProxy({
    // Called when fixture loads with fixture.reduxState as initial state.
    // See https://github.com/skidding/flatris/blob/master/cosmos/redux-proxy.js
    createStore: (initialState) => {
      return Redux.createStore(yourReducer, initialState, yourMiddleware);
    },
  })
};

react-cosmos-context-proxy

Very convenient if your app uses component context. You can provide generic context using a base fixture that all other fixtures extend.

// context-proxy.js
import createContextProxy from 'react-cosmos-context-proxy';

export default () => {
  return createContextProxy({
    // Expects fixture.context to contain `theme` object
    // See examples/context
    childContextTypes: {
      theme: PropTypes.object.isRequired,
    },
  });
};

What proxy would you create to improve DX?

Join the component revolution!

This project welcomes all. Check out the Contributing Guide to read about the project's mission and how to get involved. Ask anything on Slack. Let's make UI development fun!

Thanks to Kreativa Studio for the Cosmos logo.

react-cosmos's People

Contributors

ovidiuch avatar nighttrax avatar greenkeeper[bot] avatar piatra avatar ovidiubute avatar raitobezarius avatar bogdanjsx avatar w0rm avatar bogdan-stefan-hs avatar catalinmiron avatar jlc467 avatar radvalentin avatar ganderzz avatar gaearon avatar adaschevici avatar bbirand avatar danlipsitt avatar flavius-tirnacop-hs avatar jnishiyama avatar robbert229 avatar maciej-ka avatar cef62 avatar n1k0 avatar nik-kor avatar raulanatol avatar gitter-badger avatar yustynn avatar

Watchers

James Cloos avatar Amr Draz avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.