Svelte3, Rollup and Babel7
Svelte3 rocks. Please check it out if you haven't yet!
Transpiling
After cloning the REPL and initialising your Svelte3 project; one thing that you don't seem to get is transpiling.
When using VueCLI, for example, transpiling comes as standard.
I am running an experiment to see how to convert a Vue2 project over to Svelte3 for learning purposes, but I found that I couldn't get transpiling with Babel working easily.
Issues
After following the tutorials/documentation for adding the rollup-plugin-babel
, @babel/core
, @babel/preset-env
packages, and setting up everything as described; I simply found that it hadn't transpiled my bundle.js
as I expected.
After some time messing around, and being new to svelte/rollup/babel, I figured out that it was in-fact transpiling some code, but not the svelte/imported module code.
Reason
By what I can tell, the reason I was not getting the expected results is because the documentation or tutorials for these Svelte/Rollup/Babel are not sufficiently up-to-date in order to get it working correctly. All the tools have recently gone through major updates. The main issues were surrounding the .babelrc
and the rollup.config.js
.
Resolution
I discovered a couple of steps needed to get transpiling down to ie9
working (or you may use a es2015
preset instead).
1. Install the dependencies
yarn add --dev @babel/core @babel/preset-env rollup-plugin-babel
2. Create a babel.config.js
file in root
module.exports = function (api) {
api.cache(true);
const presets = [[ "@babel/env", { "targets": "ie 9" } ]];
return { presets }
}
This is based on the documentation as it appears by using the default .babelrc
file, each imported module (including Svelte3) will have it's own Babel config. This is what prevents transpiling the Svelte code.
3. Add the Babel plugin to rollup.config.js
Firstly import babel;
import babel from 'rollup-plugin-babel';
then add the babel()
plugin after the svelte()
plugin;
babel({
extensions: [ ".js", ".mjs", ".html", ".svelte" ]
})
A key part of this config, is the .mjs
and .svelte
values in the extensions
property. Inside the Svelte3 package; a lot of the compiler is written in .mjs
, and your project's Svelte code is likely written in .svelte
components. Both of these are not handled by Babel by default.
Another key part is removing the exclude: 'node_modules/**'
configuration. This is because we need to transpile the code that comes from the Svelte3 compiler.
Success
After these steps, your bundle.js
or whatever you've called it should be completely transpiled down to the environment you've specified in the babel.config.js
.
Just Code
If you just came here for the code reference; here it is;
Package.json
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"npm-run-all": "^4.1.5",
"rollup": "^1.10.1",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-node-resolve": "^5.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^4.0.4",
"sirv-cli": "^0.4.0",
"svelte": "^3.0.0"
}
rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file — better for performance
css: css => {
css.write('public/bundle.css');
}
}),
babel({
extensions: [ ".js", ".mjs", ".html", ".svelte" ]
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration —
// consult the documentation for details:
// https://github.com/rollup/rollup-plugin-commonjs
resolve(),
commonjs(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
babel.config.js
module.exports = function (api) {
api.cache(true);
const presets = [
[ "@babel/env", { "targets": "ie 9" } ]
];
return {
presets
}
}