eslint-config-terser-no-domprops v1.4.0
eslint-config-terser-no-domprops
Helps users of Terser's mangleProps
feature avoid repeated use of protected properties (domprops)
that won't be mangled, thereby reducing code size. Also warns against use of names of DOM built-ins,
which also won't be mangled.
The no-restricted-properties
rule applied in by this config only prevents property access, not
property creation. Ideally, it would also apply to the latter. At least with the config active it's
easy to check what's on the list by writing a temporary test JS file. You can also easily test by
attempting to import a $prop_
from the /vars
export path.
Terser's
mangleProps
feature can break your code. If you aren't familiar with it already, read the docs. This config is designed to be used with the safesttrue
option.The config exports a rule with 8020 restrictions. It will slow down your linting significantly.
Motivation
I like to ship code with the smallest possible bundle size. There are minifiers that can shorten property names, but as far as I know, only Terser is designed to be able to do it for all (safe-ish?) properties out of the box. However, its behaviour in doing this is not very sophisticated: it just has a list of properties that it will not mangle, no matter what object they appear on. To ship the smallest possible code while using this feature, then, you need to avoid the use of Terser's protected properties in your own custom objects.
Installation
npm i -D eslint-config-terser-no-domprops
Usage
In your ESLint config, add terser-no-domprops
to the extends
array.
Tips
This config simply uses ESLint's no-restricted-properties rule, which means it will also throw warnings when using using protected properties on built-in objects, which you might think is unavoidable.
When encountering these warnings, you have two options:
- Ignore them, or
- Engage in the ridiculous practice of indirect access (🙋♂️)
On eslint-config-terser-no-domprops/vars
, this package provides variable declarations for every
built-in object, un-mangleable property, and pre-accessed methods. You can import these, reference
them only once in your code, avoid complaints from this ESLint rule, and use minified references
instead of typing out every character. As an added benefit, this also results in slightly more
minimal code.
- Built-in object references are named like
$ref_Math
- Properties are named like
$prop_random
, with characters that can't appear in JavaScript identifiers replaced with underscores - Pre-accessed methods are named like
$acc_Math_random
, and make use of the aforementioned references and properties already
import {
$prop_appendChild,
$prop_body,
$prop_createElement,
$ref_document
} from "eslint-config-terser-no-domprops/vars"
const elem = $ref_document[$prop_createElement]("h1")
const elem2 = $ref_document[$prop_createElement]("p")
$ref_document[$prop_body][$prop_appendChild](elem)
$ref_document[$prop_body][$prop_appendChild](elem2)
...Terser compiles to...
const e = document,
d = "appendChild",
n = "body",
t = "createElement",
c = e[t]("h1"),
o = e[t]("p")
e[n][d](c), e[n][d](o)
Once you use a restricted property this way about twice, you're usually breaking even on characters used (post-minification). And if you use it only once, Terser is smart enough to remove the variable declaration and inline it, even with dynamic property access or creation.
It makes insanely ugly code, but it's nice knowing you're being efficient.
Happy minifying!