moutaindwarf
moutaindwarf

Reputation: 95

Web component IE11 with Svelte

I'm struggling as I'm trying to adapt webcomponents made with Svelte for IE11. I managed to show the webcomponents in the browser but I did not manage make them fully functional.

When using Svelte transitions I get the following error:

object doesn't support property or method "__shady_native_contains" in the @webcomponents file webcomponents-sd-ce.js.

I'm using webpack with @webcomponents polyfills.

Here is my courrent webpack configuration:

const sassCssConfig = {
    test: /\.s[ac]ss$/,
    use: [
        'style-loader', 'css-loader', 'sass-loader'
    ]
}

const resolveExtensions = {
    alias: {
        svelte: path.resolve('node_modules', 'svelte')
    },
    extensions: [".mjs", ".ts", ".tsx", ".js", ".json", ".svelte"]
}

module.exports = [{
    entry: ['whatwg-fetch', '@webcomponents/custom-elements', './src/main.ts'],
    mode: 'development',
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'build'),
        libraryTarget: "window",
    },
    externals: [
        {
            bc: 'bc',
            kendo: 'kendo',
            jquery: 'jQuery'
        }
    ],
    target: ['web', 'es5'],
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /(\.m?js?$)|(\.svelte$)|(\.ts$)/,
                exclude:   /\bcore-js\b/,
                resolve: {
                    fullySpecified: false
                },
                use: [
                    // Then babel
                    {
                        loader: 'babel-loader',
                       
                        options: {
                            presets: [
                                [
                                    "@babel/preset-env",
                                    {
                                        targets: {
                                            browsers: ["ie >= 10"]
                                        },
                                        useBuiltIns: "usage",
                                        corejs: 3
                                    } // or whatever your project requires
                                ],
                                "@babel/preset-typescript",
                            ],
                            plugins: [
                                // plugin-proposal-decorators is only needed if you're using experimental decorators in TypeScript
                                // ["@babel/plugin-proposal-decorators", { legacy: true }],
                                // ["@babel/plugin-proposal-class-properties", { loose: true }],
                                ['@babel/plugin-transform-typescript', { "allowNamespaces": true }],
                                 ["@babel/plugin-transform-runtime", { regenerator: true }]
                            ],
                            sourceType: 'unambiguous'
                        }
                    } 
                ],
            },
            {
                test: /\.svelte$/,
                exclude: /node_modules/,
                
                use: {
                    loader: 'svelte-loader',
                    options: {
                        customElement: true,
                        emitCss: false,
                        preprocess: require('svelte-preprocess')({})
                    },
                }
            },
            sassCssConfig
        ],
    },
    resolve: resolveExtensions,
    plugins: [
        new CopyWebpackPlugin(
            {
                patterns: [
                    {
                        context: 'node_modules/@webcomponents/webcomponentsjs',
                        from: '**/*.js',
                        to: '.'
                    }
                ]

            }
        )

    ]
},

]

In my html file I have the following setup:

<script src="//cdn.polyfill.io/v2/polyfill.min.js"></script>
<script src="~/Scripts/svelte-webpack/build/webcomponents-loader.js"></script>
<script>
  if (!window.customElements) { document.write('<!--'); }
</script>

<script src="~/Scripts/svelte-webpack/build/custom-elements-es5-adapter.js"></script>
<!-- ! DO NOT REMOVE THIS COMMENT, WE NEED ITS CLOSING MARKER -->

<script src="~/Scripts/svelte-webpack/build/bundle.js"></script>

As as side note, in main.ts I include the following for core-js / regenerator-runtime / promise-polyfill

import "core-js/stable";
import "regenerator-runtime/runtime";
import 'promise-polyfill/src/polyfill';

Has anyone encountered anything similar? I'm grateful for any help I can get on this subject.

Upvotes: 0

Views: 1157

Answers (1)

moutaindwarf
moutaindwarf

Reputation: 95

I finally got the whole thing to work with IE11. The problem was solved by replacing the /cdn.polyfill.io/v2/polyfill.min.js file with cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/core.min.js. I can not tell what the differences are exactly, but the error is now gone.

Here is the working configuration in the head script as well as a working rollup configuration (typescript/babel/svelte/:

In the index.html file:

<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/core.min.js"></script>
<script src="~/Scripts/svelte-webpack/build/custom-elements-es5-adapter.js"></script>
<script src="~/Scripts/svelte-webpack/build/webcomponents-loader.js"></script>
<script src="~/Scripts/svelte-rollup/build/bundle.js"></script>
export default {
  input: 'src/main.ts',
  output: {
    sourcemap: true,
    format: 'iife',
    name: 'app',
    file: 'build/bundle.js'
  },
  plugins: [
   
    svelte({
      dev: !production,
      customElement: true,
      emitCss: false,
      extensions: ['.svelte'],
      preprocess: sveltePreprocessor()
    }),
    // compile to IE11 compatible ES5
    babel({
        babelHelpers: 'runtime',
      extensions: [ '.js', '.mjs', '.html', '.svelte' ],
      exclude: [ 'node_modules/@babel/**', 'node_modules/core-js/**' ],
      presets: [
        [
          '@babel/preset-env',
          {
            targets: {
              ie: '11'
            },
            useBuiltIns: 'usage',
            corejs: 3
          }
        ]
      ],
      plugins: [
        '@babel/plugin-syntax-dynamic-import',
        [
          '@babel/plugin-transform-runtime',
          {
            useESModules: true
          }
        ]
      ]
    }),

    resolve({
        browser: true,
        dedupe: ['svelte']
    }),
    commonjs(),
    typescript({ sourceMap: !production, inlineSources: !production }),

    production && terser()
  ],
  watch: {
    clearScreen: false
  }
}

Also I added following pollyfills in my ts files as imports:

import "core-js/stable";
import "regenerator-runtime/runtime";
import 'promise-polyfill/src/polyfill';

tsconfig.json

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*"],
  "exclude": ["node_modules/*"]
}

I want to add as a sidenote, than I only switched to rollup to see if there was any difference. First I got the same error as mentionned above. So the answer really is the incompatibility of the polyfill.min.js with webcomponents-sd-ce.js in IE11, and not the bundling method.

Upvotes: 2

Related Questions