Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bundle react app with rollup

I am looking for help with rollup config to build simplest react app.

Currently my bundled js file doesn't really bundle any dependency and looks pretty bare bone.

Repo to repro

rollup config file

bundled JS file

My rollup config:

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';

export default {
  input: 'src/index.js',
  output: [
    {
      file: 'dist/index.js',
      format: 'umd',
      globals: {
        react: 'React',
        'react-dom': 'ReactDOM',
        'styletron-react-core': 'StyletronReactCore',
      },
      sourcemap: 'inline',
    },
  ],
  external: ['react', 'react-dom', 'styletron-react-core'],
  plugins: [
    progress(),
    nodeResolve({
      browser: true,
    }),
    json(),
    babel({
      babelrc: false,
      presets: [['es2015', { modules: false }], 'stage-1', 'react'],
      plugins: ['external-helpers'],
    }),
    visualizer(),
    filesize(),
    commonjs({
      include: 'node_modules/**',
    }),
  ],
};
like image 741
Diana Suvorova Avatar asked Jul 11 '18 17:07

Diana Suvorova


2 Answers

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.

like image 114
Dan Barclay Avatar answered Nov 12 '22 11:11

Dan Barclay


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.

like image 20
Diana Suvorova Avatar answered Nov 12 '22 11:11

Diana Suvorova