@open-wc/building-rollup
Default configuration for working with rollup
Last updated 17 hours ago by d4kmor .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install @open-wc/building-rollup 
SYNC missed versions from official npm registry.

Rollup

Part of Open Web Components

Open Web Components provides a set of defaults, recommendations and tools to help facilitate your web component project. Our recommendations include: developing, linting, testing, building, tooling, demoing, publishing and automating.

CircleCI BrowserStack Status Renovate enabled

Configuration

Rollup configuration to help you get started building modern web applications. You write modern javascript using the latest browser features, rollup will optimize your code for production ensure it runs on all supported browsers.

The input for rollup is the same index.html you use for development. Any module scripts in your index are run through rollup and your index is updated with the output from rollup.

Setup

New project

npm init @open-wc

Existing project

npm init @open-wc
# Upgrade > Building > Rollup

Manual setup

  1. Install the required dependencies:
npm i -D @open-wc/building-rollup rollup rimraf es-dev-server
  1. Create a rollup.config.js file and pass in your app's index.html:
import { createDefaultConfig } from '@open-wc/building-rollup';

// if you need to support IE11 use `createCompatibilityConfig` instead.
// import { createCompatibilityConfig } from '@open-wc/building-rollup';
// export default createCompatibilityConfig({ input: './index.html' });

export default createDefaultConfig({ input: './index.html' });
  1. Create an index.html:
<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <my-app></my-app>

    <script type="module" src="./src/my-app.js"></script>
  </body>
</html>

We use rollup-plugin-index-html which takes your index.html as input for rollup. It scans for any <script type="module" src="..."> and sends them to rollup for bundling, and outputs your index.html in the output directory.

  1. Add the following commands to your package.json:
{
  "scripts": {
    "build": "rimraf dist && rollup -c rollup.config.js",
    "start:build": "es-dev-server --app-index dist/index.html --open"
  }
}
  • start runs your app for development, reloading on file changes
  • start:build runs your app after it has been built using the build command
  • build builds your app and outputs it in your dist directory

Supporting legacy browsers

createDefaultConfig works for browsers which support es modules. If you need to support older browsers such as IE11 you need to use our createCompatibilityConfig in your rollup.config.js:

import { createCompatibilityConfig } from '@open-wc/building-rollup';

export default createCompatibilityConfig({ input: './index.html' });

In addition to outputting a regular build of your app, it outputs a legacy build which is compatible with older browsers down to IE11.

At runtime we determine which version of your app should be loaded, so that legacy browsers don't force you to ship more and slower code to most users on modern browsers.

Config features

createDefaultConfig:

  • compatible with browsers which support es modules
  • babel transform based on browser support (no es5 for all browsers)
  • load polyfills when needed:
    • dynamic import
    • webcomponents
  • resolve bare imports ( import { html } from 'lit-html' )
  • preserve import.meta.url value from before bundling
  • minify + treeshake js
  • minify html and css in template literals

createCompatibilityConfig:

  • Two build outputs:

    • Modern build:

      • es modules
      • compatible with browsers which support es modules
      • babel transform based on browser support (no es5 for all browsers)
    • Legacy build:

      • systemjs modules
      • compatible down to IE11
      • babel transform down to IE11 (es5)
      • core js polyfills (Promise, Symbol, String.prototype.includes etc.)
    • Both:

      • resolve bare imports ( import { html } from 'lit-html' )
      • preserve import.meta.url value from before bundling
      • load polyfills when needed:
        • dynamic import
        • webcomponents
        • fetch
      • minify + treeshake js
      • minify html and css in template literals

Adjusting browser support for the modern build

The legacy build targets IE11, which is the earliest browser supported by the webcomponents polyfill. For the modern build we target the 2 most recent versions of the major browsers (chrome, firefox, safari and edge).

You can adjust this by adding a browserslist configuration. For example by adding a .browserslistrc file to your project, or adding an entry to your package.json. See the browserslist documentation for more information.

Warning: you should not add IE11 or other very early browsers as a target in your browserslist, as it would result in a broken modern build because it makes some assumptions around browser support. Use the --legacy flag for legacy builds.

Customizing the babel config

You can define your own babel plugins by adding a .babelrc or babel.config.js to your project. See babeljs config for more information.

For example to add support for class properties:

{
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

Extending the rollup config

A rollup config is just a plain object. It's easy to extend it using javascript:

import { createDefaultConfig } from '@open-wc/building-rollup';

const config = createDefaultConfig({ input: './index.html' });

export default {
  ...config,
  output: {
    ...config.output,
    sourcemap: false,
  },
  plugins: [...config.plugins, myAwesomePlugin()],
};

If you use createCompatibilityConfig, it is actually an array of configs so that rollup outputs a modern and a legacy build. Simply map over the array to adjust both configs:

import { createCompatibilityConfig } from '@open-wc/building-rollup';

const configs = createCompatibilityConfig({ input: './index.html' });

export default configs.map(config => ({
  ...config,
  output: {
    ...config.output,
    sourcemap: false,
  },
  plugins: [...config.plugins, myAwesomePlugin()],
}));

Common extensions

::: warning Some extensions or plugins add non-native or experimental features to your code. This can be bad for the maintenance of your code in the long term, we therefore don't recommend it unless you know what you're doing. :::

Customizing index.html output

If you need to customize the output of your index.html you can create a basic config object with createDefaultConfig, and use deepmerge to override and apply your customized options to rollup-plugin-index-html:

import { createDefaultConfig } from '@open-wc/building-rollup';
import { indexHTMLPlugin } from 'rollup-plugin-index-html';
import deepmerge from 'deepmerge';

const basicConfig = createDefaultConfig({
  input: './index.html',
  plugins: {
    indexHTML: false,
  },
});

export default deepmerge(basicConfig, {
  plugins: [
    indexHTMLPlugin({
      polyfills: {
        fetch: false,
        intersectionObserver: true,
      },
    }),
  ],
});

See the plugin docs for all options.

non index.html entrypoint

By default we look for an index.html as entrypoint. If want to use regular entrypoints you will need to provide your index.html for output manually:

import { createDefaultConfig } from '@open-wc/building-rollup';
import { indexHTMLPlugin } from 'rollup-plugin-index-html';
import deepmerge from 'deepmerge';

const basicConfig = createDefaultConfig({
  input: './my-app.js',
  plugins: {
    indexHTML: false,
  },
});

export default merge(basicConfig, {
  plugins: [
    indexHTMLPlugin({
      indexHTML: `
        <html>
          <head></head>
          <body></body>
        </html>
      `,

      // from file
      indexHTML: fs.readFileSync('/path/to/index.html', 'utf-8'),

      // other options:
      polyfills: {
        dynamicImport: true,
        webcomponents: true,
      },
    }),
  ],
});

Resolve commonjs modules

CommonJS is the module format for NodeJS, and not suitable for the browser. Rollup only handles es modules by default, but sometimes it's necessary to be able to import a dependency. To do this, you can add rollup-plugin-commonjs:

import { createCompatibilityConfig } from '@open-wc/building-rollup';
import commonjs from 'rollup-plugin-commonjs';

const configs = createCompatibilityConfig({ input: './index.html' });

// map if you use an array of configs, otherwise just extend the config
export default configs.map(config => ({
  ...config,
  plugins: [...config.plugins, commonjs()],
}));

Copy assets

Web apps often include assets such as CSS files and images. These are not part of your regular dependency graph (see above), so they need to be copied into the build directory. Other files you might need to copy this way are e.g. fonts, JSON files, sound or video files, and HTML files (other than the index.html referenced in the input option) etc.

Rollup-plugin-cpy is a plugin that can be used, but there are other options, too.

import cpy from 'rollup-plugin-cpy';
import { createCompatibilityConfig } from '@open-wc/building-rollup';

const config = createCompatibilityConfig({
  input: './index.html',
});

// if you use an array of configs, you don't need the copy task to be executed for both builds.
// we can add the plugin only to the first rollup config:
export default [
  // add plugin to the first config
  {
    ...config[0],
    plugins: [
      ...config[0].plugins,
      cpy({
        // copy over all images files
        files: ['**/*.png'],
        dest: 'dist',
        options: {
          // parents makes sure to preserve the original folder structure
          parents: true,
        },
      }),
    ],
  },

  // leave the second config untouched
  config[1],
];

Support typescript

To import a typescript file, use the .ts extension in your index.html:

<html>
  <head></head>
  <body>
    <my-app></my-app>
    <script type="module" src="./src/my-app.ts"></script>
  </body>
</html>

Make sure you set your tsconfig.json target and module fields to ESNext. This way tsc, the typescript compiler, won't do any compilation so that a plugin can take care of it.

Within rollup there are two options to add typescript support.

1. Babel

We recommend using the babel typescript plugin. Add it to your babel config file (.babelrc or babel.config.js):

{
  "presets": ["@babel/preset-typescript"]
}

You also need to specify .ts in the extensions option, for babel and node to properly recognize ts files:

const configs = createDefaultConfig({
  input: './index.html',
  extensions: ['.js', '.mjs', '.ts'],
});

(keep .js in there, since node will want to resolve javascript files in node_modules)

This is the fastest method, as it strips away types during babel transformation of your code. It will not perform any type checking though. We recommend setting up the type checking as part of your linting setup, so that you don't need to run the typechecker during development for faster builds.

2. Plugin

It is also possible to add the rollup typescript plugin, which does typechecking and compiling for you:

import typescript from 'rollup-plugin-typescript2';
import { createCompatibilityConfig } from '@open-wc/building-rollup';

const configs = createCompatibilityConfig({
  input: './index.html',
});

export default configs.map(config => ({
  ...config,
  plugins: [...config.plugins, typescript()],
}));

Disable typescript compilation

We already mentioned this above, but this is really important: Make sure to prevent any compilation done by the typescript compiler (tsc). If you use one of the options above, you put babel or rollup in charge of the compilation of typescript. In no case do you want multiple compilers to interfere with each other.

You can do this by setting the following options in tsconfig.json:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext"
  }
}

Import CSS files in lit-html

To separate your lit-html styles in css files, you can use rollup-plugin-lit-css:

import { createCompatibilityConfig } from '@open-wc/building-rollup';
import litcss from 'rollup-plugin-lit-css';

const configs = createCompatibilityConfig({ input: './index.html' });

// map if you use an array of configs, otherwise just extend the config
export default configs.map(config => ({
  ...config,
  plugins: [...config.plugins, litcss({ include, exclude, uglify })],
}));

Progressive Web App

Making your app installable

Make sure your PWA meets the installable criteria, which you can find here. You can find a tool to generate your manifest.json here. When your app has a service worker with a fetch handler (generated by this configuration), a manifest.json, and is served over HTTPS, your app is ready to be installed.

Enabling the service worker

This configuration will by default generate a service worker for you, using rollup-plugin-workbox. The service worker will only be generated for production. To opt-in to using this service worker, you can add the following code snippet to your index.html:

<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('./sw.js');
    });
  }
</script>

Overriding the workbox config

If you want to override the default config with your own workbox configuration, you can disable the default workbox configuration by setting options.plugins.workbox to false in the options object that you pass to createDefaultConfig, and then you can override the plugins

Alternatively, you can create a workbox-config.js in the root of your project, and it will be automatically be picked up by the configuration if available. Do note that this only works for generateSW mode.

const { createDefaultConfig } = require('@open-wc/building-rollup');
const deepmerge = require('deepmerge');
const { injectManifest /* generateSW */ } = require('rollup-plugin-workbox');

