Enables jsx plugin in case jsx syntax is used in js files#2530
Conversation
More specifically: in an empty folder (no package.json), create a index.js ... |
| */ | ||
| function isUsingJSXinJS(asset) { | ||
| // matches import * as React from 'react' and alike | ||
| const es6Candidate = /from\s+[`"'](react|preact|nervjs|hyperapp)[`"']/; |
There was a problem hiding this comment.
Would this make sense to be just one regex (that is defined as a constant at the top similar to how env variable detections and such works)?
That would simplify this code a lot
| if ( | ||
| pragma || | ||
| JSX_EXTENSIONS[path.extname(asset.name)] || | ||
| isUsingJSXinJS(asset) |
There was a problem hiding this comment.
Should we also use the regex to determine what pragma to use? Presumably this case is to detect if you haven't already installed one of those dependencies yet so would be weird if it always used react.
There was a problem hiding this comment.
This is a valid concern, I was thinking about it as well. Luckily, the pipeline is built in a way that it would, after creating ast in pretransform, re-collect dependencies, install them and re-iterate over that function which results in setting correct pragma.
On second thought, I've decided to implement your suggestion as it should add robustness.
| @@ -0,0 +1,3 @@ | |||
| { | |||
| "private": true | |||
| } | |||
There was a problem hiding this comment.
The underlying problem this PR is trying to solve is that JSX in JS support fails when no dependencies are specified.
No dependencies are two-folded
- When there are no deps in package.json
- When there is no package.json
Unfortunately, I couldn't capture the second case with those tests as omitting package.json would modify package.json in other directories (the top-level package.json in integration-tests I think).
However, creation of package.json is tested on many other occasions, which would lead us back to case 1. So case 2. should work by implication (tested locally, is fine).
| @@ -0,0 +1,3 @@ | |||
| const Preact = require('preact'); | |||
There was a problem hiding this comment.
not using import here for the sake of testing require syntax as well.
9f1c217 to
213383a
Compare
| */ | ||
| function maybeCreateFallbackPragma(asset) { | ||
| for (const dep in JSX_PRAGMA) { | ||
| if (asset.contents.match(createJSXRegexFor(dep))) { |
There was a problem hiding this comment.
Maybe we should create these regexes ahead of time rather than recreating them for every file
There was a problem hiding this comment.
+1 thanks for the hint, will fix tomorrow morning
| * package.json is empty or missing yet and therefore pragma cannot | ||
| * be determined based on pkg.dependencies / pkg.devDependencies | ||
| */ | ||
| const cacheJsxRegexFor = {}; |
There was a problem hiding this comment.
@devongovett, hope that goes in direction of your proposal. If I understood correctly, the intention behind it was to avoid instantiating the same regex multiple times. Regexes are now lazily created in case needed (in other words: in case maybeCreateFallbackPragma gets called) and then cached (similarly to ahead of time creation).
887aa95 to
22bc1d4
Compare
↪️ Pull Request
Enables usage of JSX syntax in
.jsfiles. There are two other alternative solution proposals apart from the current one (see #2519).1. Always enable JSX.
Opinion: It's a clean solution, especially in comparison to current one, but I think it would add overhead in terms of speed where jsx is not needed.
2. Catch the error when babel tries to parse, enable
jsxand re-build.Opinion: Babel fails with error code
'BABEL_PARSE_ERROR'that is too generic to identify if it's a jsx problem or not. It's a possible alternative, but also feels a bit hacky.Feedback appreciated, I intend to add tests if we agree on a solution. I'm not sure if this is a Good First Issue since the solutions we've come up with are not ideal.
💻 Examples
JSX-syntax works now even in files with extension
.js. For instance,index.js.🚨 Test instructions
Create
index.jsfile with above contents and runparcel index.js✔️ PR Todo