Isomorphic + Rollup + Package.json
Published: 2020-10-22 14:41:46

---
title: Isomorphic + Rollup + Package.json
published: true
description: Transpil/Compile once for node, browsers in raw, es, and umd formats using rollup
tags: 
//cover_image: https://direct_url_to_image.jpg
---

# Isomorphic + Rollup + Package.json

It took me a while to piece this all together, so I'm mainly posting these notes here for myself as I go along. 

We want same code for nodejs and the browser, so in package.json we set: 
```json
// package.json
...
"main": "dist/index.js",
"browser": "lib/index.browser.js"
...
```

But maybe we want both ES and UMD modules available to the browser user, so we break browser out:
```json
// package.json -  browser expanded
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "browser":{ 
    "dist/index.js": "dist/index.browser.js",
    "dist/index.esm.js": "dist/index.browser.esm.js"
  },
``` 

Now, depending on how the user imports the package, will determine what file they get. If they use `index.js` from nodejs the user will get `dist/index.js` but if they use `index.js` from the browser they will get `dist/index.browser.js`!

### Make the files

We can use Rollupjs to make these files

```js
// rollup.config.js
...
import pkg from './package.json'
...
export default [
	// browser-friendly builds
	{
		input: 'src/main.js',
		output: [{
			name: 'myPkgName',
			file: pkg.browser['dist/index.js'], // from package.json
			format: 'umd'
		},
		{
			file: pkg.browser['dist/index.esm.js'], // from package.json
			format: 'es'
		}]
		plugins: [
			resolve(), // so Rollup can bundle modules
			babel({
				exclude: ['node_modules/**']
			}),
			commonjs(), // so Rollup can convert to ES module
		]
	},

	// CommonJS (for Node) and ES module (for bundlers) build.
	// (We could have three entries in the configuration array
	// instead of two, but it's quicker to generate multiple
	// builds from a single configuration where possible, using
	// an array for the `output` option, where we can specify 
	// `file` and `format` for each target)
	{
		input: 'src/main.js',
		output: [
			{ file: pkg.main, format: 'cjs' }, // from package.json
			{ file: pkg.module, format: 'es' } // from package.json
		],
		plugins: [
			babel({
				exclude: ['node_modules/**']
			})
		]
	}
];
```
## Use the ES Module

Now that you have an ES module, you can import it into your code

```js
import NamedExport from 'myCoolModule'
```

Bundle your code (again) with Rollup in the same way, perhaps using a front end framework like Svelte.

```js
// bundled output from a framework, like Svelte
build/bundle.js
```

Now that you have all these modules, and they are bundled into the code, they can also be used for cool things like code-splitting and dynamic imports.

```html
// index.html
<!-- This standard way only works if the browser 
is modern and supports dynamic imports -->
<script defer type="module" src='/build/main.js'></script>  	
```

## Dynamic Import an ES module in any browser
Use dimport:

```html
<!-- https://www.npmjs.com/package/dimport -->
<script defer type="module" src="https://unpkg.com/dimport?module"
data-main="/build/main.js"></script>

<script defer type="nomodule" src="https://unpkg.com/dimport/nomodule" 
data-main="/build/main.js"></script> 

```
Refs:
[dimport](https://github.com/lukeed/dimport)
[Dynamic Imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports)
[Svelte Code Splitting](https://github.com/rixo/svelte-template-hot/tree/example-code-splitting)
[Svelte Code Splitting without Sapper](https://stackoverflow.com/questions/60024414/how-to-do-code-splitting-using-svelte-without-sapper)
[Code Splitting Routify](https://levelup.gitconnected.com/code-splitting-in-svelte-js-routify-7de5fe919f61)
[Target based Dependency Transpiling](https://gist.github.com/ncochard/6cce17272a069fdb4ac92569d85508f4)
[Package.json Browsr Swithcing](https://github.com/rollup/rollup-plugin-node-resolve/issues/8#issuecomment-257323750)
[Pkg.json Browser Tests](https://github.com/stereobooster/main-module-browser-test)
[Rollup Config: Multi-inputs](https://github.com/rollup/rollup-plugin-babel/issues/312#issuecomment-520543628)
[Rollup Config: babel](https://github.com/rollup/rollup-starter-lib/blob/babel/rollup.config.js)