# Bundle ESM & CommonJS JavaScript into a Theme Component

**URL:** https://meta.discourse.org/t/bundle-esm-commonjs-javascript-into-a-theme-component/147186
**Category:** Development
**Created:** [April 7, 2020, 9:35pm UTC](https://meta.discourse.org/t/bundle-esm-commonjs-javascript-into-a-theme-component/147186 "2020-04-07T21:35:16Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![balupton](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/balupton/32/255461_2.png) [@balupton](https://meta.discourse.org/u/balupton)
#### Post date: [April 7, 2020, 9:35pm UTC](https://meta.discourse.org/t/bundle-esm-commonjs-javascript-into-a-theme-component/147186/1 "2020-04-07T21:35:17Z")

</div>

I recently published the theme component:

> [@YouTube Timestamps Component](https://meta.discourse.org/t/youtube-timestamps-component/147091):
>
> Converts timestamps within a post, to timestamp hyperlinks to the post’s (otherwise the topic’s) associated YouTube video. [https://github.com/bevry/discourse-component-youtubetimestamps](https://github.com/bevry/discourse-component-youtubetimestamps)See it in action here [Maps of Meaning #9 - #2 by balupton - Study Notes - Bevry's Discourse](https://discuss.bevry.me/t/maps-of-meaning-9/31/2?u=balupton) (has things like 5:1 , 11:1 that are correctly not timestamped) [Maps of Meaning #8 - #2 by balupton - Study Notes - Bevry's Discourse](https://discuss.bevry.me/t/maps-of-meaning-8/30/2?u=balupton) (has a link to a referenced youtube video inside the notes, hence usage of # my n…

Which does an ESM import of the npm package [extract-timestmap](https://github.com/bevry/extract-timestamp), which was scaffolded using [boundation](https://github.com/bevry/boundation) which generates a CommonJS edition for Node.js, and a ESM edition for browsers.

The theme component javascript `source/index.js` imports the dependency `extract-timestamp` like so:

> <https://github.com/bevry/discourse-component-youtubetimestamps/blob/34f5def462f44e35e7f3a7bb1dc9b95e800180db/source/index.js#L1-L5>

Which uses this `build.bash` file to turn the `source/index.js` file that contains our theme component logic, into a `common/header.html` for discourse:

> <https://github.com/bevry/discourse-component-youtubetimestamps/blob/34f5def462f44e35e7f3a7bb1dc9b95e800180db/build.bash>

Which is run by doing `bash ./build.bash` or if you are using a npm scripts workflow, via `npm run build` with:

> <https://github.com/bevry/discourse-component-youtubetimestamps/blob/34f5def462f44e35e7f3a7bb1dc9b95e800180db/package.json#L7>

Which results in a `common/header.html` file that is packaged into a single file (bundling the imports from earlier):

> <https://github.com/bevry/discourse-component-youtubetimestamps/blob/34f5def462f44e35e7f3a7bb1dc9b95e800180db/common/header.html>

This could be useful to others developing their own theme components.

I’ll probably add first-class scaffolding support for discourse theme components to [boundation](https://github.com/bevry/boundation) at a later stage, to automate this guide.
