Lit-element: Transpiling to es5 for ie11 with webpack and babel

Created on 11 Oct 2019  路  7Comments  路  Source: Polymer/lit-element

I am not able to get a working configuration for ie11 using webpack and babel.

I managed to search over the internet but every proposed solution doesn't work for me.

Probably, they do not work for many developers.

I think that this is quite an issue for the adoption of lit-element where ie11 is a requierment.

Please, provide a working configuration to bundle es5 with webpack and babel. The documentation is so vague on this point.

All 7 comments

We have documentation and configuration presets at open-wc, that should help you get started: https://open-wc.org/building/

You only need one plugin: webpack-babel-multi-target-plugin. It produces ES module bundle for modern browsers and ES5 bundle for IE11. The config by https://open-wc.org should include it.

Thank you very much.

I have an existing webpack configuration and I am a little bit confused. May you provide some help?
I am able to use custom elements and lit-html, but I cannot import LitElement.

I end up with a ie11 error:

Function.prototype.toString: 'this' is not a Function object

That is my configuration:

const path = require('path');

// Remove modules
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// Minimification
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  devServer: {
    contentBase: path.join(__dirname, 'www'),
    compress: true,
    port: 8009
  },
  entry: {
    // ...
    'uiComponents': './src/ui-components/ui-components.js',
    // ...
    'webComponentsLoaders': './src/web-components-loaders.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'www/bundles/'),
    libraryTarget: 'var',
    library: '[name]'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: ['babel-loader'],
        exclude: /node_modules/
      },
      {
        test: /\.js$/,
        exclude: /node_modules\/(?!(lit-element|lit-html))/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                targets: {
                  ie: 11,
                },
              }
            ]
          ],
          plugins: [
            ['@babel/plugin-transform-runtime']
          ],
        }
      }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js']
  }
};

web-components-loaders.js

import '@webcomponents/webcomponentsjs/webcomponents-bundle';
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';

Index.html

<script src="bundles/webComponentsLoaders.js"></script>
<script src="bundles/uiComponents.js"></script>
<script>
    window.addEventListener('WebComponentsReady', function (e) {
        uiComponents.OutdateBrowser.show();
        uiComponents.prepare();
    });
</script>
<div id="pop-up"></div>
<simple-i-element></simple-i-element>

component

import '@babel/polyfill';
import './views/simple-element';
import { LitElement, html } from 'lit-element';

class SimpleElement extends LitElement {
  render() {
    return html`<h1>Simple Element</h1>`;
  }
}
customElements.define('simple-i-element', SimpleElement);

@lp74 I see the same error when trying running on IE11 after transpilation.

cc @web-padawan @LarsDenBakker

What you might be running into is that the web component polyfills themselves load polyfills for Promise, Symbol and a few other things. This creates conflicts when also loading babel or core-js polyfills. This is a long standing issue that I really hope gets fixed at some point.

The solution is to load the babel polyfills before the web component polyfills, preferably as a script tag because they can't run in strict mode but it's possible webpack can also take care of this for you.

Thank you all and thank @LarsDenBakker for your hints.
This week I am going to try your solution. I will post my results.

BR

I've solved:

<!doctype html>
<html>
<head lang='en'>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width'>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>LIT Starter Kit</title>
    <link rel="preload" href="./index.css" as="style">
</head>
<body>

    <!-- CODE HERE --> 

    <!-- Legacy browser (IE11) -->
    <script nomodule src="webcomponents-loader.js"></script>
    <script nomodule src='index.js'></script>

    <!-- Modern browser -->
    <script type="module" src='index.es6.js'></script>

</body>
</html>
// Webpack config

const ie11BabeLoader = {
  loader: 'babel-loader',
  options: {
    presets: [
      [
        '@babel/preset-env',
        {
          modules: 'false',
          targets: {
            browsers: '> 1%, IE 11, not dead',
          },
        }
      ]
    ]
  }
};

module.exports = [
  {
    mode: 'development',
    entry: {
      'index': [
        'regenerator-runtime/runtime',
        'whatwg-fetch',
        './src/index.js'
      ],
    },
    output: {
      filename: '[name].js',
      path: path.resolve(__dirname, 'build'),
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [extractCSS ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader']
        },
        {
          test: /\.less$/,
          use: [extractCSS ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'less-loader'],
        },
        {
          test: /\.l3ss$/,
          use: [
            ie11BabeLoader,
            {
              loader: 'lit-scss-loader',
              options: {
                minify: true, // defaults to false
              },
            }, 'extract-loader', 'css-loader', 'less-loader'],
        },
        {
          test: /\.(ttf|eot|woff|woff2|svg)$/,
          use: {
            loader: 'file-loader',
            options: {
              name: 'fonts/[name].[ext]',
            },
          },
        },
        {
          test: /\.js$/,
          exclude: /node_modules\/(?!(lit-html|lit-element))/,
          use: [ie11BabeLoader]
        }
      ]
    },
    resolve: {
      extensions: ['.js']
    },
    plugins: [
      new MiniCssExtractPlugin(),
      new CopyPlugin([
        { from: 'src/index.html', to: '', toType: 'dir' },
        { from: 'src/foo.json', to: '', toType: 'dir' },
        { from: 'node_modules/css-vars-ponyfill/dist/css-vars-ponyfill.min.js', to: '', toType: 'dir' },
        { from: 'node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js', to: '', toType: 'dir' },
        { from: 'node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js', to: '', toType: 'dir' },
        { from: 'node_modules/@webcomponents/webcomponentsjs/bundles', to: 'bundles', toType: 'dir' }
      ])
    ]
  },
}

Now I've got another issue that is https://github.com/Polymer/lit-html/issues/1042

Was this page helpful?
0 / 5 - 0 ratings