Terser rules for Bazel
The Terser rules run the Terser JS minifier with Bazel.
Wraps the Terser CLI documented at https://github.com/terser-js/terser#command-line-usage
Installation
Add the @bazel/terser
npm package to your devDependencies
in package.json
.
Your WORKSPACE
should declare a yarn_install
or npm_install
rule named npm
.
It should then install the rules found in the npm packages using the install_bazel_dependencies
function.
See https://github.com/bazelbuild/rules_nodejs/#quickstart
This causes the @bazel/terser
package to be installed as a Bazel workspace named npm_bazel_terser
.
Installing with self-managed dependencies
If you didn't use the yarn_install
or npm_install
rule to create an npm
workspace, you'll have to declare a rule in your root BUILD.bazel
file to execute terser:
nodejs_binary(
name = "terser_bin",
entry_point = "//:node_modules/terser/bin/uglifyjs",
node_modules = ["//:node_modules"],
)
terser_minified
Run the terser minifier.
Typical example:
load("@npm_bazel_terser//:index.bzl", "terser_minified")
terser_minified(
name = "out.min",
src = "input.js",
config_file = "terser_config.json",
)
Note that the name
attribute determines what the resulting files will be called.
So the example above will output out.min.js
and out.min.js.map
(since sourcemap
defaults to true
).
If the input is a directory, then the output will also be a directory, named after the name
attribute.
Usage
terser_minified(name, args, config_file, debug, sourcemap, src, terser_bin)
name
(name, mandatory): A unique name for this target.
args
(List of strings): Additional command line arguments to pass to terser.
Terser only parses minify() args from the config file so additional arguments such as --comments
may
be passed to the rule using this attribute. See https://github.com/terser/terser#command-line-usage for the
full list of terser CLI options.
Defaults to []
config_file
(label): A JSON file containing Terser minify() options.
This is the file you would pass to the --config-file argument in terser's CLI.
https://github.com/terser-js/terser#minify-options documents the content of the file.
Bazel will make a copy of your config file, treating it as a template.
Run bazel with --subcommands
to see the path to the copied file.
If you use the magic strings "bazel_debug"
or "bazel_no_debug"
, these will be
replaced with true
and false
respecting the value of the debug
attribute
or the --compilation_mode=dbg
bazel flag.
For example,
{
"compress": {
"arrows": "bazel_no_debug"
}
}
Will disable the arrows
compression setting when debugging.
If config_file
isn't supplied, Bazel will use a default config file.
Defaults to @npm_bazel_terser//:terser_config.default.json
debug
(Boolean): Configure terser to produce more readable output.
Instead of setting this attribute, consider using debugging compilation mode instead
bazel build --compilation_mode=dbg //my/terser:target
so that it only affects the current build.
Defaults to False
sourcemap
(Boolean): Whether to produce a .js.map output
Defaults to True
src
(label, mandatory): File(s) to minify.
Can be a .js file, a rule producing .js files as its default output, or a rule producing a directory of .js files.
Note that you can pass multiple files to terser, which it will bundle together.
If you want to do this, you can pass a filegroup here.
terser_bin
(label): An executable target that runs Terser
Defaults to @npm//@bazel/terser/bin:terser
1.0.0 (2019-12-20)
Bug Fixes
- builtin: bin folder was included in runfiles path for tests when link type was 'bin' (f938ab7)
- builtin: link module_name to directories recursively to avoid directory clashes (#1432) (0217724), closes #1411
- builtin: strip BOM when parsing package.json (#1453) (c65d9b7), closes #1448
- typescript: remove stray references to ts_auto_deps (#1449) (aacd924)
chore
Code Refactoring
- pkg_npm attributes renames packages=>nested_packages & replacements=>substitutions (7e1b7df)
- remove
bootstrap
attribute & fix $(location) expansions in nodejs_binary templated_args (1860a6a) - remove templated_args_file from nodejs_binary & nodejs_test (799acb4)
- builtin: add
args
to yarn_install & npm_install (#1462) (d245d09) - builtin: remove legacy jasmine_node_test (6d731cf)
- builtin: renamed npm_package to pkg_npm to match naming convention (7df4109)
- pre-1.0 release breaking changes (cc64818)
- remove unused exclude_packages from npm_install & yarn_install (f50dea3)
Features
Performance Improvements
BREAKING CHANGES
templated_args_file
removed from nodejs_binary, nodejs_test & jasmine_node_test. This was a separation of concerns and complicated node.bzl more than necessary while also being rigid in how the params file is formatted. It is more flexible to expose this functionality as another simple rule named params_file.
To match standard $(location) and $(locations) expansion, params_file args location expansions are also in the standard short_path form (this differs from the old templated_args behavior which was not Bazel idiomatic)
Usage example:
load("@build_bazel_rules_nodejs//:index.bzl", "params_file", "nodejs_binary")
params_file(
name = "params_file",
args = [
"--some_param",
"$(location //path/to/some:file)",
"--some_other_param",
"$(location //path/to/some/other:file)",
],
data = [
"//path/to/some:file",
"//path/to/some/other:file",
],
)
nodejs_binary(
name = "my_binary",
data = [":params_file"],
entry_point = ":my_binary.js",
templated_args = ["$(location :params_file)"],
)
- bootstrap attribute in nodejs_binary, nodejs_test & jasmine_node_test removed
This can be replaced with the --node_options=--require=$(location label)
argument such as,
nodejs_test(
name = "bootstrap_test",
templated_args = ["--node_options=--require=$(rlocation $(location :bootstrap.js))"],
entry_point = ":bootstrap.spec.js",
data = ["bootstrap.js"],
)
or
jasmine_node_test(
name = "bootstrap_test",
srcs = ["bootstrap.spec.js"],
templated_args = ["--node_options=--require=$(rlocation $(location :bootstrap.js))"],
data = ["bootstrap.js"],
)
templated_args
$(location)
and $(locations)
are now correctly expanded when there is no space before $(location
such as templated_args = ["--node_options=--require=$(rlocation $(location :bootstrap.js))"]
.
Path is returned in runfiles manifest path format such as repo/path/to/file
. This differs from how $(location)
and $(locations) expansion behaves in expansion the args
attribute of a *_binary or *_test which returns
the runfiles short path of the format ./path/to/file
for user repo and ../external_repo/path/to/file
for external
repositories. We may change this behavior in the future with $(mlocation) and $(mlocations) used to expand
to the runfiles manifest path.
See https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes-binaries.
-
- pkg_npm attribute packages renamed to nested_packages
- pkg_npm attribute replacements renamed to substitutions
- builtin: legacy @build_bazel_rules_nodejs//internal/jasmine_node_test removed; use jasmine_node_test from @bazel/jasmine npm package instead
- builtin:
args
in yarn_install and npm_install can be used to pass arbitrary arguments so we removed the following attributes: - prod_only from yarn_install and npm_install; should be replaced by args = ["--prod"] and args = ["--production"] respectively
- frozen_lockfile from yarn_install; should be replaced by args = ["--frozen-lockfile"]
- network_timeout from yanr_install; should be replaced by args = ["--network_timeout", "<time in ms>"]
- builtin:
npm_package
renamed to pkg_npm
. This is to match the naming convention for package rules https://docs.bazel.build/versions/master/be/pkg.html. - Users must now switch to loading from index.bzl
- Removed unused exclude_packages from npm_install & yarn_install
- //:declaration_provider.bzl deleted; load from //:providers.bzl instead
//internal/common:npm_pacakge_info.bzl removed; load from //:providers.bzl instead
transitive_js_ecma_script_module_info macro removed; use js_ecma_script_module_info instead
@npm_bazel_karma//:browser_repositories.bzl removed; use @io_bazel_rules_webtesting//web/versioned:browsers-0.3.2.bzl instead
@npm_bazel_protractor//:browser_repositories.bzl removed; use @io_bazel_rules_webtesting//web/versioned:browsers-0.3.2.bzl instead
ts_web_test & ts_web_test_suite marcos removed; use karma_web_test & karma_web_test_suite instead