Fix an incorrect minification transformation (#1121)
This release removes an incorrect substitution rule in esbuild's peephole optimizer, which is run when minification is enabled. The incorrect rule transformed if(a && falsy) into if(a, falsy) which is equivalent if falsy has no side effects (such as the literal false). However, the rule didn't check that the expression is side-effect free first which could result in miscompiled code. I have removed the rule instead of modifying it to check for the lack of side effects first because while the code is slightly smaller, it may also be more expensive at run-time which is undesirable. The size savings are also very insignificant.
Node searches for packages in nearby node_modules directories, but it also allows you to inject extra directories to search for packages in using the NODE_PATH environment variable. This is supported when using esbuild's CLI as well as via the nodePaths option when using esbuild's API.
Node's module resolution algorithm is well-documented, and esbuild's path resolution is designed to follow it. The full algorithm is here: https://nodejs.org/api/modules.html#modules_all_together. However, it appears that the documented algorithm is incorrect with regard to NODE_PATH. The documentation says NODE_PATH directories should take precedence over node_modules directories, and so that's how esbuild worked. However, in practice node actually does it the other way around.
Starting with this release, esbuild will now allow node_modules directories to take precedence over NODE_PATH directories. This is a deviation from the published algorithm.
Provide a better error message for incorrectly-quoted JSX attributes (#959, #1115)
People sometimes try to use the output of JSON.stringify() as a JSX attribute when automatically-generating JSX code. Doing so is incorrect because JSX strings work like XML instead of like JS (since JSX is XML-in-JS). Specifically, using a backslash before a quote does not cause it to be escaped:
// JSX ends the "content" attribute here and sets "content" to 'some so-called \\'
// v
let button = <Button content="some so-called \"button text\"" />
// ^
// There is no "=" after the JSX attribute "text", so we expect a ">"
It's not just esbuild; Babel and TypeScript also treat this as a syntax error. All of these JSX parsers are just following the JSX specification. This has come up twice now so it could be worth having a dedicated error message. Previously esbuild had a generic syntax error like this:
> example.jsx:1:58: error: Expected ">" but found "\\"
1 │ let button = <Button content="some so-called \"button text\"" />
╵ ^
Now esbuild will provide more information if it detects this case:
> example.jsx:1:58: error: Unexpected backslash in JSX element
1 │ let button = <Button content="some so-called \"button text\"" />
╵ ^
example.jsx:1:45: note: Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes
1 │ let button = <Button content="some so-called \"button text\"" />
│ ~~
╵ "
example.jsx:1:29: note: Consider using a JavaScript string inside {...} instead of a quoted JSX attribute
1 │ let button = <Button content="some so-called \"button text\"" />
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
╵ {"some so-called \"button text\""}
Fix an incorrect minification transformation (#1121)
This release removes an incorrect substitution rule in esbuild's peephole optimizer, which is run when minification is enabled. The incorrect rule transformed if(a && falsy) into if(a, falsy) which is equivalent if falsy has no side effects (such as the literal false). However, the rule didn't check that the expression is side-effect free first which could result in miscompiled code. I have removed the rule instead of modifying it to check for the lack of side effects first because while the code is slightly smaller, it may also be more expensive at run-time which is undesirable. The size savings are also very insignificant.
Node searches for packages in nearby node_modules directories, but it also allows you to inject extra directories to search for packages in using the NODE_PATH environment variable. This is supported when using esbuild's CLI as well as via the nodePaths option when using esbuild's API.
Node's module resolution algorithm is well-documented, and esbuild's path resolution is designed to follow it. The full algorithm is here: https://nodejs.org/api/modules.html#modules_all_together. However, it appears that the documented algorithm is incorrect with regard to NODE_PATH. The documentation says NODE_PATH directories should take precedence over node_modules directories, and so that's how esbuild worked. However, in practice node actually does it the other way around.
Starting with this release, esbuild will now allow node_modules directories to take precedence over NODE_PATH directories. This is a deviation from the published algorithm.
Provide a better error message for incorrectly-quoted JSX attributes (#959, #1115)
People sometimes try to use the output of JSON.stringify() as a JSX attribute when automatically-generating JSX code. Doing so is incorrect because JSX strings work like XML instead of like JS (since JSX is XML-in-JS). Specifically, using a backslash before a quote does not cause it to be escaped:
// JSX ends the "content" attribute here and sets "content" to 'some so-called \\'
// v
let button = <Button content="some so-called \"button text\"" />
// ^
// There is no "=" after the JSX attribute "text", so we expect a ">"
It's not just esbuild; Babel and TypeScript also treat this as a syntax error. All of these JSX parsers are just following the JSX specification. This has come up twice now so it could be worth having a dedicated error message. Previously esbuild had a generic syntax error like this:
> example.jsx:1:58: error: Expected ">" but found "\\"
1 │ let button = <Button content="some so-called \"button text\"" />
╵ ^
Now esbuild will provide more information if it detects this case:
> example.jsx:1:58: error: Unexpected backslash in JSX element
1 │ let button = <Button content="some so-called \"button text\"" />
╵ ^
example.jsx:1:45: note: Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes
1 │ let button = <Button content="some so-called \"button text\"" />
│ ~~
╵ "
example.jsx:1:29: note: Consider using a JavaScript string inside {...} instead of a quoted JSX attribute
1 │ let button = <Button content="some so-called \"button text\"" />
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
╵ {"some so-called \"button text\""}
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.
Dependabot will merge this PR once CI passes on it, as requested by @alexlafroscia.
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Bumps esbuild from 0.8.9 to 0.11.6.
Release notes
Sourced from esbuild's releases.
... (truncated)
Changelog
Sourced from esbuild's changelog.
... (truncated)
Commits
d16c619
publish 0.11.6 to npm0ffaab1
some small changes to release notesef9d29e
fix #1121: remove a bad peephole minification99b2606
fix #1115: add a special-cased error message5dc64cb
fix #1117: check "node_modules" before "NODE_PATH"00269f3
publish 0.11.5 to npmde9864f
disable tree shaking when using code splitting (#1110)e0d09e2
move bit set to another file5aab36b
release notes for hashing speedupsac54d0f
use xxHash instead of SHA1 for speed (#1107)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase
.Dependabot will merge this PR once CI passes on it, as requested by @alexlafroscia.
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)