# Differential bundling and serving

Jetpack supports differential bundling and serving. That is it can produce 2 bundles instead of just one. A modern and a legacy bundle. An appropriate bundle can then be served to each browser. This ensures that modern browsers get smaller and more efficient bundles. This also helps speed up development builds by transpiling less.

## Modern by default

By default, jetpack only compiles for modern browsers. This is the simplest way to use jetpack since you don't have to worry about how to do differential serving. You can use `jetpack/serve`, `express.static`, Nginx or CDN to serve your bundles.

You can tweak what modern browsers are targeted if you would like to support more browser's than jetpack's default by creating a custom `.browserslistrc`, e.g.:

```
>0.5%
```

```
# use browserlist's defaults
defaults
```

## Differential builds

Instead of just the default modern bundle, you can build both modern and legacy bundles using cli args:

```
jetpack build --modern --legacy
jetpack build -ml
```

Or by configuring it in your `jetpack.config.js`:

```
module.exports = {
  target: {
    modern: true,
    legacy: true
  }
}
```

To tweak what browsers are considered modern and legacy, use `.browserslistrc` with `modern` and `legacy` environments:

```
[modern]
> 10%

[legacy]
> 0.1%
```

Running `jetpack build` with legacy turned on will produce `index.html` pointing to `bundle.js` and `index.legacy.html` pointing to `bundle.legacy.js`. You will need a way to serve the right index file to each browser.

## Differential serving

Jetpack opts to not use module/no module approach due to it's 2 limitations:

1. Currently module/no module option in `@babel/preset-env` transpiles async/await into regenerator and that's not desired for modern browsers.
2. The browsers that support ES modules will eventually get old, and by using browser detection to serve the right bundle we can keep transpiling less and less over time.

To do the differential serving you can use the built in `jetpack/serve` module or the standalone [`jetpack-serve`](https://github.com/KidkArolis/jetpack-serve) package. The package is recommended in production, since that allows installing jetpack as dev dependency.

### jetpack/serve module

```js
const express = require('express')
const jetpack = require('jetpack/serve')

const app = express()

app.get('/api/data', (req, res) => {
  res.send('hello')
})

// this will work in both production and development
// in development it proxies to jetpack's dev serve
// in production it will detect if browser is modern
// or legacy and serve an appropriate entry point
app.get('*', jetpack)

app.listen(3000, function () {
  console.log('Running server on http://localhost:3000')
})
```

This is the most convenient option, but can be undesirable if you'd like to avoid shipping the entire jetpack package with all of it's dependencies (i.e. `webpack`, `swc`, `postcss`, etc.) to your production apps. To avoid that, consider installing `jetpack` as a dev dependency and using the standalone `jetpack-serve` package instead.

### jetpack-serve package

```js
const express = require('express')
const jetpack = require('jetpack-serve')

const app = express()

app.get('/api/data', (req, res) => {
  res.send('hello')
})

// this will work in both production and development
// in development it will require('jetpack/serve'), so
// you will have to have jetpack installed
// in production it will detect if browser is modern
// or legacy and serve an appropriate entry point and use
// express.static for the actual assets
app.use(jetpack())

app.listen(3000, function () {
  console.log('Running server on http://localhost:3000')
})
```

Or if you're using something other than express or want to customise the behaviour, you can use the UA regex directly:

```js
const jetpack = require('jetpack-serve')

module.exports = function handle(req, res) {
  const isModern = jetpack.regexp({ modern: true }).test(req.headers['user-agent'])
  if (isModern) {
    // serve modern
  } else {
    // serve legacy
  }
}
```

## Browsers command

To see what browsers your modern or legacy bundles will target, jetpack provides a `jetpack browsers` command:

```
$ jetpack browsers

[modern query]
> 0.5% and last 2 versions

[modern browsers]
chrome 74
edge 18
edge 17
firefox 66
firefox 60

[modern coverage globally]
77.88%
```
