web icon indicating copy to clipboard operation
web copied to clipboard

Polyfill loader injects modern script

Open mrrasmussendk opened this issue 4 years ago • 5 comments

Looking at https://modern-web.dev/docs/building/rollup-plugin-polyfills-loader/

the output of the polyfill loader is "modern" javascript and can therefore not be executed on IE11

Example of rollup build:

// Import rollup plugins
import html from '@web/rollup-plugin-html';
import polyfillsLoader from '@web/rollup-plugin-polyfills-loader';
import {copy} from '@web/rollup-plugin-copy';
import resolve from '@rollup/plugin-node-resolve';
import {getBabelOutputPlugin} from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import minifyHTML from 'rollup-plugin-minify-html-literals';
import summary from 'rollup-plugin-summary';

// Configure an instance of @web/rollup-plugin-html
const htmlPlugin = html({
  rootDir: './',
  flattenOutput: false,
});

export default {
  // Entry point for application build; can specify a glob to build multiple
  // HTML files for non-SPA app
  input: 'index.html',
  plugins: [
    htmlPlugin,
    // Resolve bare module specifiers to relative paths
    resolve(),
    // Minify HTML template literals
    minifyHTML(),
    // Minify JS
    terser({
      module: true,
      warnings: true,
    }),
    // Inject polyfills into HTML (core-js, regnerator-runtime, webcoponents,
    // lit/polyfill-support) and dynamically loads modern vs. legacy builds
    polyfillsLoader({
      modernOutput: {
        name: 'modern',
      },
      // Feature detection for loading legacy bundles
      legacyOutput: {
        name: 'legacy',
        test: "!('noModule' in HTMLScriptElement.prototype)",
        type: 'systemjs',
      },
      // List of polyfills to inject (each has individual feature detection)
      polyfills: {
        webcomponents: false,
        coreJs: true,
        fetch: true,
        // Custom configuration for loading Lit's polyfill-support module,
        // required for interfacing with the webcomponents polyfills
        custom: [
          {
            name: 'webcomponent-loader',
            path: 'node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js',
            module: false,
          },
          {
            name: 'lit-polyfill-support',
            path: 'node_modules/lit/polyfill-support.js',
            test: "!('attachShadow' in Element.prototype)",
            module: false,
          },
        ],
      },
    }),
    // Print bundle summary
    summary(),
    // Optional: copy any static assets to build directory
    copy({
      patterns: ['data/**/*', 'images/**/*'],
    }),
  ],
  // Specifies two JS output configurations, modern and legacy, which the HTML plugin will
  // automatically choose between; the legacy build is compiled to ES5
  // and SystemJS modules
  output: [
    {
      // Modern JS bundles (no JS compilation, ES module output)
      format: 'esm',
      chunkFileNames: '[name]-[hash].js',
      entryFileNames: '[name]-[hash].js',
      dir: 'build',
      plugins: [htmlPlugin.api.addOutput('modern')],
    },
    {
      // Legacy JS bundles (ES5 compilation and SystemJS module output)
      format: 'esm',
      chunkFileNames: 'legacy-[name]-[hash].js',
      entryFileNames: 'legacy-[name]-[hash].js',
      dir: 'build',
      plugins: [
        htmlPlugin.api.addOutput('legacy'),
        // Uses babel to compile JS to ES5 and modules to SystemJS
        getBabelOutputPlugin({
          compact: true,
          presets: [
            [
              '@babel/preset-env',
              {
                targets: {
                  ie: '11',
                },
                modules: 'systemjs',
              },
            ],
          ],
        }),
      ],
    },
  ],
  preserveEntrySignatures: false,
};

This produces the following output:

  function polyfillsLoader() {
    function loadScript(src, type, attributes = []) {
      return new Promise(function (resolve) {
        var script = document.createElement('script');

        function onLoaded() {
          if (script.parentElement) {
            script.parentElement.removeChild(script);
          }

          resolve();
        }

        script.src = src;
        script.onload = onLoaded;
        attributes.forEach(att => {
          script.setAttribute(att.name, att.value);
        });

The issue is the arrow function and of course the attributes = [], which is not allowed in IE 11

mrrasmussendk avatar Dec 01 '21 14:12 mrrasmussendk

Hi, any news about that. Just to complete the @mrrasmussendk information, this code neither works for ie11 attributes.forEach(att => { script.setAttribute(att.name, att.value); }); is it in the roadmap to make ie11 compatibility for this?

Here, I share a tentative solution

` function polyfillsLoader() { function loadScript(src, type, attributes) { return new Promise(function (resolve) { var script = document.createElement('script');

    function onLoaded() {
      if (script.parentElement) {
        script.parentElement.removeChild(script);
      }

      resolve();
    }

    script.src = src;
    script.onload = onLoaded;
     if (attributes) {
            attributes.forEach(function (att) {
              script.setAttribute(att.name, att.value);
            });
  }

`

As a workaround, I've overridden the dist code (node_modules@web\polyfills-loader\dist\createPolyfillsLoader.js) with that and it works for me

twigy11 avatar Mar 27 '22 11:03 twigy11

@twigy11 I ran into the same issue and made the exact same changes. Are you creating a PR?

adriaanthomas avatar Apr 06 '22 08:04 adriaanthomas

Oh sorry you have: #1905.

adriaanthomas avatar Apr 06 '22 09:04 adriaanthomas

yes, @adriaanthomas . It's blocked for any test error Which I couldn't reproduce in my local environment ( I currently pass all tests). Meanwhile, I'm using the workaround that I've posted. So, I'm waiting for any idea or answer about the block

twigy11 avatar Apr 06 '22 12:04 twigy11

@adriaanthomas the fix was included in the 1.3.2 version

twigy11 avatar Apr 20 '22 09:04 twigy11

Fixed by #1926

web-padawan avatar Oct 20 '22 10:10 web-padawan