Reputation: 17067
I wrote a library of elements, and want to make sure designers can just add the right source file to their HTML pages to start using it. I am creating a bundle using rollup (to roll it up to one file) and babel (to make sure any browser can use it).
My rollup.conf
is pretty simple:
import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import minify from 'rollup-plugin-babel-minify'
module.exports = [
// IIFE
{
input: './tpe.js',
output: {
file: 'distr/tpe.js', // IIFE ONE FILE
format: 'iife'
},
plugins: [resolve({}), babel({})]
},
{
input: './themes/material/material.js',
output: {
file: 'distr/material.js', // IIFE ONE FILE
format: 'iife'
},
plugins: [resolve({}), minify({})]
}
]
Note that ./tpe.js
contains a long list of imports:
import './ee-autocomplete-input-spans.js'
import './ee-autocomplete-item-country.js'
import './ee-autocomplete-item-email.js'
import './ee-autocomplete-item-li.js'
import './ee-autocomplete.js'
import './ee-drawer.js'
import './ee-fab.js'
import './ee-header.js'
import './ee-nav-bar.js'
import './ee-network.js'
import './ee-snack-bar.js'
import './ee-tabs.js'
...
My babel.conf.js
is even simpler:
module.exports = function (api) {
api.cache(true)
const presets = [
[
'@babel/env', {
modules: false,
exclude: [],
targets: {
ie: "9"
}
}
]
]
const plugins = []
return {
presets,
plugins
}
This is all fine, except that I have to ask my users to do this:
<script src="https://unpkg.com/@babel/polyfill/dist/polyfill.min.js"></script>
<script src="./distr/material.js"></script>
<script src="./distr/tpe.js"></script>
<nn-input-text id="input" name="aName"></nn-input-text>
Without that polyfill.min.js, I get the dreaded regeneratorRuntime is not defined
.
I spent hours, and hours, and hours trying to make sure that I don't need to ask users to have that polyfill.min.js
.
To "fix" the problem, I added this to my ./tpe.js:
import 'regenerator-runtime/runtime'
import './ee-autocomplete-input-spans.js'
import './ee-autocomplete-item-country.js'
import './ee-autocomplete-item-email.js'
import './ee-autocomplete-item-li.js'
This actually allows me to have just this:
<script src="./distr/material.js"></script>
<script src="./distr/tpe.js"></script>
<nn-input-text id="input" name="aName"></nn-input-text>
QUESTIONS:
Babel is compiling things in node_modules, which in my case is exactly lit-html and lit-element (both ES6 source). I had problems at the beginning where lit-element (in node_modules) didn't compile. However, the problem disappeared and I don't know how/why.
Is regenerator-runtime/runtime
the ONLY thing I will ever need to polyfill? I am targeting IE9 after all...
Is there a better way to add regenerator-runtime/runtime
without having it in the includes in tpe.js?
I read about "corejs" being important is it provides more polyfills. However, adding this
useBuiltIns: "usage",
corejs: 3
Results in a lot of warnings. And then if I add an exclude in rollup.conf.js
like this:
plugins: [resolve({}), babel({exclude: [/\/core-js\//]}), minify({})]
Things compile, but the result doesn't work (Uncaught SyntaxError: Cannot use import statement outside a module
).
If I instead do:
useBuiltIns: "entry",
corejs: 3
I don't need the "exclude", but it doesn't seem to do anything. Do I actually need the corejs polyfills?
Upvotes: 3
Views: 1544
Reputation: 18205
I saw the Github issue you opened and linked to this post.
I have also been trying to diagnose this setup and the problems I've run into trying to configure it.
Checkout this recommended config on the rollup-plugin-babel repo.
I was running into the same issue with regeneratorRuntime is not defined
and couldn't figure out why the polyfills weren't being loaded as I hoped/expected.
The key seems to be that 3 plugins are required for this use-case.
// We need all 3 of these to end up with the 'usage'-based babel polyfills
import babel from "rollup-plugin-babel";
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
export default [
{
input: "src/index.js",
output: {
file: "dist/index.js",
format: "iife"
},
plugins: [
resolve(),
babel({
exclude: "node_modules/**",
presets: [
[
"@babel/preset-env",
{
corejs: 3,
modules: false,
useBuiltIns: "usage",
targets: {
ie: "11"
}
}
]
]
}),
commonjs()
]
}
];
Here's my dependenices from package.json
:
"scripts": {
"start": "rollup -c --compact --watch"
}
"dependencies": {
"core-js": "^3.3.4",
"regenerator-runtime": "^0.13.3"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/preset-env": "^7.6.3",
"rollup": "^1.26.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
}
My output dist/index.js
ends up including this assignment for regeneratorRuntime
, which wasn't there before I had all 3 of the above rollup plugins:
try {
regeneratorRuntime = runtime;
} catch (accidentalStrictMode) {
// This module should not be running in strict mode, so the above
// assignment should always work unless something is misconfigured. Just
// in case runtime.js accidentally runs in strict mode, we can escape
// strict mode using a global Function call. This could conceivably fail
// if a Content Security Policy forbids using Function, but in that case
// the proper solution is to fix the accidental strict mode problem. If
// you've misconfigured your bundler to force strict mode and applied a
// CSP to forbid Function, and you're not willing to fix either of those
// problems, please detail your unique predicament in a GitHub issue.
Function("r", "regeneratorRuntime = r")(runtime);
}
Upvotes: 1