Run rollup.js bundler under Bazel
npm install @bazel/rollupThe Rollup rules run the rollup.js bundler with Bazel.
Add the @bazel/rollup npm package to your devDependencies in package.json. (rollup itself should also be included in devDependencies, unless you plan on providing it via a custom target.)
If you didn't use the yarn_install or npm_install rule, you'll have to declare a rule in your root BUILD.bazel file to execute rollup:
``python`Create a rollup rule to use in rollup_bundle#rollup_bin
attribute when using user-managed dependencies
nodejs_binary(
name = "rollup_bin",
entry_point = "//:node_modules/rollup/bin/rollup",
# Point bazel to your node_modules to find the entry point
data = ["//:node_modules"],
)
The rollup_bundle rule is used to invoke Rollup on some JavaScript inputs.
The API docs appear below.
Typical example:
`python
load("@npm//@bazel/rollup:index.bzl", "rollup_bundle")
rollup_bundle(
name = "bundle",
srcs = ["dependency.js"],
entry_point = "input.js",
config_file = "rollup.config.js",
)
`
Note that the command-line options set by Bazel override what appears in the rollup config file.
This means that typically a single rollup.config.js can contain settings for your whole repo,rollup_bundle
and multiple rules can share the configuration.
Thus, setting options that Bazel controls will have no effect, e.g.
`javascript`
module.exports = {
output: { file: 'this_is_ignored.js' },
}
You must determine ahead of time whether Rollup will write a single file or a directory.
Rollup's CLI has the same behavior, forcing you to pick --output.file or --output.dir.
Writing a directory is used when you have dynamic imports which cause code-splitting, or if you
provide multiple entry points. Use the output_dir attribute to specify that you want a
directory output.
Each rollup_bundle rule produces only one output by running the rollup CLI a single time.
To get multiple output formats, you can wrap the rule with a macro or list comprehension, e.g.
`python`
[
rollup_bundle(
name = "bundle.%s" % format,
entry_point = "foo.js",
format = format,
)
for format in [
"cjs",
"umd",
]
]
This will produce one output per requested format.
You can stamp the current version control info into the output by writing some code in your rollup config.
See the stamping documentation.
By passing the --stamp option to Bazel, two additional input files will be readable by Rollup.
1. The variable bazel_version_file will point to bazel-out/volatile-status.txt which containsbazel_info_file
statuses that change frequently; such changes do not cause a re-build of the rollup_bundle.
2. The variable will point to bazel-out/stable-status.txt file which contains
statuses that stay the same; any changed values will cause rollup_bundle to rebuild.
Both bazel_version_file and bazel_info_file will be undefined if the build is run without --stamp.
> Note that under --stamp, only the bundle is re-built, but not the compilation steps that produced the inputs.
> This avoids a slow cascading re-build of a whole tree of actions.
To use these files, you write JS code in your rollup.config.js to read from the status files and parse the lines.
Each line is a space-separated key/value pair.
`javascript
/**
* The status files are expected to look like
* BUILD_SCM_HASH 83c699db39cfd74526cdf9bebb75aa6f122908bb
* BUILD_SCM_LOCAL_CHANGES true
* STABLE_BUILD_SCM_VERSION 6.0.0-beta.6+12.sha-83c699d.with-local-changes
* BUILD_TIMESTAMP 1520021990506
*
* Parsing regex is created based on Bazel's documentation describing the status file schema:
* The key names can be anything but they may only use upper case letters and underscores. The
* first space after the key name separates it from the value. The value is the rest of the line
* (including additional whitespaces).
*
* @param {string} p the path to the status file
* @returns a two-dimensional array of key/value pairs
*/
function parseStatusFile(p) {
if (!p) return [];
const results = {};
const statusFile = require('fs').readFileSync(p, {encoding: 'utf-8'});
for (const match of
${statusFile}.matchAll(/^([A-Z_]+) (.*)/gm)) {0
// Lines which go unmatched define an index value of and should be skipped.
if (match.index === 0) {
continue;
}
results[match[1]] = match[2];
}
return results;
}
// This undefined variable will be replaced with the full path during the build.
const statuses = parseStatusFile(bazel_version_file);
// Parse the stamp file produced by Bazel from the version control system
let version = '
// Don't assume BUILD_SCM_VERSION exists
if (statuses['BUILD_SCM_VERSION']) {
version = 'v' + statuses['BUILD_SCM_VERSION'];
if (DEBUG) {
version += '_debug';
}
}
`
When you use --compilation_mode=dbg, Bazel produces a distinct output-tree in bazel-out/[arch]-dbg/bin.rollup.config.js
Code in your can look in the environment to detect if a debug build is being performed,
and include extra developer information in the bundle that you wouldn't normally ship to production.
Similarly, --compilation_mode=opt is Bazel's signal to perform extra optimizations.
You could use this value to perform extra production-only optimizations.
For example you could define a constant for enabling Debug:
`javascript`
const DEBUG = process.env['COMPILATION_MODE'] === 'dbg';
and configure Rollup differently when DEBUG is true or false.
The rollup_bin attribute allows you to customize the rollup.js program we execute,nodejs_binary
so you can use to construct your own.
> You can always call bazel query --output=build [default rollup_bin] to see what
> the default definition looks like, then copy-paste from there to be sure yours
> matches.
`python
nodejs_binary(
name = "rollup_more_mem",
data = ["@npm//rollup:rollup"],
entry_point = "@npm//:node_modules/rollup/dist/bin/rollup",
templated_args = [
"--node_options=--max-old-space-size=
],
)
rollup_bundle(
...
rollup_bin = ":rollup_more_mem",
)
`
USAGE
rollup_bundle(name, args, config_file, deps, entry_point, entry_points, format, link_workspace_root,
output_dir, rollup_bin, rollup_worker_bin, silent, silent_on_success, sourcemap, srcs,
stamp, supports_workers)
Runs the rollup.js CLI under Bazel.
ATTRIBUTES
(Name, mandatory): A unique name for this target.
(List of strings): Command line arguments to pass to Rollup. Can be used to override config file settings.
These argument passed on the command line before arguments that are added by the rule.
Run bazel with --subcommands to see what Rollup CLI command line was invoked.
See the Rollup CLI docs for a complete list of supported arguments.
Defaults to []
(Label): A rollup.config.js file
Passed to the --config option, see the config doc
If not set, a default basic Rollup config is used.
Defaults to @npm//@bazel/rollup:rollup.config.js
(List of labels): Other libraries that are required by the code, or by the rollup.config.js
Defaults to []
(Label): The bundle's entry point (e.g. your main.js or app.js or index.js).
This is just a shortcut for the entry_points attribute with a single output chunk named the same as the rule.
For example, these are equivalent:
`python`
rollup_bundle(
name = "bundle",
entry_point = "index.js",
)
`python`
rollup_bundle(
name = "bundle",
entry_points = {
"index.js": "bundle"
}
)
If rollup_bundle is used on a ts_library, the rollup_bundle rule handles selecting the correct outputs from ts_library.entry_point
In this case, can be specified as the .ts file and rollup_bundle will handle the mapping to the .mjs output file.
For example:
`python
ts_library(
name = "foo",
srcs = [
"foo.ts",
"index.ts",
],
)
rollup_bundle(
name = "bundle",
deps = [ "foo" ],
entry_point = "index.ts",
)
`
Defaults to None
(Dictionary: Label -> String): The bundle's entry points (e.g. your main.js or app.js or index.js).
Passed to the --input option in Rollup.
Keys in this dictionary are labels pointing to .js entry point files.
Values are the name to be given to the corresponding output chunk.
Either this attribute or entry_point must be specified, but not both.
Defaults to {}
(String): Specifies the format of the generated bundle. One of the following:
- amd: Asynchronous Module Definition, used with module loaders like RequireJScjs
- : CommonJS, suitable for Node and other bundlersesm
- : Keep the bundle as an ES module file, suitable for other bundlers and inclusion as a