Skip to content

Firestore bundle build #4090

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

Merged
merged 6 commits into from
Nov 20, 2020
Merged

Firestore bundle build #4090

merged 6 commits into from
Nov 20, 2020

Conversation

Feiyang1
Copy link
Member

Notable changes:

  • Build the main, memory and bundle entry points in one go in order to share code. So developers can do the following without including any duplicate code.
import `@firebase/firestore`
import `@firebase/firestore/bundle`

or

import `@firebase/firestore/memory`
import `@firebase/firestore/bundle`

It is achieved by supplying a map of entry points to rollup's input field instead of building single entry point individually.

  • Moved bundle specific code out of the files referenced by the main entry point, and into bundle specific files, e.g. api/bundle.ts and core/bundle.ts. I also created a new file local/local_store_bundle.ts and moved bundle specific functions in local/local_store.ts to it.

This is needed to code split the bundle code from the main SDK code. Generally, code defined in the same module cannot be split into different bundles, a limitation imposed by the es6 spec. The spec says a module should only be evaluated once at runtime, so its side effects only happen once. If a module gets split into multiple bundles, the module will be effectively evaluated multiple times once per bundle. There is also the question on which bundle(s) should include the side effect code (e.g. a top level console.log()).

In case a module doesn't have side effects, I thought it's possible to code split it safely using

treeshake: {
      moduleSideEffects: false
}

but it doesn't seem to make any difference using rollup. Maybe webpack is able to, but I didn't try.
Anyway, I think it's safer to follow the spec and move bundle code into its own files.

  • Added the entry point for @firebase/firestore/bundle

Todos:

  • Bundle code are hard coded into some classes. For example, bundleCache in IndexedDbPersistence and MemoryPersistence. We may want to look into prototype patching these classes at runtime in order to split out the bundle code.

  • I reorganized code without thinking too much about the semantics. You might want to redo some of the changes.

  • We need to add a bundle entry point in firebase.

  • I removed loadBundle and namedQuery from the firestore namespace definition in the main entry point to enable code split.
    If we want them to be available under firebase.firestore after people import @firebase/firestore/bundle, we should patch them onto firebase.firestore. I added a TODO for it in the comment.

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2020

⚠️ No Changeset found

Latest commit: cca3da7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@Feiyang1
Copy link
Member Author

You can see the code split result by looking at the generated bundle.js , e.g. dist/esm2017/bundle.js

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Nov 19, 2020

Size Analysis Report

Affected Products

No changes between base commit (8dbf020) and head commit (4f9707d).

Test Logs

@schmidt-sebastian
Copy link
Contributor

The concept looks pretty good to me. I wonder if it makes sense to do the prototype patching for the Persistence-methods. Ideally, I would not be in this business for firestore-exp, but prototype patching would be the only way to get rid of the extra methods, as they are part of a class hierarchy. I think for now we can probably keep them as is, especially since they will already be part of the next @firebase/firestore release.

@Feiyang1
Copy link
Member Author

The amount of code in dist/esm2017/bundle.js doesn't seem to be a lot with this PR. Is it really 5% of the entire SDK? Maybe I missed something. Can you guys take a look to see if any bundle code that should be code split, but weren't?

@Feiyang1
Copy link
Member Author

Feiyang1 commented Nov 19, 2020

We should be able to see the size report once #4094 is merged and this PR and Hui's PR rebased on master.

@wu-hui
Copy link
Contributor

wu-hui commented Nov 20, 2020

This looks great! It would probably take me rest of 2020 to figure out all of these by myself!

Agree with Sebastian we can probably leave persistence code out for now.

@wu-hui wu-hui merged commit 7ae8144 into wuandy/BundlesPrototypePatch Nov 20, 2020
@firebase firebase locked and limited conversation to collaborators Dec 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants