How to make your Svelte 3 Cordova app work on old phones using Babel 7 and Rollup
Tags: webdev, cordova, svelte, babel
Published: 2019-08-22 00:00:00

---
date: "2019-08-22"
title: "How to make your Svelte 3 Cordova app work on old phones using Babel 7 and Rollup"
published: true
category: "cordova"
tags: "webdev, cordova, svelte, babel"
cover_image: "https://thepracticaldev.s3.amazonaws.com/i/sz9ykmm5n0hr4q96jqx6.jpg"
canonical_url: https://www.learningsomethingnew.com/how-to-make-your-svelte-3-cordova-app-work-on-old-phones-using-babel-7-and-rollup
---

When working with a relatively new framework like svelte you come across issues that more "battle tested" frameworks have solved already.
One such issue is transpiling your code to work on older browsers. This is meaningful especially for a cordova app, because it runs in a system WebView, which version depends on various factors, and is not always updated.

> I wrote more about WebView versions in the post: [should you transpile your cordova app](https://www.learningsomethingnew.com/should-you-transpile-your-cordova-app)


## What should be transpiled?

We're going to use babel of course, in order to transpile.

From the babel [docs](https://babeljs.io/docs/en/):
> Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

But which code needs to be transpiled? We need to consider two levels of transpilation:
### 1. Our app's code
If you're using ES6 and above in your app (and you should), you need to transpile that. This includes you `.svelte` files and `.js` files.

### 2. Dependencies
Your dependencies are also code that's bundled along with your app. If they were published with ES6 syntax, then they'll cause your `bundle.js` to contain untranspiled code.
By the way, here is [babel's take on external dependencies](https://github.com/rollup/rollup-plugin-babel#external-dependencies):
> Ideally, you should only be transforming your source code, rather than running all of your external dependencies through Babel – hence the exclude: 'node_modules/**'
> We encourage library authors not to distribute code that uses untranspiled ES6 features (other than modules) for this reason. Consumers of your library should not have to transpile your ES6 code, any more than they should have to transpile your CoffeeScript, ClojureScript or TypeScript.

Unfortunately, not all libraries abide by this rule. 
One such library is [axios](https://github.com/axios/axios/blob/master/UPGRADE_GUIDE.md#es6-promise-polyfill):
> Up until the 0.6.0 release ES6 Promise was being polyfilled using es6-promise. With this release, the polyfill has been removed, and you will need to supply it yourself if your environment needs it.

Another is svelte. According to this [svelte GitHub issue](https://github.com/sveltejs/svelte/issues/558), it's still a WIP to list exactly what needs transpiling / polyfills.


## The solution

The following configuration has worked for me, successfully transpiling my cordova app.

### 1. Install dependencies
First let's install the required babel packages, and the rollup plugin.
```sh
npm i -D @babel/core @babel/preset-env rollup-plugin-babel core-js
```

### 2. Configure babel
Now add the following configuration to `babel.config.js`:
```js
module.exports = function (api) {
    api.cache(true);
    const presets = [
        ["@babel/preset-env", {
            // "debug": true,
            useBuiltIns: "usage",
            corejs: 3, // or 2,
            targets: {
                browsers: "last 2 versions",
            }
        }]
    ];
    return {
        presets
    }
}
```

Notice the `browsers: "last 2 versions"` line. It's a feature of `@babel/preset-env` that makes it transpile to last 2 major versions of all browsers.
Also, the `debug` field can come in handy if you want to see exactly what files are being transpiled.

### 3. Configure rollup

Add the following babel section *at the end* of the plugins section of `rollup.config.js`, assuming you're using the same directory structure as in the [svelte cordova template](https://github.com/syonip/svelte-cordova-template):

```js
import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import replace from 'rollup-plugin-replace';
import babel from 'rollup-plugin-babel';


export default {
	...
	plugins: [
		...
		production && babel({
			exclude: [
				// 'node_modules/**',
				/\/core-js\//,
			],
			extensions: ['.svelte', '.js', '.jsx', '.es6', '.es', '.mjs', '.ts']
		}),
	]
};
```

Several things to notice here:
- The line `production && babel` is a js trick to make the babel plugin not execute in dev mode. You can turn this on or off as you please, if you're testing how the transpiled code works, it might be handy to let it run in dev mode too.
- The `exclude` section does **not** contain `node_modules`. We're transpiling our dependencies, because some of them are untranspiled. If this is not the case for you, you can ignore them, but you still need to transpile the svelte module itself.
- The `extensions` section must contain the `.svelte` extension, or else your own app's code won't go through babel.
- We **are** excluding `core-js` from transpilation, because of a [circular reference issue with rollup-plugin-babel](https://github.com/rollup/rollup-plugin-babel/issues/254)


## Credits
I've used this [post by simey.me](http://simey.me/svelte3-rollup-and-babel7/) as a basis for the configuration described here.