Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow jsxFactory and jsxFragment to be passed in buildOptions for use by esbuild #1838

Merged
merged 2 commits into from
Dec 7, 2020
Merged

Conversation

robert-hurst-cmd
Copy link
Contributor

@robert-hurst-cmd robert-hurst-cmd commented Dec 6, 2020

Changes

This PR adds the options jsxFactory and jsxFragment to the buildOptions object within the snowpack config. It allows users to specify a custom jsx factory and fragment function without needing to use babel instead of esbuild. Nothing complex, just passing the options through as esbuild already supports them.

Testing

WIP - This PR is a draft because I wasn't sure how best to create the tests for these options. A recommendation on what kind of test is required from the project's maintainers here is appreciated. I'll update the PR accordingly.

Docs

Added the options to the reference docs for the build options.

@vercel
Copy link

vercel bot commented Dec 6, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/pikapkg/snowpack/6b2f4nvdq
✅ Preview: https://snowpack-git-main.pikapkg.vercel.app

@FredKSchott
Copy link
Owner

Normally it's good to start a discussion first before creating a PR, in case the work isn't something that we're interested in merging. In this case, are you coming from #1681 ? I think the latest from that thread was that just changing the pragma wouldn't help here to enable the React 17 JSX transform, since that pragma uses a new function signature. See Evan's answer here: #1681 (reply in thread)

If you have a different use-case, please share it!

@robert-hurst-cmd
Copy link
Contributor Author

robert-hurst-cmd commented Dec 6, 2020

@FredKSchott i should have included that context, sorry about that. I saw this discussion #1422 in which you mentioned you’d love to see a PR exposing these options via buildOptions.

As little background, I’ve been writing my own frontend framework which uses JSX. I wanted to use snowpack to build it, but noticed there was no way to change the JSX factory or fragment functions without using Babel instead of esbuild. I thought it would be an easy win here to support anyone not using React or Preact to allow these options to be passed, since all of the hard work has already been implemented on the esbuild side. The options just needed to be exposed.

Copy link
Owner

@FredKSchott FredKSchott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. appreciate the extra detail.

To add a test, look in the tests/build directory and copy the format of a similar directory (make sure you rebase off of master, since there were recently some changes to how we do build tests).

const isPreact = checkIsPreact(filePath, contents);
if (isPreact) {
jsxFactory || (jsxFactory = 'h')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit different from how we treat conditional variable setting in the rest of the codebase. for consistency, please do something closer to this:

const jsxFactory = config.buildOptions.jsxFactory ?? (isPreact ? 'h' : undefined);
const jsxFragment = config.buildOptions. jsxFragment ?? (isPreact ? 'Fragment' : undefined);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. The nullish operator is much better here, glad you guys are using them 👍

@@ -194,6 +194,14 @@ module.exports = {

- Rename your web modules directory.

#### buildOptions.jsxFactory | `string` | Default: `React.createElement` or `h` if Preact is detected
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Default: React.createElement (or h, if a Preact import is detected)
Default: React.Fragment (or Fragment, if a Preact import is detected)

@@ -68,6 +68,8 @@ const DEFAULT_CONFIG: SnowpackUserConfig = {
sourceMaps: false,
watch: false,
htmlFragments: false,
jsxFactory: undefined,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if undefined, just leave unset in this default object. You'll need to update the SnowpackConfig TypeScript interface as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it because I saw hmrPort was set to undefined above in dev options. Makes sense, I'll remove it.

Copy link
Owner

@FredKSchott FredKSchott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, LGTM!

@FredKSchott FredKSchott marked this pull request as ready for review December 7, 2020 19:14
@FredKSchott FredKSchott merged commit 1f42e44 into FredKSchott:main Dec 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants