-
Notifications
You must be signed in to change notification settings - Fork 916
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
Tree-shake JS using build result, instead of source #475
Comments
Okay, I took a stab at this and it's working well for the basic usecase. But, it will still require some work to be PR ready: https://github.com/pikapkg/snowpack/compare/wip-install-after-build?expand=1 The current workflow:
This workflow is what causes the issues outlined above: We tree-shake in production, but we're tree-shaking based on the EXACT imports of your source code which aren't always This WIP branch introduces a new workflow:
We could even take this a step further:
Surprisingly, the fact that we already split "building" and "import resolving" into two different steps in build/dev means that this isn't "one step further" proposal isn't as strange as it sounds. It actually removes an entire problem set related to "what do we do when we can't find an import in the import map" during build: the import map is generated from the final build, instead of the reverse that we have today. |
(https://github.com/pikapkg/snowpack/compare/wip-install-after-build has been updated) Update: I actually kind of like the direction that the "one step further" proposal above is heading in:
This is nice in that there's very little duplicate work across steps: just 1 read from disk step, 1 build step, 1 scan step, 1 resolve step, and finally 1 write to disk step. A small downside is that it requires a programatic interface to call |
We're seeing more and more issues related to our tree-shaking scanner not working properly on source files, when the build changes imports:
import { SomeTypeOrInterface }
runs into errors, sinceSomeTypeOrInterface
doesn't exist as an actual JS export, only as a TS type. Our current workaround is to force users to typeimport type { SomeTypeOrInterface }
instead, but this isn't ideal.@emotion/core
: The babel plugin adds a newjsx
import at build time, but this isn't detected when we scan the source file so it's removed via tree-shaking. (See: https://www.pika.dev/npm/snowpack/discuss/356)During development, we're still limited to scanning source files so that we can deliver on our promise of a fast dev environment. If we built every file before scanning, that would get slower as your application grew. BUT... since our build command is by definition building the entire application, it feels like we should take advantage of this higher-fidelity result so that our tree-shaking algo can be as efficient (and as error-free) as possible.
Solution?
One thing that I just realized: we can run our installer AFTER a successful build, and scan the build result directory instead of your source directory. This should solve a whole host of issues around imports that are added/removed/changed during build, or that never exist at all (ex: Svelte core library is never tree-shaken, since no
svelte/internal
imports actually exist in your source code).Ironically, this goes against something that I'd said in #441 - we would now need to continue to support scanning
/web_modules/react.js
, or/custom/web_modules_dir/react.js
. #483 intentionally left this work TODO so that we could resolve here.The text was updated successfully, but these errors were encountered: