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

build: use esbuild #343

Merged
merged 1 commit into from
Apr 1, 2021
Merged

build: use esbuild #343

merged 1 commit into from
Apr 1, 2021

Conversation

aulneau
Copy link
Contributor

@aulneau aulneau commented Mar 26, 2021

Hi there!

I made a PR for jotai a few days ago updating the build tooling to use esbuild as the typescript transpiler and @dai-shi requested I make PRs for zustand and valtio, so here we are! The main reason for this change is because of how much faster esbuild is at compiling javascript from typescript:

Before
✨ Done in 25.26s.

After
✨ Done in 6.80s.

There are also some very minor bundle size changes with this update.

General overview of changes

  • added esbuild and rollup-plugin-esbuild
  • replaced the typescript plugin in createESMConfig, createCommonJSConfig, and createIIFEConfig to use esbuild
  • added id.includes('@babel/runtime') to the externals check per this recommendation
  • updated the node version used in the codesandbox ci to 12 (due to esbuild requirement)

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 26, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit f66f187:

Sandbox Source
React Configuration
React Typescript Configuration

@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

@dai-shi as I was comparing the packaging of these three packages, zustand stands out of the convention where you're bundling esm as a separate module, and defaulting to cjs as the main export. After this I saw this PR: #336. Curious how you want to move forward?

@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

Yes, let's change it.
It's a breaking change for index.cjs users #336 (comment), but i'm going with just minor update with breaking change notice in the release page, as this use case is not very common.

@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

Same apply here with the comment in valtio: pmndrs/valtio#129 (comment)

rollup.config.js Outdated Show resolved Hide resolved
@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

@dai-shi I haven't seen this kind of thing before: createIIFEConfig, do you want it in both jotai/valtio?

@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

Hm, I think we can drop iife build in zustand. I don't know who is using in which case.
Wonder if @drcmda or @JeremyRH have an idea?

@aulneau aulneau requested a review from dai-shi March 26, 2021 13:20
package.json Outdated Show resolved Hide resolved
@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

There is one new issue that I don't quite understand: https://rollupjs.org/guide/en/#error-this-is-undefined
Screen Shot 2021-03-26 at 8 25 38 AM

src/middleware.ts Outdated Show resolved Hide resolved
@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

Is it happening only for cjs build (esbuild + babel), or also module build (esbuild only)? Or, am I missing something totally.

@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

Is it happening only for cjs build (esbuild + babel), or also module build (esbuild only)? Or, am I missing something totally.

Just for the cjs bundle. It seems to be an issue of the conversion down to es5, but #343 (comment) fixes it

@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

@aulneau Thanks for your investigation.
Actually, I would prefer a solution without changing the src, because it affects the module bundle.
Would you try moduleContext or the custom onwarn? I have no idea what to specify for moduleContext though, null?

@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

Actually, I would prefer a solution without changing the src, because it affects the module bundle.

I am curious though, I think if we do not make this change, the resulting cjs bundle will not work if I understand what the issue is.

Can I ask why you would prefer to keep arrow functions over non? isn't the result the same?

@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2021

I think if we do not make this change, the resulting cjs bundle will not work if I understand what the issue is.

I didn't take like that... It just seems a potential warning. I will read it again.

isn't the result the same?

For the module bundle, arrow functions are not transpiled. I think the current code looks just right and don't want to prohibit unbound arrow functions for the future.

@aulneau
Copy link
Contributor Author

aulneau commented Mar 26, 2021

I didn't take like that... It just seems a potential warning. I will read it again.

I see, if it's just a warning then that should be fine.

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2021

rollup/rollup#1518 (comment)

It's a warning because sometimes you can ignore it and sometimes you can't.

I'm assuming this is a warning not for us.
Please try other options without modifying src:

  • rollup-plugin-async (this is a totally different solution, but it might turn to be good.)
  • moduleContext to null
  • custom onwarn to ignore 'THIS_IS_UNDEFINED'

@aulneau once this is done, let's ask someone to help for trial in discord.

@aulneau
Copy link
Contributor Author

aulneau commented Mar 27, 2021

@dai-shi sure thing!

Question for you around the middleware.ts file. I see here that the promise is used in setItem, however here and here the promise is ignored. Is that intentional? If so, do you want to add void before the ignored promises?

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2021

Question for you around the middleware.ts file. I see here that the promise is used in setItem, however here and here the promise is ignored. Is that intentional? If so, do you want to add void before the ignored promises?

I think it's intentional. @AnatoleLucet can confirm.

I don't mind adding void as you suggested in #343 (comment).
So, this is unrelated with THIS_IS_UNDEFINED thing, right?

@AnatoleLucet
Copy link
Collaborator

Question for you around the middleware.ts file. I see here that the promise is used in setItem, however here and here the promise is ignored. Is that intentional? If so, do you want to add void before the ignored promises?

I think it's intentional. @AnatoleLucet can confirm.

I don't mind adding void as you suggested in #343 (comment).
So, this is unrelated with THIS_IS_UNDEFINED thing, right?

Yes, it's intentional. I don't mind adding a void either.

@aulneau
Copy link
Contributor Author

aulneau commented Mar 27, 2021

So, this is unrelated with THIS_IS_UNDEFINED thing, right?

Yep, just something I've noticed.

So everything seems to be working now. I realized we actually don't need to use either @rollup/plugin-typescript or rollup-plugin-esbuild on the cjs output as we're using babel and it seems to handle it all perfectly fine! Seems to have cut another half a second off the total time :) I think this is ready for folks to test! It'd be good to get some esm based apps (Eg using vite or snowpack) and some cjs apps (maybe a next.js app or something) to ensure nothing is broken!

package.json Outdated Show resolved Hide resolved
@JeremyRH
Copy link
Contributor

JeremyRH commented Mar 28, 2021

@aulneau Awesome job with this PR. Using rollup-plugin-esbuild to parse TypeScript and concurrently to run the builds in parallel is great. I suspect a lot of the build time improvements are due to running them in parallel.

In the future, we should look at using esbuild directly in place of rollup. It doesn't support ES5 output but if we plan on removing the iife bundle, do we need to output ES5?

@dai-shi
Copy link
Member

dai-shi commented Mar 28, 2021

It doesn't support ES5 output but if we plan on removing the iife bundle, do we need to output ES5?

Both iife and cjs used to target ie11, and it doesn't change for cjs in this pr. We still use babel for cjs.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks for your work!

@aulneau aulneau force-pushed the build/esbuild branch 2 times, most recently from 7a26795 to a234671 Compare March 31, 2021 00:56
]
config.babelHelpers = 'runtime'
config.plugins = [...config.plugins, '@babel/plugin-transform-regenerator']
config.babelHelpers = 'bundled'
Copy link
Member

Choose a reason for hiding this comment

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

Let me check how much this would affect the bundle size.

Copy link
Member

Choose a reason for hiding this comment

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

'runtime' 'bundled' diff
index.js 3760 3561 -199
middleware.js 8720 9147 +427
shallow.js 620 620 0
vanilla.js 1798 1798 0

Okay, this is more or less what I expected.
We will probably be refactoring persist in middleware.ts without async/await, so the diff is likely to be reduced in the future.
Let's go with bundled as cjs build is kind of fallback.

@dai-shi dai-shi merged commit 77334ec into pmndrs:master Apr 1, 2021
This was referenced Apr 1, 2021
@dai-shi dai-shi mentioned this pull request Apr 9, 2021
1 task
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.

4 participants