Skip to content

Commit

Permalink
Disable terser conditional optimization (#39279)
Browse files Browse the repository at this point in the history
* Disable optimization of conditionals

This prevents optimizations such as converting:

condition ? __( 'true', 'domain' ) : __( 'false', 'domain' );

to

__(o?'true':'false','domain' );

which is an invalid optimization for translatable strings

* changelog

* Update tests now that Terser's conditional optimization has been disabled

* changelog

* Remove documentation about unnecessary workaround
  • Loading branch information
d-alleyne authored and gogdzl committed Oct 25, 2024
1 parent 9ba58c7 commit c9fb037
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 268 deletions.
31 changes: 0 additions & 31 deletions projects/js-packages/i18n-check-webpack-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,37 +102,6 @@ Instead put it inside the property:
/>
```

### Conditional function call compaction

When a conditional calls the same function in each branch with only one argument different, Terser will transform it to a single call with the condition inside the argument. For example, either of these
```js
example = flag ? __( 'Flag is set', 'domain' ) : __( 'Flag is not set', 'domain' );
```
```js
if ( flag ) {
example = __( 'Flag is set', 'domain' );
} else {
example = __( 'Flag is not set', 'domain' );
}
```
will become
```js
example = __( flag ? 'Flag is set' : 'Flag is not set', 'domain' );
```
which will result in neither string being detected for translation.

You can fix this by making the calls less similar, for example by adding a dummy argument to one call
```js
example = flag ? __( 'Flag is set', 'domain' ) : __( 'Flag is not set', 'domain', /* dummy arg to avoid bad minification */ 0 );
```
or by specifying an unnecessary context in one call (or a different context in both)
```js
example = flag ? __( 'Flag is set', 'domain' ) : _x( 'Flag is not set', '', 'domain' );
```
```js
example = flag ? _x( 'Flag is set', 'Something', 'domain' ) : _x( 'Flag is not set', 'Something different', 'domain' );
```

### Pruned branches and common strings

In some cases, such as when `process.env.NODE_ENV` is tested or when ES module tree-shaking is done, code paths can be known to be unreachable. For example, only one branch in the following will be kept:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Updated tests now that Terser's conditionals' optimization is disabled
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ exports[`Webpack \`known-problems\`: Webpack build files 1`] = `
exports[`Webpack \`known-problems\`: Webpack build stats 1`] = `
{
"errors": [
{
"message": "main.js:3:148: msgid argument is not a string literal: __(o?"Foo is set":"Foo is not set","domain")",
},
{
"message": "main.js: Translator comments have gone missing for "The comment will be lost when the assignment is merged into the above const" (context "context")
- Translators: This comment will be lost",
Expand All @@ -113,11 +110,6 @@ exports[`Webpack \`known-problems\`: Webpack build stats 1`] = `
"message": "main.js: Translator comments have gone missing for "This is another workaround" (context "context")
- Translators: This comment will be in the source but not detected for the right message.",
},
{
"message": "main.js: Optimization seems to have broken the following translation strings:
- "Foo is not set"
- "Foo is set"",
},
],
"warnings": [],
}
Expand Down Expand Up @@ -165,245 +157,32 @@ exports[`Webpack \`options-filter\`: Webpack build stats 1`] = `
{
"children": [
{
"errors": [
{
"message": "string/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"message": "string/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"message": "string/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"message": "string/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"message": "string/main.js: Optimization seems to have broken the following translation strings:
- "string is not set"
- "string is set"",
},
],
"errors": [],
"name": "string",
"warnings": [],
},
{
"errors": [
{
"message": "regex/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"message": "regex/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"message": "regex/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"message": "regex/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"message": "regex/main.js: Optimization seems to have broken the following translation strings:
- "regex is not set"
- "regex is set"",
},
],
"errors": [],
"name": "regex",
"warnings": [],
},
{
"errors": [
{
"message": "function/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"message": "function/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"message": "function/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"message": "function/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"message": "function/main.js: Optimization seems to have broken the following translation strings:
- "func is not set"
- "func is set"",
},
],
"errors": [],
"name": "function",
"warnings": [],
},
{
"errors": [
{
"message": "array/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"message": "array/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"message": "array/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"message": "array/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"message": "array/main.js: Optimization seems to have broken the following translation strings:
- "arr is not set"
- "arr is set"",
},
],
"errors": [],
"name": "array",
"warnings": [],
},
{
"errors": [
{
"message": "undefined/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"message": "undefined/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"message": "undefined/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"message": "undefined/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"message": "undefined/main.js: Optimization seems to have broken the following translation strings:
- "arr is not set"
- "arr is set"
- "func is not set"
- "func is set"
- "regex is not set"
- "regex is set"
- "string is not set"
- "string is set"",
},
],
"errors": [],
"name": "undefined",
"warnings": [],
},
],
"errors": [
{
"compilerPath": "string",
"message": "string/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"compilerPath": "string",
"message": "string/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"compilerPath": "string",
"message": "string/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"compilerPath": "string",
"message": "string/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"compilerPath": "string",
"message": "string/main.js: Optimization seems to have broken the following translation strings:
- "string is not set"
- "string is set"",
},
{
"compilerPath": "regex",
"message": "regex/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"compilerPath": "regex",
"message": "regex/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"compilerPath": "regex",
"message": "regex/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"compilerPath": "regex",
"message": "regex/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"compilerPath": "regex",
"message": "regex/main.js: Optimization seems to have broken the following translation strings:
- "regex is not set"
- "regex is set"",
},
{
"compilerPath": "function",
"message": "function/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"compilerPath": "function",
"message": "function/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"compilerPath": "function",
"message": "function/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"compilerPath": "function",
"message": "function/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"compilerPath": "function",
"message": "function/main.js: Optimization seems to have broken the following translation strings:
- "func is not set"
- "func is set"",
},
{
"compilerPath": "array",
"message": "array/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"compilerPath": "array",
"message": "array/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"compilerPath": "array",
"message": "array/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"compilerPath": "array",
"message": "array/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"compilerPath": "array",
"message": "array/main.js: Optimization seems to have broken the following translation strings:
- "arr is not set"
- "arr is set"",
},
{
"compilerPath": "undefined",
"message": "undefined/main.js:1:76: msgid argument is not a string literal: __(t?"arr is set":"arr is not set","domain")",
},
{
"compilerPath": "undefined",
"message": "undefined/main.js:1:186: msgid argument is not a string literal: __(t?"func is set":"func is not set","domain")",
},
{
"compilerPath": "undefined",
"message": "undefined/main.js:1:374: msgid argument is not a string literal: __(t?"regex is set":"regex is not set","domain")",
},
{
"compilerPath": "undefined",
"message": "undefined/main.js:1:488: msgid argument is not a string literal: __(t?"string is set":"string is not set","domain")",
},
{
"compilerPath": "undefined",
"message": "undefined/main.js: Optimization seems to have broken the following translation strings:
- "arr is not set"
- "arr is set"
- "func is not set"
- "func is set"
- "regex is not set"
- "regex is set"
- "string is not set"
- "string is set"",
},
],
"errors": [],
"warnings": [],
}
`;
Expand All @@ -420,16 +199,7 @@ exports[`Webpack \`options-warnOnly\`: Webpack build files 1`] = `
exports[`Webpack \`options-warnOnly\`: Webpack build stats 1`] = `
{
"errors": [],
"warnings": [
{
"message": "main.js:1:77: msgid argument is not a string literal: __(t?"X is set":"X is not set","domain")",
},
{
"message": "main.js: Optimization seems to have broken the following translation strings:
- "X is not set"
- "X is set"",
},
],
"warnings": [],
}
`;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Prevents an optimization of conditionals which breaks translatable strings
3 changes: 3 additions & 0 deletions projects/js-packages/webpack-config/src/webpack/terser.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ const defaultOptions = {
`${ isTranslatorsComment }; return isTranslatorsComment( comment )`
),
},
compress: {
conditionals: false,
},
},
// Same.
extractComments: new Function(
Expand Down

0 comments on commit c9fb037

Please sign in to comment.