const basicConfig = createDefaultConfig({
  input: './index.html',
  plugins: {
    workbox: false,
  },
});

const workboxConfig = require('./workbox-config.js');

export default merge(basicConfig, {
  plugins: [injectManifest(workboxConfig)],
});

workbox-config.js:

const path = require('path');

module.exports = {
  swDest: path.join(__dirname, 'dist', 'sw.js'),
  swSrc: path.join(__dirname, 'serviceWorker.js'),
  globDirectory: path.join(__dirname, 'dist'),
  globPatterns: ['**/*.{html,js,css}'],
};

You can find the options for configuring Workbox here.

Disabling service worker generation

To opt out of using workbox to generate a service worker, you can disabled it by overriding the options in the createDefaultConfig function:

export default createDefaultConfig({
  input: './index.html',
  plugins: {
    workbox: false,
  },
});

A note on skipWaiting

By default, the service worker generated will not call skipWaiting. The reason for this is that it becomes very painful very quickly if you're lazyloading code in your application.

If you want to add a user-friendly 'Add To Home Screen' experience, you can use the pwa-update-available web component.

<script> export default { mounted() { const editLink = document.querySelector('.edit-link a'); if (editLink) { const url = editLink.href; editLink.href = url.substr(0, url.indexOf('/master/')) + '/master/packages/building-rollup/README.md'; } } } </script>

Current Tags

  • 0.15.4                                ...           latest (17 hours ago)

