React: React 16.0.0-alpha 7 does not bundle correctly in a project using rollup

Created on 7 Apr 2017  Â·  7Comments  Â·  Source: facebook/react

Do you want to request a feature or report a bug?
Bug
What is the current behavior?
When using rollup in a project that imports the latest React 16.0.0-alpha7, the bundle ends up containing both react-development.js and react-production.min.js, and the file size is unnecessarily large.

My guess - This happening because the entry point of react was changed recently to

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

and rollup apparently cannot eliminate exports in dead branches even when replacing process.env.NODE_ENV with production.

Uglify also cannot remove the dead code, because rollup seems to hoist required stuff to the top level.
Online Demo: Try building react@next using this tool that uses rollup to report package sizes. Compare that to searching for just react.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
Steps to reproduce:
1) Import react in any project that uses rollup to bundle.
2) Use [rollup-plugin-replace] (https://github.com/rollup/rollup-plugin-replace) to replace process.env.NODE_ENV with production.
3) Use rollup-plugin-node-resolve, rollup-plugin-commonjs and uglifyjs plugins so that rollup understands commonjs exports and minifies stuff.
4) Check the bundle size, it is 47.5kB.

What is the expected behavior?
Size should be much smaller.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
The size is fine when using 15.4.2 because the entry point reads as

'use strict';

module.exports = require('./lib/React');
Bug

Most helpful comment

We have an open issue on plugin order generally: https://github.com/rollup/rollup/issues/1148

Truthfully, it's kind of a hard problem that goes with the territory — any time you have a plugin system, getting the plugins to interact well with each other is going to be tricky. I haven't found a solution that I'm completely happy with (but open to ideas).

I've added a line to the rollup-plugin-replace README that should hopefully reduce the potential for confusion: https://github.com/rollup/rollup-plugin-replace/blob/master/README.md#usage

All 7 comments

Can you provide a full project please?

Are you using rollup-plugin-replace before rollup-plugin-commonjs? The commonjs plugin eliminates dead branches to solve exactly this problem, but it depends on the process.env.NODE_ENV being replaced before the commonjs transformation takes place.

As @trueadm suggested to me in a chat, we could wrap the whole DEV bundle into a process.env.NODE_ENV condition, and do the opposite for the prod bundle. This way we wouldn't be affected by an incorrect setup.

Well, using rollup-plugin-replace before rollup-plugin-commonjs seems to have worked. Apologies, I come from a webpack world, where order of plugins hardly matter and it is UglifyJS which is mainly responsible for removing development code.

@Rich-Harris should we document this somewhere since other people may get caught up with this too. Don't find a mention about CJS plugin dead code elimination in docs and the issue I linked earlier is slightly misleading.

FWIW it is mentioned in our docs:

screen shot 2017-04-07 at 4 48 52 pm

But I do think it might be better to protect against bad configs on our side too.

We have an open issue on plugin order generally: https://github.com/rollup/rollup/issues/1148

Truthfully, it's kind of a hard problem that goes with the territory — any time you have a plugin system, getting the plugins to interact well with each other is going to be tricky. I haven't found a solution that I'm completely happy with (but open to ideas).

I've added a line to the rollup-plugin-replace README that should hopefully reduce the potential for confusion: https://github.com/rollup/rollup-plugin-replace/blob/master/README.md#usage

I think we fixed it by wrapping the whole dev bundle into an IIFE inside if (process.env.NODE_ENV !== "production") { check.

Was this page helpful?
0 / 5 - 0 ratings