tooling.report

feature

Flags

Can flags be inlined at build time?

Person in shorts with blue hair walking left

Introduction

Applications often make use of "flags", which are constant values set at build-time. Evaluating these values prior to bundling enables many useful optimizations. For example, flags can make certain code paths unreachable, allowing modules to be pruned from the dependency tree.

The Test

This test compiles a single JavaScript module with a conditional statement based on an IS_SERVER flag. The method by which this flag value is applied varies between tools, but generally the result is that any usage of the variable is replaced with a Boolean literal value at compile time.

index.js

if (IS_SERVER) {
  console.log('This is running on the server');
} else {
  console.log('This is running on the client');
}

To pass the test, IS_SERVER must evaluate to true/false, and the if statement must be eliminated from the output code, leaving only the relevant log.

Conclusion

browserify

Gulp can be used to preprocess JavaScript files, with AST-aware constant inlining powered by gulp-envify. Once constants are inlined, the source can be passed through gulp-terser to remove unreachable conditional code and imports.

parcel

Parcel inlines environment variables whenever they are referenced in source code via process.env.*. As a result, environment variables defined when running parcel can be used as build-time flags.

rollup

The official plugin @rollup/plugin-replace allows you to perform simple replacements within code. Rollup also applies some dead-code elimination without using a minifier, so you can see that unreachable code is removed without needing to read minified code.

Alternatively, you could create a virtual module like import isServer from 'consts:isServer';. The difference is a virtual module can be code-split, whereas the @rollup/plugin-replace method will result in the flag value being duplicated throughout the code.

Given that flags are usually booleans, or small primitive values, duplication is usually better for resource size and loading time than module splitting. If the 'flag' value is more like a larger JavaScript object, then a virtual import becomes a better method.

webpack

Webpack provides two plugins, DefinePlugin and EnvironmentPlugin, both of which inline variables or expressions to during compilation. DefinePlugin allows specifying global constants to be inlined, whereas EnvironmentPlugin accepts a list of environment variables whose value should be inlined anywhere process.env.* is used.