Skip to content

Commit 232acfe

Browse files
committed
feat(terser): introduce @bazel/terser package
This is a clean implementation starting from what we were running in the built-in rollup_bundle rule. It doesn't yet incorporate our new JS Providers design; that will come next. For now it just understands immediate .js inputs
1 parent 48c5088 commit 232acfe

40 files changed

Lines changed: 776 additions & 0 deletions

commitlint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = {
1818
'protractor',
1919
'stylus',
2020
'rollup',
21+
'terser',
2122
'typescript',
2223
'worker',
2324
]

docs/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ _PACKAGE_READMES = {
4141
"Less": "//packages/less:README.md",
4242
"Protractor": "//packages/protractor:README.md",
4343
"Stylus": "//packages/stylus:README.md",
44+
"Terser": "//packages/terser:README.md",
4445
"TypeScript": "//packages/typescript:README.md",
4546
}
4647

docs/Terser.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: Terser
3+
layout: default
4+
stylesheet: docs
5+
---
6+
# Terser rules for Bazel
7+
8+
**WARNING: this is beta-quality software. Breaking changes are likely. Not recommended for production use without expert support.**
9+
10+
The Terser rules run the Terser JS minifier with Bazel.
11+
12+
Wraps the Terser CLI documented at https://github.com/terser-js/terser#command-line-usage
13+
14+
15+
## Installation
16+
17+
Add the `@bazel/terser` npm package to your `devDependencies` in `package.json`.
18+
19+
Your `WORKSPACE` should declare a `yarn_install` or `npm_install` rule named `npm`.
20+
It should then install the rules found in the npm packages using the `install_bazel_dependencies` function.
21+
See https://github.com/bazelbuild/rules_nodejs/#quickstart
22+
23+
This causes the `@bazel/terser` package to be installed as a Bazel workspace named `npm_bazel_terser`.
24+
25+
26+
## Installing with self-managed dependencies
27+
28+
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:
29+
30+
```python
31+
# Create a terser rule to use in terser_minified#terser_bin
32+
# attribute when using self-managed dependencies
33+
nodejs_binary(
34+
name = "terser_bin",
35+
entry_point = "//:node_modules/terser/bin/uglifyjs",
36+
# Point bazel to your node_modules to find the entry point
37+
node_modules = ["//:node_modules"],
38+
)
39+
```
40+
41+
[name]: https://bazel.build/docs/build-ref.html#name
42+
[label]: https://bazel.build/docs/build-ref.html#labels
43+
[labels]: https://bazel.build/docs/build-ref.html#labels
44+
45+
46+
## terser_minified
47+
48+
Run the terser minifier.
49+
50+
Typical example:
51+
```python
52+
load("@npm_bazel_terser//:index.bzl", "terser_minified")
53+
54+
terser_minified(
55+
name = "out.min",
56+
src = "input.js",
57+
config_file = "terser_config.json",
58+
)
59+
```
60+
61+
Note that the `name` attribute determines what the resulting files will be called.
62+
63+
64+
65+
### Usage
66+
67+
```
68+
terser_minified(name, config_file, debug, sourcemap, src, terser_bin)
69+
```
70+
71+
72+
73+
#### `name`
74+
(*[name], mandatory*): A unique name for this target.
75+
76+
77+
#### `config_file`
78+
(*[label]*): A JSON file containing Terser minify() options.
79+
80+
This is the file you would pass to the --config-file argument in terser's CLI.
81+
https://github.com/terser-js/terser#minify-options documents the content of the file.
82+
83+
Bazel will make a copy of your config file, treating it as a template.
84+
If you use the magic strings `bazel_debug` or `bazel_no_debug`, these will be
85+
replaced with `true` and `false` respecting the value of the `debug` attribute
86+
or the `--define=DEBUG=true` bazel flag.
87+
88+
If this isn't supplied, Bazel will use a default config file.
89+
90+
91+
#### `debug`
92+
(*Boolean*): Configure terser to produce more readable output.
93+
94+
Instead of setting this attribute, consider setting the DEBUG variable instead
95+
bazel build --define=DEBUG=true //my/terser:target
96+
so that it only affects the current build.
97+
98+
99+
#### `sourcemap`
100+
(*Boolean*): Whether to produce a .js.map file for each .js output
101+
102+
103+
#### `src`
104+
(*[label], mandatory*): A JS file, or a rule producing .js as its default output
105+
106+
Note that you can pass multiple files to terser, which it will bundle together.
107+
If you want to do this, you can pass a filegroup here.
108+
109+
110+
#### `terser_bin`
111+
(*[label]*): An executable target that runs Terser
112+
113+

docs/_includes/drawer.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
<li><a href="Jasmine.html">Jasmine</a></li>
4141
</ul>
4242
</li>
43+
<li>
44+
<span class="drawer-nav-title">Optimizers</span>
45+
<ul>
46+
<li><a href="Terser.html">Terser</a></li>
47+
</ul>
48+
</li>
4349
<li>
4450
<span class="drawer-nav-title">Deployment</span>
4551
<ul>

e2e/BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ e2e_integration_test(
9696
},
9797
)
9898

99+
e2e_integration_test(
100+
name = "e2e_terser",
101+
npm_packages = {
102+
"//packages/terser:npm_package": "@bazel/terser",
103+
},
104+
)
105+
99106
e2e_integration_test(
100107
name = "e2e_ts_devserver",
101108
npm_packages = {

e2e/index.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ALL_E2E = [
1313
"stylus",
1414
"symlinked_node_modules_npm",
1515
"symlinked_node_modules_yarn",
16+
"terser",
1617
"ts_auto_deps",
1718
"ts_devserver",
1819
"typescript",

e2e/terser/.bazelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import %workspace%/../../common.bazelrc

e2e/terser/BUILD.bazel

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_test")
2+
load("@npm_bazel_terser//:index.bzl", "terser_minified")
3+
4+
terser_minified(
5+
name = "out.min",
6+
src = "input.js",
7+
)
8+
9+
nodejs_test(
10+
name = "test",
11+
data = ["out.min.js"],
12+
entry_point = ":test.js",
13+
)
14+
15+
# For testing from the root workspace of this repository with bazel_integration_test.
16+
filegroup(
17+
name = "all_files",
18+
srcs = glob(
19+
include = ["**/*"],
20+
exclude = [
21+
"bazel-out/**/*",
22+
"dist/**/*",
23+
"node_modules/**/*",
24+
],
25+
),
26+
visibility = ["//visibility:public"],
27+
)

e2e/terser/WORKSPACE

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright 2018 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
workspace(
16+
name = "e2e_terser",
17+
managed_directories = {"@npm": ["node_modules"]},
18+
)
19+
20+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
21+
22+
http_archive(
23+
name = "build_bazel_rules_nodejs",
24+
sha256 = "3356c6b767403392bab018ce91625f6d15ff8f11c6d772dc84bc9cada01c669a",
25+
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.36.1/rules_nodejs-0.36.1.tar.gz"],
26+
)
27+
28+
load("@build_bazel_rules_nodejs//:defs.bzl", "yarn_install")
29+
30+
yarn_install(
31+
name = "npm",
32+
package_json = "//:package.json",
33+
yarn_lock = "//:yarn.lock",
34+
)
35+
36+
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
37+
38+
install_bazel_dependencies()

e2e/terser/input.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const somelongname = 1;
2+
console.error(somelongname);

0 commit comments

Comments
 (0)