Skip to content
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

Request: provide clear example on creating non-trivial UMD bundles #898

Closed
d-w-d opened this issue Oct 8, 2020 · 5 comments
Closed

Request: provide clear example on creating non-trivial UMD bundles #898

d-w-d opened this issue Oct 8, 2020 · 5 comments
Labels
kind: support Asking for support with something or a specific use case problem: stale Issue has not been responded to in some time

Comments

@d-w-d
Copy link

d-w-d commented Oct 8, 2020

Current Behavior

There is no guidance on how to include/exclude imported modules into a UMD bundle. I have spent a whole day playing around with tsdx.config.js and rollup plugins trying to make it work. I find both the rollup-plugin documentation and tsdx documentation lacking. By comparison, I have found it straightforward in the past to create UMDs with webpack.

Desired Behavior

Here is my code, which includes a tsdx.config.js file. I want to be able to build a working UMD bundle when I run ./_build_all (a wrapper around tsdx build --format umd). I also want to be able to control what gets bundled into the UMD. The 3rd party dependencies imported into my code are:

import React, { useState, useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';

For the UMD, I'd like the OrbitControls and TrackballControls bundled, but Three and React can be externalized.

Suggested Solution

Please show me how to configure my tsdx.config.js file to achieve my stated ends, and then consider including this as an example in your codebase to help others.

Who does this impact? Who is this for?

Anyone who is trying to create a non-trivial UMD bundle will benefit from a clear example of a codebase with various dependencies where some need to be bundled, and some need to be excluded.

Describe alternatives you've considered

Abandon tsdx/rollup altogether and start again using webpack 5.

@d-w-d d-w-d changed the title Provide clear example on creating non-trivial UMD bundles Request: provide clear example on creating non-trivial UMD bundles Oct 8, 2020
@agilgur5 agilgur5 added the kind: support Asking for support with something or a specific use case label Oct 12, 2020
@agilgur5
Copy link
Collaborator

agilgur5 commented Oct 12, 2020

TSDX doesn't seem to have that many UMD users (it hasn't been part of the default build output for a while either (#120 / #126)), or at least not "non-trivial" UMD users, so as such I don't think there's as much experience with UMD when compared to the other formats. I'd agree that the Rollup docs are somewhat "low-level" and can be difficult to grok until you've read through them a few times or used the options a few times (it's even more so on the plugins side 😅 ). It hasn't gotten as much attention as Webpack and has a number of advanced features (e.g. Rollup has more advanced side-effect detection than other bundlers, can output multiple bundles, etc), Webpack's docs used to be even more low-level than Rollup's however. Rollup is very open to docs contributions and suggestions, especially from newcomers at the beginning of the learning curve.

Bundling is particularly more complex as it can involve externals, globals, and commonjs options (the latter being different from something like Webpack). Though in my experience, externals were confusing with Webpack too (though my last experience building libraries with Webpack was Webpack 1 or maybe 2). On top of that, ThreeJS adds some complexity too as it's historically been pretty monolithic and had poor bundler support -- I'm surprised OrbitControls and TrackballControls still haven't been split up into official libraries. You're trying to leave Three externalized but some of its internals bundles which is definitely non-trivial.

I'll try to help with this with my limited time as I think this could be a good example / use-case and could potentially reveal some bugs.

@agilgur5
Copy link
Collaborator

agilgur5 commented Oct 12, 2020

First, you might be able to get a library variant of TrackballControls and OrbitControls; e.g. I've used three-trackballcontrols before.

Some unrelated comments:

  • I'd think you'd want to change the "type" of repo to a "template repo" on GitHub since you seem to be wanting to provide a template -- might want to wait till this is fixed though 😅
  • I noticed you had react and react-dom as deps -- react-dom generally isn't used directly in libraries though and react is already a peerDep (that's part of the TSDX template). You probably want to have three as a peerDep too.
  • I noticed you used --name -- there's gonna be a breaking change to that in the next breaking version due to (fix): --name shouldn't change output filenames #669

@agilgur5
Copy link
Collaborator

agilgur5 commented Oct 12, 2020

Second, you've got some mismatches with your Rollup plugins that I'm not sure are intentional. Not sure if this branch is from a different debugging attempt that might explain it. You have two versions of node-resolve and plugin-typescript as well as plugin-typescript2. The commonjs version is also incorrect. You can see TSDX's package.json for the versions and plugins used. (I noticed you had a fix for #888 / #892 / #896, which is correct).
...But you shouldn't need to import the plugins to override them. Perhaps you're misunderstanding how to configure tsdx.config.js -- #379 has a few examples. You've got config.plugins = [ ... ] and are basically re-writing all the internal plugins instead of something like config.plugins.map(...) and modifying some of the existing plugins.
Also if you did need to import for some reason, e.g. exact name matching during a search of the plugins, you wouldn't necessarily need to install those plugins since TSDX has already installed them into your node_modules tree (this apparently doesn't work for Berry / Yarn 2 though per #688 ).

You've currently overridden external with rollup-plugin-peer-deps-external, but that plugin will include "module paths" like 'three/examples/...', so it should end up bundling those.

I'd try leaving all the plugins as is and just monkey-patching externals a tiny bit:

module.exports = {
  rollup(config) {
    if (config.output.format === 'umd') {
      const origExternals = config.external
      config.external = (id) => {
        // bundle in ThreeJS plugins
        if (id.startsWith('three/examples/')) {
          return false;
        }

        return origExternal(id);
      }
    }
  }
}

Notice that the changes here are additive and are not replacing config.

I'm not sure if you'll need to modify commonjs or globals on top of that, but start from there and see if that works. I believe the jsm path is all ESM, so you shouldn't need to change anything with commonjs (it doesn't need converting from CJS to ESM as it's already ESM). You might need to add Three to output.globals as well, i.e. in the 'umd' block, add config.output.globals['three'] = 'THREE'.

@agilgur5 agilgur5 added the problem: stale Issue has not been responded to in some time label Oct 16, 2020
@agilgur5
Copy link
Collaborator

agilgur5 commented Oct 22, 2020

While I spent quite a bit of time responding, OP has not followed up... Closing as stale

@d-w-d
Copy link
Author

d-w-d commented May 18, 2021

Sorry -- been busy and not able to get back to this. Thanks very much for your responses -- they were very helpful. In particular, I found that your module.exports = { ... } suggestion worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case problem: stale Issue has not been responded to in some time
Projects
None yet
Development

No branches or pull requests

2 participants