130 Versions

  • 0.15.4                                ...           17 hours ago
  • 0.15.3                                ...           2 days ago
  • 0.15.2                                ...           3 days ago
  • 0.15.1                                ...           3 days ago
  • 0.15.0                                ...           3 days ago
  • 0.14.10                                ...           6 days ago
  • 0.14.9                                ...           6 days ago
  • 0.14.8                                ...           9 days ago
  • 0.14.7                                ...           11 days ago
  • 0.14.6                                ...           12 days ago
  • 0.14.5                                ...           14 days ago
  • 0.14.4                                ...           15 days ago
  • 0.14.3                                ...           18 days ago
  • 0.14.2                                ...           21 days ago
  • 0.14.1                                ...           21 days ago
  • 0.14.0                                ...           21 days ago
  • 0.13.2                                ...           22 days ago
  • 0.12.12                                ...           a month ago
  • 0.12.11                                ...           a month ago
  • 0.12.10                                ...           a month ago
  • 0.12.9                                ...           a month ago
  • 0.12.8                                ...           a month ago
  • 0.12.7                                ...           a month ago
  • 0.12.6                                ...           a month ago
  • 0.12.5                                ...           a month ago
  • 0.12.4                                ...           2 months ago
  • 0.12.3                                ...           2 months ago
  • 0.12.2                                ...           2 months ago
  • 0.12.1                                ...           2 months ago
  • 0.12.0                                ...           2 months ago
  • 0.11.3                                ...           2 months ago
  • 0.11.2                                ...           2 months ago
  • 0.11.1                                ...           2 months ago
  • 0.11.0                                ...           2 months ago
  • 0.10.1                                ...           2 months ago
  • 0.10.0                                ...           2 months ago
  • 0.9.33                                ...           2 months ago
  • 0.9.32                                ...           2 months ago
  • 0.9.31                                ...           2 months ago
  • 0.9.30                                ...           3 months ago
  • 0.9.29                                ...           3 months ago
  • 0.9.28                                ...           3 months ago
  • 0.9.27                                ...           3 months ago
  • 0.9.26                                ...           3 months ago
  • 0.9.25                                ...           3 months ago
  • 0.9.24                                ...           4 months ago
  • 0.9.23                                ...           4 months ago
  • 0.9.22                                ...           4 months ago
  • 0.9.21                                ...           4 months ago
  • 0.9.20                                ...           4 months ago
  • 0.9.19                                ...           4 months ago
  • 0.9.18                                ...           4 months ago
  • 0.9.17                                ...           4 months ago
  • 0.9.16                                ...           4 months ago
  • 0.9.15                                ...           4 months ago
  • 0.9.14                                ...           4 months ago
  • 0.9.13                                ...           4 months ago
  • 0.9.12                                ...           4 months ago
  • 0.9.11                                ...           4 months ago
  • 0.9.10                                ...           4 months ago
  • 0.9.9                                ...           4 months ago
  • 0.9.8                                ...           4 months ago
  • 0.9.7                                ...           4 months ago
  • 0.9.6                                ...           4 months ago
  • 0.9.5                                ...           4 months ago
  • 0.9.4                                ...           4 months ago
  • 0.9.3                                ...           5 months ago
  • 0.9.2                                ...           5 months ago
  • 0.9.1                                ...           5 months ago
  • 0.9.0                                ...           5 months ago
  • 0.8.12                                ...           5 months ago
  • 0.8.11                                ...           5 months ago
  • 0.8.10                                ...           5 months ago
  • 0.8.9                                ...           5 months ago
  • 0.8.8                                ...           5 months ago
  • 0.8.7                                ...           5 months ago
  • 0.8.6                                ...           5 months ago
  • 0.8.5                                ...           5 months ago
  • 0.8.4                                ...           5 months ago
  • 0.8.3                                ...           5 months ago
  • 0.8.2                                ...           5 months ago
  • 0.8.1                                ...           5 months ago
  • 0.8.0                                ...           5 months ago
  • 0.7.6                                ...           5 months ago
  • 0.7.5                                ...           5 months ago
  • 0.7.4                                ...           5 months ago
  • 0.7.3                                ...           5 months ago
  • 0.7.2                                ...           5 months ago
  • 0.7.1                                ...           5 months ago
  • 0.7.0                                ...           5 months ago
  • 0.6.3                                ...           5 months ago
  • 0.6.2                                ...           5 months ago
  • 0.6.1                                ...           6 months ago
  • 0.6.0                                ...           6 months ago
  • 0.5.7                                ...           6 months ago
  • 0.5.6                                ...           6 months ago
  • 0.5.5                                ...           6 months ago
  • 0.5.4                                ...           6 months ago
  • 0.5.3                                ...           6 months ago
  • 0.5.2                                ...           6 months ago
  • 0.5.1                                ...           6 months ago
  • 0.5.0                                ...           6 months ago
  • 0.4.7                                ...           7 months ago
  • 0.4.6                                ...           7 months ago
  • 0.4.5                                ...           7 months ago
  • 0.4.4                                ...           7 months ago
  • 0.4.3                                ...           7 months ago
  • 0.4.2                                ...           7 months ago
  • 0.4.1                                ...           7 months ago
  • 0.4.0                                ...           7 months ago
  • 0.3.3                                ...           7 months ago
  • 0.3.2                                ...           8 months ago
  • 0.3.1                                ...           8 months ago
  • 0.3.0                                ...           8 months ago
  • 0.2.4                                ...           8 months ago
  • 0.2.3                                ...           8 months ago
  • 0.2.2                                ...           8 months ago
  • 0.2.1                                ...           9 months ago
  • 0.2.0                                ...           9 months ago
  • 0.1.10                                ...           9 months ago
  • 0.1.9                                ...           9 months ago
  • 0.1.8                                ...           9 months ago
  • 0.1.7                                ...           9 months ago
  • 0.1.6                                ...           9 months ago
  • 0.1.5                                ...           9 months ago
  • 0.1.4                                ...           9 months ago
  • 0.1.3                                ...           9 months ago
  • 0.1.2                                ...           9 months ago
  • 0.1.1                                ...           9 months ago
  • 0.1.0                                ...           9 months ago

Copyright 2014 - 2016 © taobao.org |