preserve_annotations preserves comments that merely mention an annotation token, not just real annotations
Under preserve_annotations: true, terser (since v5.26.0) preserves a comment if its text merely contains /[@#]__(PURE|INLINE|NOINLINE)__/ - so unrelated // line comments and prose documentation that just mention __PURE__/__NOINLINE__ survive, instead of only real annotation comments in annotation position.
Version: 5.48.0 (introduced in 5.26.0; <= 5.25.0 drop these comments)
Options: { format: { preserve_annotations: true } }
Input:
function f() {
// keep g() out of line, see the #__NOINLINE__ note // <- prose doc, NOT an annotation
const value = /*#__NOINLINE__*/ g() // <- real annotation
return value ? value : 0
}
function g(){ return 1 }
export { f }Output (5.48.0):
function n(){
// keep g() out of line, see the #__NOINLINE__ note X wrongly preserved (just prose)
const n=/*#__NOINLINE__*/t();return n||0}function t(){return 1}export{n as f};
// OK /*#__NOINLINE__*/ correctly preserved (real annotation)Expected: only the real annotation survives; the // documentation comment is dropped:
function n(){const n=/*#__NOINLINE__*/t();return n||0}function t(){return 1}export{n as f};Why it matters: terser's own output is valid (the // is on its own line), but a preserved // line comment is a latent hazard - any later step that strips/joins newlines (a compact re-bundle, or String.replace(/[\r\n]/g, '')) turns it into a comment that swallows the following code -> SyntaxError: Unexpected end of input.
Source: terser/terser