You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Request: provide clear example on creating non-trivial UMD bundles #898
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.
changed the title [-]Provide clear example on creating non-trivial UMD bundles[/-][+]Request: provide clear example on creating non-trivial UMD bundles[/+]on Oct 8, 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.
First, you might be able to get a library variant of TrackballControls and OrbitControls; e.g. I've used three-trackballcontrolsbefore.
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.
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'){constorigExternals=config.externalconfig.external=(id)=>{// bundle in ThreeJS pluginsif(id.startsWith('three/examples/')){returnfalse;}returnorigExternal(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'.
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.
Activity
[-]Provide clear example on creating non-trivial UMD bundles[/-][+]Request: provide clear example on creating non-trivial UMD bundles[/+]agilgur5 commentedon Oct 12, 2020
TSDX doesn't seem to have that many UMD users (it hasn't been part of the default
buildoutput 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, andcommonjsoptions (the latter being different from something like Webpack). Though in my experience,externalswere 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 surprisedOrbitControlsandTrackballControlsstill 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 commentedon Oct 12, 2020
First, you might be able to get a library variant of
TrackballControlsandOrbitControls; e.g. I've usedthree-trackballcontrolsbefore.Some unrelated comments:
reactandreact-domas deps --react-domgenerally isn't used directly in libraries though andreactis already a peerDep (that's part of the TSDX template). You probably want to havethreeas a peerDep too.--name-- there's gonna be a breaking change to that in the next breaking version due to (fix): --name shouldn't change output filenames #669agilgur5 commentedon 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-resolveandplugin-typescriptas well asplugin-typescript2. Thecommonjsversion is also incorrect. You can see TSDX'spackage.jsonfor the versions and plugins used. (I noticed you had a fix for #888 / #892 / #896, which is correct)....But you shouldn't need to
importthe plugins to override them. Perhaps you're misunderstanding how to configuretsdx.config.js-- #379 has a few examples. You've gotconfig.plugins = [ ... ]and are basically re-writing all the internal plugins instead of something likeconfig.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_modulestree (this apparently doesn't work for Berry / Yarn 2 though per #688 ).You've currently overridden
externalwithrollup-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
externalsa tiny bit:Notice that the changes here are additive and are not replacing config.
I'm not sure if you'll need to modify
commonjsorglobalson top of that, but start from there and see if that works. I believe thejsmpath is all ESM, so you shouldn't need to change anything withcommonjs(it doesn't need converting from CJS to ESM as it's already ESM). You might need to add Three tooutput.globalsas well, i.e. in the'umd'block, addconfig.output.globals['three'] = 'THREE'.agilgur5 commentedon Oct 22, 2020
While I spent quite a bit of time responding, OP has not followed up... Closing as stale
d-w-d commentedon 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.