Skip to content

feat(plugin-react): adding jsxPure option#7088

Merged
patak-cat merged 2 commits intovitejs:mainfrom
jpapini:feature/jsx-pure-annotation
Mar 25, 2022
Merged

feat(plugin-react): adding jsxPure option#7088
patak-cat merged 2 commits intovitejs:mainfrom
jpapini:feature/jsx-pure-annotation

Conversation

@jpapini
Copy link
Copy Markdown
Contributor

@jpapini jpapini commented Feb 25, 2022

Description

Passing the pure option to @babel/plugin-transform-react-jsx in order to force pure annotation for custom JSX factory (like @emotion/react).

By default, Babel disable pure annotations if the jsx importSource is not react but we have the opportunity to force pure annotations by adding the pure option to the babel plugin like explained here:
babel/babel#11126 (comment)
This is useful in library mode and it improve treeshaking.

For example:

export default defineConfig({
    plugins: [
        react({
            jsxImportSource: "@emotion/react"
        }),
    ],
});

produce the following output:

import { jsx, jsxs, Fragment } from "@emotion/react/jsx-runtime";

const Component1 = ({
  prop1,
  prop2
}) => {
  return jsxs(Fragment, {
    children: [jsx(Component2, {
      children: prop1
    }), jsx(Component3, {
      prop2
    })]
  });
};

But with:

export default defineConfig({
    plugins: [
        react({
            jsxImportSource: "@emotion/react",
            jsxPure: true,
        }),
    ],
});

it produce the following output:

import { jsx, jsxs, Fragment } from "@emotion/react/jsx-runtime";

const Component1 = ({
  prop1,
  prop2
}) => {
  return /* @__PURE__ */ jsxs(Fragment, {
    children: [/* @__PURE__ */ jsx(Component2, {
      children: prop1
    }), /* @__PURE__ */ jsx(Component3, {
        prop2
    })]
  });
};

Additional context

Pure annotation explanation


What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the Commit Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.

@bluwy bluwy added plugin: react p2-nice-to-have Not breaking anything but nice to have (priority) labels Feb 26, 2022
@bluwy bluwy requested a review from aleclarson February 26, 2022 07:50
@aleclarson
Copy link
Copy Markdown
Contributor

I wonder if jsxPure: true should be the default?

@aleclarson
Copy link
Copy Markdown
Contributor

aleclarson commented Mar 2, 2022

If anything, we could resolve the jsxImportSource, find its package.json, and look for sideEffects field to see if the module has side effects. Not a perfect heuristic, but probably good enough. (eg: @emotion/react has sideEffects: false in its package.json)

Though I think I'm leaning toward jsxPure: true default, since JSX calls are supposed to be pure anyway

@jpapini
Copy link
Copy Markdown
Contributor Author

jpapini commented Mar 7, 2022

Thanks for your review! I added a commit for making jsxPure true by default.
About looking for the sideEffects field in package.json, I think it's not a good way to determine if a custom runtime is side effect free. For example, preact/jsx-runtime didn't have this field in the package.json file.
https://github.com/preactjs/preact/blob/master/jsx-runtime/package.json

@patak-cat patak-cat merged commit d451435 into vitejs:main Mar 25, 2022
@jpapini jpapini deleted the feature/jsx-pure-annotation branch March 28, 2022 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p2-nice-to-have Not breaking anything but nice to have (priority)

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants