ecsyjs / ecsy-three

ECSY and three.js components, systems and helpers
https://three.ecsy.io
MIT License
178 stars 14 forks source link

Which type of bundle should we provide? #6

Open fernandojsg opened 4 years ago

fernandojsg commented 4 years ago

Currently browsers can't resolve third party modules, so if we include a ecsy-three bundle in your webapp:

// your-app.html
import Sky from 'https://unpkg.com/ecsy-three'

You will get an error indicating that ecsy and three modules are not found, as they are imported on the ecsy-three package

// ecsy-three.module.js
import { TagComponent, System, ... } from 'ecsy';
import { Vector3, Vector4, ... } from 'three';

I'd like to provide a way to use the library without a bundler (webpack or rollup), so people could just import it on, let's say, glitch, and they could work on their projects without that build step.

1. Import maps

The ideal way would be to use import-maps although this is still in early development and we can't expect it to be widely available on browsers anytime soon.

<script type="importmap">
{
  "imports": {
    "ecsy": "https://unpkg.com/ecsy",
    "three": "https://unpkg.com/three"
  }
}
</script>

2. Import maps via es-module-shims

Use a es-module-shims, although is not using the same naming convention and in order to make it work, modules script tags should be using module-shims instead of just `html

<script defer src="es-module-shims.js"></script>
<script type="importmap-shim">
{
  "imports": {
    "ecsy": "https://unpkg.com/ecsy",
    "three": "https://unpkg.com/three"
  }
}
</script>
<script type="module-shim">
  import World from "ECSY";
</script>

3. Bundle everything together

Similar to how A-Frame does right now, bundling threejs inside the A-Frame and exposing it as AFRAME.THREE. We could include ECSY and THREE and exposing it in the bundle as well. The obvious cons is the size of the package, and that we should be using the exposed ecsy and three everywhere instead of importing them again as otherwise we could have some unexpected side effects (as colliding IDs on objects).

4. Replace third-party import with https://unpkg

Create a special bundle where all the external dependencies are being replaced with its unpkg url, so the browser will resolve them just fine:

// ecsy-three.module.js
import { TagComponent, System, ... } from 'ecsy';
import { Vector3, Vector4, ... } from 'three';

will turn into:

// ecsy-three.module.unpkg.js
import { TagComponent, System, ... } from 'https://unpkg.com/ecsy@0.2.2/build/ecsy.js';
import { Vector3, Vector4, ... } from 'https://unpkg.com/three@0.113.2/build/three.module.js';

5. Use snowpack (previously pika/web)

Snowpack will extract the packages from node_modules and create a web_modules folder that will be used to resolve the imports.

fernandojsg commented 4 years ago

We could obviously provide multiple bundles (eg: 3 and 4) and people could use the best that fits their workflow, but I'd love to hear your feedback if you have a preferred/recommended way to go with it