Build ESM views with external CDN support#1382
Build ESM views with external CDN support#1382cristiano-belloni wants to merge 110 commits intorelease/v4from
Conversation
…tsconfig" This reverts commit 04f3b93.
🦋 Changeset detectedLatest commit: 78bc31e The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| }; | ||
| } | ||
| const externalBlockList = | ||
| process.env.EXTERNAL_BLOCK_LIST && !isApp |
There was a problem hiding this comment.
Why would we choose to block things? I think exposing this API without an understanding of why this is necessary is probably a bit careless.
There was a problem hiding this comment.
Mainly for three reasons:
- If you have an organisation with a private registry, some internal packages could be present in the registry but not in the (possibly public) ESM CDN. In that case, you will need to bundle them.
- You could be importing a dependency in the monorepo that "looks" like an external dep from the import statement but in reality is resolved by workspace symlinks (and it's not meant to be published to the registry or the CDN). In that case you almost always want to bundle it (we could filter out the workspace dependencies by default, but then you have the inverse problem: what if they're separately published to the CDN and you want to rewrite them?)
- You could want an escape hatch for when a dependency is broken in the CDN and you can't wait for the CDN to fix it. So you decide to be a bit less efficient and bundle it, until the CDN fixes it, you remove the dependency from the blocklist, re-bundle and redeploy.
We can also have allow lists - they'd be useful in case the CDN exports only a selected range of dependencies (although less useful IMHO). But I wouldn't remove block lists.
There was a problem hiding this comment.
(or maybe you meant that EXTERNAL_BLOCK_LIST is a misnomer? It contains an optional list of dependencies that are to not be rewritten to an external CDN, but bundled in the build file. If you have a better name, happy to change it)
| // If you want to use webpack then we'll always use webpack. But if you've indicated | ||
| // you want esbuild - then we'll switch you to the new fancy world. | ||
| if (!useWebpack || useEsbuild) { | ||
| if (!useWebpack || useEsbuild || isView) { |
There was a problem hiding this comment.
This is untransparent for people that are still using webpack for apps they will probably be expecting webpack for starting a view. I think it would be better to throw an error down the webpack path if it's a view so that people are blocked from that flow, given esbuild is still opt in, and we do currently support webpack for starting views.
There was a problem hiding this comment.
Agree. This is going to be temporary until we have Webpack 5, but I will log an error and throw down the webpack path.
There was a problem hiding this comment.
Done, in start and build too.
There was a problem hiding this comment.
There is another PR that supports Webpack 5 and contains this PR. For the sake of simplicity, I'm keeping them separated.
| dependencies: Dependency, | ||
| browserTarget: string[], | ||
| ): Promise<esbuild.BuildResult & { outputFiles: esbuild.OutputFile[] }> { | ||
| const fileRelativePath = `./${fileName}`; |
There was a problem hiding this comment.
Surely this would be the package name?
There was a problem hiding this comment.
This is index.js if we're starting a view or index-[HASH].js if we're building a view. I think that the view entrypoint js file should be hashed for cache-breaking purposes? After all whoever loads it will fetch it at runtime. We keep track of the name in the output package.json, module field, so there is always a way to get the hashed file name. If you think it should be named differently let's have a chat about that.
|
Close this as it's contained in #1439 |
This is related to #1311
index.htmland_trampoline.jsto distribute views as static site (modular serve viewworks)EXTERNAL_CDN_TEMPLATE="https://esm.sh/[name]@[version]"for esm.sh,EXTERNAL_CDN_TEMPLATE="https://cdn.skypack.dev/[name]@[version]"for Skypack. Default is Skypack.modulefield in output package.json with the built (hashed) module name.bundledDependenciesarray.view serveworks for viewsesnexttargets and fallback tolinkcss injection for global css imports from the CDN.