# Discourse-webpack: A boilerplate for developing JS-heavy Discourse components

**URL:** https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750
**Category:** Development
**Created:** [March 15, 2019, 11:03pm UTC](https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750 "2019-03-15T23:03:50Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![labofoz](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/labofoz/32/135498_2.png) [@labofoz](https://meta.discourse.org/u/labofoz)
#### Post date: [March 15, 2019, 11:03pm UTC](https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750/1 "2019-03-15T23:03:51Z")

</div>

**Edit by @david: Discourse’s theming system now has built-in support [for multiple JS files](https://meta.discourse.org/t/splitting-up-theme-javascript-into-multiple-files/119369). This webpack method is no longer required.**

* * *

Hi! So while I was [developing my **handsfree-discourse** component](https://meta.discourse.org/t/hands-free-discourse-an-accessibility-component-w-head-tracked-pointers/111546), I hit a few problems around file management. My main issue is that I needed a way to break up my code across multiple files. The other issue was that I needed to include 3rd party libraries without having to ask admins to enable CORS or trigger additional HTTP requests.

To solve these issues I made [discourse-webpack](https://github.com/BrowseHandsfree/discourse-webpack), a boilerplate to quickly scaffold JS-heavy components! Features include:

- Local dev server with live reloading
- Includes a commit script to keep your source code and compiled code in separate branches!

The rest of this topic explains how to use it and why it works. I literally just finished testing this for a few other components I’m working on, so let me know if you run into any problems or have any specific requests!

* * *

 ![](https://global.discourse-cdn.com/meta/original/3X/8/1/8145666392d1dbe51052d8732746889efdee921c.gif)

# Discourse Webpack

Quickly scaffold JavaScript-heavy components for your Discourse Community, complete with a commit script to keep your source code and build code in separate branches to help you keep shipping _fast_!

* * *

# Install

First, make sure you have [NodeJS \>= 8](https://nodejs.org/en/download/) and [git](https://git-scm.com/downloads) installed locally on your machine. Then, type each of the lines below:

```bash
# Download this repository
git clone https://github.com/browsehandsfree/discourse-webpack

# Move into the directory
cd discourse-webpack

# Install dependencies
npm install

```

You’ll then need to edit the following in `package.json`, replacing all of our links with yours. Specifically:

```js
{
  name: 'your-project',
  repository: {
    url: 'git+https://github.com/username/repo'
  },
  author: '',
  bugs: {
    url: 'https://github.com/username/repo/issues'
  },
  homepage: 'https://example.com'
}

```

Most importantly of all, make sure `repository.url` is correct and is prefaced with `git+`. When you run `npm run discourse`, it’ll commit and push to that repo.

Also, don’t forget to [set your Discourse’s](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648) `about.json`, which is located in `/src/discourse/about.json`

* * *

# Development

After `npm install`, you’ll end up with the following directory structure:

```bash
discourse-webpack
|- node_modules/ # Dependencies
|- src/ # The main source files
|--|- discourse/ # Discourse theme files
|--|--|- common/
|--|--|- desktop/
|--|--|- mobile/
|--|- main.css # The main stylesheet
|--|- main.js # The main Javascript entry
|--|- sandbox.html # Sandbox for local development
|- .gitignore
|- discourse-push.js # Special commit script
|- README.md
|- webpack.config.js # Webpack config
|- yarn.lock

```

## Command Line Scripts

Additionally, you have access to the following commands from the project root:

```bash
# Launch a dev server on localhost:8080
# - Supports livereload
# - Uses `/src/sandbox.html` to help you debug locally
npm run dev

# Compile your component into `/dist`
npm run build

# Compile your component into `/dist`
# - Then commits `/dist` into the `discourse` branch
npm run discourse

```

## How it works

Once you’ve downloaded the repo and installed dependencies it’s time to start developing! Use `npm run dev` to start a livereload server on `localhost:8080`.

Visiting that URL will load the HTML file located in `/src/sandbox.html`. This file isn’t actually used within Discourse, and is just here to help you develop your scripts locally (outside the context of Discourse).

The main webpack entry point is `/src/main.js`. From there, you can `import` other scripts and webpack will bundle everything together and inject them into the following files:

- `/src/sandbox.html`
- `/src/discourse/common/body_tag.html`

`main.js` is compiled and injected into `sandbox.html` automatically, but is manually injected inline with `body_tag.html` because of the following code:

```html
<script>
  <%= compilation.assets['main.js'].source() %>
</script>

```

If you wanted to inject your script into another template, like `after_header.html`, you would just copy that `script` tag into that template instead. This allows you to use keep the HTML and JavaScript for that template separated while developing…but concatenated when deployed!

* * *

## Compiling

When you compile with `npm run build`, what’s happening is:

- First, `/src/main.js` and dependencies are bundled
- Then, all files in `/src/discourse/` are copied over to `/dist/`
- At the same time, `main.js` is injected **inline** in any template file that contains:

```html
<script>
  <%= compilation.assets['main.js'].source() %>
</script>

```

* * *

## Deploying

When you run `npm run discourse`, the `/discourse-push.js` script is called and does the following:

- First it’ll compile, as if with `npm run build`
- Then, it’ll initialize a new git repo inside of `/dist`
- It then commits `/dist` into your projects `discourse` branch (it’ll create the branch if it doesn’t exist)

* * *

# Using the `discourse` branch

> Each of the following `/relative/urls/` are relative to your forum’s base URL, eg, [https://example.com/relative/urls/](https://example.com/relative/urls/)

## Install the component

Install your component by visiting `/admin/customize/themes` and “Import from the web” from your projects repository, eg: `https://github.com/my-awesome/discourse-component`.

Then set the branch to `discourse`. It won’t work if you leave it at `master`, since Discourse will try to load the uncompiled files (if it works at all).

 ![https://browsehandsfree.com/admin/customize/themes](https://global.discourse-cdn.com/meta/original/3X/8/e/8e0670e29e3f04c97d91e257ea4c22dedf928e05.png)

* * *

# Debugging theme specific files on your own host

- Install the [Discourse Theme CLI](https://meta.discourse.org/t/discourse-theme-cli-console-app-to-help-you-build-themes/82950)
- Log into [https://theme-creator.discourse.org](https://theme-creator.discourse.org)
- CD into this directory, then run `discourse_theme watch .`
- Use `https://theme-creator.discourse.org` as the base URL
  - Use your API key from `theme-creator`

> If you’re new to Discourse and would like to fork this project, the following reads might be helpful.
> 
> - [Beginners guide to Install Discourse on Windows 10](https://meta.discourse.org/t/beginners-guide-to-install-discourse-on-windows-10-for-development/75149)
> - [Beginners guide to using discourse themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966)
> - [Developers guide to discourse themes](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648)

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [June 3, 2019, 10:26am UTC](https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750/8 "2019-06-03T10:26:54Z")

</div>

Discourse now has native support for “JS heavy” theme components

> [@Split up theme Javascript into multiple files](https://meta.discourse.org/t/splitting-up-theme-javascript-into-multiple-files/119369):
>
> Complex theme javascript can be split into multiple files, to keep things nicely organised. To use this functionality, simply add files to the /javascripts folder in your theme directory. These files can not be edited from the Discourse UI, so you must use the [Theme CLI](https://meta.discourse.org/t/discourse-theme-cli-console-app-to-help-you-build-themes/82950) or [source the theme from git](https://meta.discourse.org/t/how-to-source-a-theme-from-a-private-git-repository/82584). Javascript files are treated exactly the same as they are in core/plugins, so you should follow the same file/folder structure. Theme files are loaded after core/plugins, so if the filenames match,…

@labofoz I would be interested to know whether you think this is enough to avoid the need for discourse-webpack?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [January 4, 2022, 11:15am UTC](https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750/9 "2022-01-04T11:15:06Z")

</div>



---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [January 13, 2022, 7:59pm UTC](https://meta.discourse.org/t/discourse-webpack-a-boilerplate-for-developing-js-heavy-discourse-components/111750/10 "2022-01-13T19:59:12Z")

</div>


