rollup / rollup-plugin-commonjs

This module has moved and is now available at @rollup/plugin-commonjs / https://github.com/rollup/plugins/blob/master/packages/commonjs
MIT License
502 stars 126 forks source link

Evaluating conditional require delayed #424

Closed yesmeck closed 4 years ago

yesmeck commented 4 years ago

We came across a situation that there is a third party library require module conditionally.

function foo() {
  if (env.production) {
    return require('./foo.production');
  }
  return require('./foo');
}

Now this plugin will hoist all requires to the top scope, which will lead both modules to be evaluated, but we want them to be evaluated conditionally. Can we evaluating conditional required module delayed?

LeoYuan commented 4 years ago

We ran into the same issue too.

Supposed solution:

Find those requires in conditional statement like if / else if / switch case / conditional operator, and wrap those module in a lazy execution mode, code as below:

import getFooProduction from './foo.production-wrapper';
import getFoo from './foo-wrapper';

function foo() {
  if (env.production) {
    return getFooProduction();
  }
  return getFoo();
}
LeoYuan commented 4 years ago

I tried using { ignore: [ './foo.production', './foo' ] } to prevent transpiling conditional requires, BUT sadly, the ignore files will not be copied to dist folder, so an Module Not Found error would be thrown when try to load ./foo.production / ./foo.

I think this solution maybe better than that I supposed above, ignore specified modules & copy those required modules to dist folder

eight04 commented 4 years ago

I think what we need is to run dead code elimination before running the commonjs plugin. Rollup already supports dead code elimination. Not sure if it is possible to extract the logic into a plugin.

Currently, I'm using the re plugin to strip unwanted modules from the bundle i.e. replace the entire module with an empty string.

yesmeck commented 4 years ago

The conditions are determined at runtime, rollup-plugin-re won't work in my case.

lukastaegert commented 4 years ago

There is currently no way to translate a synchronous conditional require call to an ES module, which is required to make this work. Possible options:

yesmeck commented 4 years ago

@lukastaegert I see thanks for your reply.