-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Re-exports from graphql-tag prevent Webpack from tree-shaking correctly #8217
Comments
Seems to fix #8217, judging from the provided reproduction. Presumably this is because using ECMAScript re-export syntax means we don't have to import anything into the scope of the index.ts module, which makes the whole situation easier for the tree-shaker to reason about.
@nwalters512 Thanks for the reproduction! I can confirm the Tree shaking can be fragile (and has multiple implementations with different limitations), but we control both of these packages ( |
Fantastic - thanks @benjamn!
We are rapidly discovering this 😬 but we greatly appreciate that y'all are willing to support it as best you can. I think standard |
Fixes #8217, judging from the provided reproduction. Presumably this is because using ECMAScript re-export syntax means we don't have to import anything into the scope of the index.ts module, which makes the whole situation easier for the tree-shaker to reason about.
Intended outcome:
If my application never imports the
gql
tag from@apollo/client
, no code fromgraphql-tag
should end up in my bundle.Actual outcome:
Even though my application never imports the
gql
tag from@apollo/client
, a lot of code fromgraphql-tag
(andgraphql
, transitively) ends up in my bundle.How to reproduce the issue:
Here's a reproduction with a bog-standard Next.js app: https://github.com/nwalters512/graphql-tree-shaking-repro. Notice how nowhere in the application is
gql
ever imported - the only query (insrc/pages/index.js
) was precompiled to simulate the use of https://github.com/gajus/babel-plugin-graphql-tag.Here's how to actually see that
graphql-tag
code is ending up in the bundle:yarn
to install dependenciesyarn build
.next/static/chunks
- one of them should contain the stringWarning: fragment with name
(on my machine the file was.next/static/chunks/425-4d21a67b7cb1dd316a5c.js
). This corresponds to this line ingraphql-tag
- it's presence demonstrates thatgraphql-tag
code is ending up in the bundle.I believe this is caused by this re-exporting of values from
graphql-tag
in@apollo/client
. You can demonstrate this root cause by editingnode_modules/@apollo/client/core/index.js
in my repro app as follows:Now, run
rm -rf .next && yarn build
to clear any caches and rebuild the app. Observe that the stringWarning: fragment with name
no longer appears in any client-side bundles - this shows that with the removal of that line from@apollo/client
, code fromgraphql-tag
is no longer included in the bundles.I don't know how to actually fix this - the comment about the line in the source explains in great deal why that code is how it is. I also don't know exactly what on that line causes problems - my guess is that the re-exporting of destructured variables from another module throws off its tree shaking algorithm. This suspicion is bolstered by the output from Webpack's StatsWriterPlugin (which we use internally at NerdWallet, not in my sample app) which lists the reason that
node_modules/graphql-tag/lib/index.js
is included in the bundle asharmony side effect evaluation
.This is preventing us from realizing most benefits from
babel-plugin-graphql-tag
- even though we can still compile all queries at build time, we still end up shipping many kilobytes of dependencies fromgraphql
andgraphql-tag
to clients, which negatively impacts performance, especially for low-end devices on slow networks.Versions
The text was updated successfully, but these errors were encountered: