Isomorphic

Code Splitting

for the Future of Web Development

Lukas Taegert-Atkinson

About myself

  • Rollup contributor since Jul 2017
  • Acting maintainer and core
    developer since Nov 2017
  • ❤️ tree-shaking and
    static code-optimization

About RollupJS

Rollup Logo
  • Bundles and optimizes JavaScript
  • Created by Rich Harris in 2015
  • Used by React, Vue, Ember, Angular,
    D3, Jest, Prettier, Bloomberg…
  • Core part of StencilJS

1

Modern Web

Development

Web-development in 2009

<script src="jquery.js"></script>
<script src="index.js"></script>

Web-development in 2019

ℹ 「wds」: Project is running at https://localhost:8080/
Version: webpack 4.35.0
Time: 24334ms
    ...
    + 1388 hidden modules
ℹ 「wdm」: Compiled successfully.

What happened? Projects got bigger.
People do not like big files.

But isn't there a module system now? Jup.

Supported by all major browsers? Possibly.

But couldn't I just use these modules…

Make Web-Development fun again

Today

Heavily based on create-es-react-app by Luke Jackson,

featuring

es-react, csz and servor by Luke Jackson,
htm by Jason Miller

Limitations

  • Libraries need to be ES modules
    ☞ Make PRs, create forks
  • Imports need to be relative
    ☞ Use import maps in development
    (chrome://flags → All experimental built-in modules)
    <script type="importmap">{"imports": {
        "es-react": "./node_modules/es-react/index.js"
      }}</script>

2

Isomorphic Bundling and

Code Splitting

Rollup code-splitting

input: [
  "Entry A",
  "Entry B"
]
or
input: {
  nameA: "Entry A",
  nameB: "Entry B"
}
Assign the same color (random hash) to each direct dependency of an entry module.
Mix colors (XOR hashes) if necessary.
Merge the modules in each chunk.

Each chunk is still a module.

How is this "isomorphic"?

No added wrappers, there is a 1-to-1 equivalence
between relevant bindings

You can bundle it again for the same output.

Contrast "traditional" code-splitting

Modules are wrapped in functions in tables in each chunk.

Only the runtime knows how to load each module.

Plugin support

Supporting legacy browsers

  • Polyfill dynamic import for ES6+ browsers via dynamicImportFunction option
  • Use SystemJS/AMD format for older browsers

3

Next steps for the

Future

Improved dynamic import code-splitting

Today: Dynamic imports are regular entry points

Future: Take already loaded modules into account

Timeframe: Soon!

Statement-level code-splitting

entry-a.js
import {x} from './lib.js'
console.log(x)
entry-b.js
import {y} from './lib.js'
console.log(y)
lib.js
console.log('Hello')
export const x = 1
export const y = 2
entry-a.js
import './chunk.js'
const x = 1 console.log(x)
entry-b.js
import './chunk.js'
const y = 2 console.log(y)
chunk.js
console.log('Hello')

Timeframe: Remote future

To make this (and more) possible, we need

You

  • Find bugs, fix bugs
  • Improve documentation
  • Create plugins, maintain plugins
  • Drive discussions to shape the future

What you may have

Learned

  • You do not need a build step
  • Code-splitting does not need a runtime
  • Rollup needs you

Thank you

Lukas Taegert-Atkinson

+

Code: github.com/lukastaegert/isomorphic-code-splitting
Slides: lukastaegert.github.io/isomorphic-code-splitting