Skip to main content

JS modules

This guide covers using JS modules in your bud.js app.

Importing modules

You can import JS modules using the import keyword.

src/scripts/app.js
import slider from '@src/scripts/slider.js'

slider()

Exporting modules

Likewise, you can export modules to make them available for import elsewhere.

src/scripts/slider.js
export default function slider() {
console.log('sliding!')
}

Importing third-party modules

You can import third-party modules using the import keyword. You don't need to include node_modules/ in the import statement.

src/scripts/app.js
import {slider} from 'example-slider-lib'

slider()

Dynamic imports

You can import modules dynamically using the import() function.

src/scripts/app.js
const app = async () => {
const {slider} = await import('example-slider-lib')
slider()
}

app()

Importing css

You can import css using the import keyword.

src/scripts/app.js
import '@src/styles/app.css'

This is essentially the same as adding the css file to the bud.entry call in your bud.config.js file. But, when considered alongside dynamic imports it is much more powerful.

Conditional css

This demo illustrates conditionally loading CSS based on the presence of a .slider element on the page:

The app.js file imports the slider.js module when a .slider element is present on the page.

const app = async () => {
if (document.querySelector('.slider')) {
const {slider} = await import('./slider.js')
slider()
}
}

app()

CSS modules

By naming a css file with the .module.css extension, you can import it as a JS module and use it as a CSS module.

src/scripts/app.js
import styles from '@src/styles/app.module.css'
document.body.classList.add(styles.body)
src/styles/app.module.css
.body {
background: black;
}

When this is compiled, the styles object will contain a body property with a unique class name. This class name will be added to the body element when the script executes.

<body class="body_1j2k3l"></body>

It's a very nice way to avoid class name collisions.

Importing data

You can use the import keyword to import a variety of data formats:

json

src/scripts/app.js
import data from '@src/data.json'
console.log(data.propertyName)

yml

src/scripts/app.js
import data from '@src/data.yml'
console.log(data.propertyName)

toml

src/scripts/app.js
import data from '@src/data.toml'
console.log(data.propertyName)

Importing markup

html

src/scripts/app.js
import html from '@src/data.html'
console.log(html)

markdown

Will be imported as HTML:

src/scripts/app.js
import html from '@src/data.md'
console.log(html)

Transpiling

You have a choice of transpilers for your JS modules. By default bud.js does not include any transpilation.

Our recommended extension is @roots/bud-swc.

SWC

@roots/bud-swc is a swc extension for bud.js.

npm install @roots/bud-swc --save-dev

It is a very fast and modern transpiler. The extension supports JavaScript and TypeScript with zero configuration.

Babel

@roots/bud-babel is a babel extension for bud.js.

npm install @roots/bud-babel --save-dev

It is a very popular transpiler. It is also very configurable.

TypeScript

@roots/bud-typescript is a typescript extension for bud.js.

npm install @roots/bud-typescript --save-dev

It is a very popular transpiler. The extension supports JavaScript and TypeScript with zero configuration.

ESBuild

@roots/bud-esbuild is a esbuild extension for bud.js.

npm install @roots/bud-esbuild --save-dev

It is a very fast and modern transpiler. The extension supports JavaScript and TypeScript with zero configuration. This extension should be considered experimental.

Framework support

React

You can add React support to your project by installing the @roots/bud-react extension.

npm install @roots/bud-react --save-dev

This extension is compatible with any of the transpilers mentioned above. A transpiler is required to use React.

Vue

You can add Vue support to your project by installing the @roots/bud-vue extension.

npm install @roots/bud-vue --save-dev

By default the extension comes configured to use with Vue 3 SFCs. If you want to use Vue 2 refer to the extension docs.

Hot module reloading

Here is a quick example of how to enable hot module reloading in your application entrypoint:

src/scripts/app.js
const app = () => console.log(`foo`)

app()

import.meta.webpackHot?.accept(console.error)

You will need to refer to the webpack documentation for hot module reloading for more information.