skypackjs / skypack-cdn

An issue tracker for the CDN
107 stars 5 forks source link

[Feature] Deep Package Imports #14

Closed NMinhNguyen closed 4 years ago

NMinhNguyen commented 4 years ago

I seem to be unable to load @material-ui/core/Button (which is the preferred way to import Material-UI components, see https://material-ui.com/guides/minimizing-bundle-size/#option-1):

const script = document.createElement('script');
script.type = 'module';
script.src = 'https://cdn.pika.dev/@material-ui/core/Button@%5E4.10.1';
document.head.appendChild(script);

image

Importing from @material-ui/core isn't recommended because it can pull in way too much code.

FredKSchott commented 4 years ago

Importing from files within a package is still experimental, and only well supported for a couple of packages (svelte, preact).

We'll be adding this support soon though, stay tuned

georges-gomes commented 4 years ago

Hi @FredKSchott

We added support for Pika CDN as dependency manager https://webcomponents.dev and https://components.studio

Screenshot 2020-06-22 at 08 19 30

It works pretty well šŸ‘ but in our case deep imports are pretty common.

Just coining a vote for the feature here.

FredKSchott commented 4 years ago

Update: Support has been added! Still considered experimental over the next couple of weeks, but it currently works for all known cases.

FredKSchott commented 4 years ago

Note that https://cdn.pika.dev/@material-ui/core/Button@%5E4.10.1 isn't the correct URL, that would be https://cdn.pika.dev/@material-ui/core@^4.10.1/Button.

Also, worth noting that exports currently only support packages published as ESM. ~Since @material-ui is CJS~ Update: I was wrong! The URLĀ in OP was to the CJS entrypoint, but see below.

NMinhNguyen commented 4 years ago

Ah thanks.

Since @material-ui is CJS

It's actually not. Check module field in https://unpkg.com/browse/@material-ui/core@4.10.0/Button/package.json

NMinhNguyen commented 4 years ago

That being said if I hit esm/Button directly (presumably, pika.dev doesn't use Button/package.json in module resolution), then https://cdn.pika.dev/@material-ui/core/esm/Button and then https://cdn.pika.dev/-/@material-ui/core@v4.10.2-HfV8Hzq1BKBjNDu13I4k/dist=es2019,mode=exports/esm/Button seem to show that there's no bundling? This would lead to a waterfall:

// https://cdn.pika.dev/-/@material-ui/core@v4.10.2-HfV8Hzq1BKBjNDu13I4k/dist=es2019,mode=exports/esm/Button/index.js
export { default } from './Button';

That being said, there is some merit in not bundling - otherwise you could accidentally bundle something that uses React.createContext() (e.g. MUI theme) and is thus meant to be a singleton.

FredKSchott commented 4 years ago

Yup, individual exports are served unbundled because of that exact issue. We can help solve the waterfall issue by sending the proper modulepreload headers down to the browser, but you're still left with ~100 requests just for that one Button.

There are two options to resolve:

  1. Import the entire package at once. It's probably larger than you need, but it's optimize to have no request waterfall and is probably faster in most cases.
  2. If a package has an "exports" map configured, we can pre-bundle based on that. That would give you exactly what you want (minimal requests, minimal file size) but it's something that the package authors will need to configure.
FredKSchott commented 4 years ago

This has been completed! We now pre-bundle and optimize assets based on an export map if one exists. If one does not exist, then we serve the resources directly out of the package.

If you're looking to use a package that is ESM and has no export map, consider asking the team to add one. Or, if they don't want to, you can create one in this project: https://github.com/pikapkg/DefinitelyExported

DefinitelyExported will be our project for crowd-sourced export maps (a lot like DefinitelyTyped is for TypeScript types) that we'll plug into internally.