How to bundle react app with rollup

In case someone will run into this: Here is my working rollup configs.

I updated the demo repo as well.

import babel from 'rollup-plugin-babel';
import filesize from 'rollup-plugin-filesize';
import nodeResolve from 'rollup-plugin-node-resolve';
import progress from 'rollup-plugin-progress';
import visualizer from 'rollup-plugin-visualizer';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';

export default {
  input: 'src/index.js',
  output: [
    {
      file: 'dist/index.js',
      format: 'umd',
      sourcemap: 'inline',
    },
  ],
  plugins: [
    progress(),
    nodeResolve({
      browser: true,
    }),
    json(),
    commonjs({
      include: [
        'node_modules/**',
      ],
      exclude: [
        'node_modules/process-es6/**',
      ],
      namedExports: {
        'node_modules/react/index.js': ['Children', 'Component', 'PropTypes', 'createElement'],
        'node_modules/react-dom/index.js': ['render'],
      },
    }),
    babel({
      babelrc: false,
      presets: [['es2015', { modules: false }], 'stage-1', 'react'],
      plugins: ['external-helpers'],
    }),
    visualizer(),
    filesize(),
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
  ],
};

My original problem was assuming React dependency was external. This is correct for the component libraries but not for standalone app. I also had to fix some minor problems and named imports mapping.

Hope this will save somebody some time.


Here's a more up-to-date version using the supported rollup plugins for anyone new who stumbles across this question wanting TypeScript support:

// rollup.config.js

import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import typescript from '@rollup/plugin-typescript';
import css from 'rollup-plugin-css-only';

export default {
      input: 'src/index.ts',
      output: [
        {
          file: 'dist/index.js',
          name: 'app',
          sourcemap: 'inline',
          format: 'iife',
        },
      ],
      plugins: [
        peerDepsExternal(),
        resolve({
          browser: true,
          dedupe: ['react', 'react-dom'],
        }),
        replace({
          'process.env.NODE_ENV': JSON.stringify('production'),
        }),
        commonjs(),
        typescript({
          tsconfig: 'tsconfig.json',
          sourceMap: true,
          inlineSources: true,
        }),
        css({ output: 'dist/style.css' }),
      ],
    };
  });

This will output an index.js and style.css within the dist folder

If you are not using TypeScript, just remove the typescript import and plugin from the sample.