sveltejs/svelte

Svelte applications fail to load in IE 11. Similar loading issue with the main site svelte.dev

tridattran opened this issue ยท 39 comments

image

Digging closer the error is on this line:

const identity = x => x;

I suspect I need a polyfill but there doesn't seem to be an appropriate one.
Svelte version: 3.0.0

The home page: https://svelte.dev/ gives this error:
(as of 30/04/2019)

image

IE version:

image

If you want to support IE11 you must transpile the code to syntax that it supports and add a Promise polyfill.

svelte.dev is not transpiled with IE11 in mind (e.g. => is not allowed), and I don't think any polyfills needed to make shimport work in IE11 are included either.

Should IE11 be supported for svelte.dev?

thgh commented

I would expect svelte.dev to enable the legacy build.

It does, but apparently it's not doing its job correctly. Might need to dig into some Babel stuff - which might be helpful if it means we can improve configuration in sapper-template.

However, even with that ironed out, the site uses CSS variables all over the place, which no amount of Babeling is going to help. I'm undecided whether making the site work on IE11 is an important goal.

+1 for IE11 support, it's still widely used in some corners of the globe (wish it wasn't but it is). We use a Svelte CSS variables pre-processing step in our workflow that works well.

I'm going to close this issue. As suggested above, with the correct polyfills, svelte can be made to work in IE.

For anyone interested, this is my webpack.config.js is below.

The important updates are:

  • '@webcomponents/custom-elements' to support custom elements.
  • babel loader (that also looks for .svelte files).

const mode = process.env.NODE_ENV || 'development';
const prod = mode === 'production';

module.exports = {
	entry: {
		bundle: [
			'@webcomponents/custom-elements',
			'./src/main.js'
		]
	},
	resolve: {
		extensions: ['.mjs', '.js', '.svelte', '.css']
	},
	output: {
		path: __dirname + '/public',
		filename: '[name].js',
		chunkFilename: '[name].[id].js'
	},
	module: {
		rules: [
			{
				test: /(\.m?js?$)|(\.svelte$)/,
				exclude: /\bcore-js\b/,
				use: {
				  loader: 'babel-loader',
				  options: {
					presets: [
						['@babel/preset-env', {
							targets: {
								"browsers": [
									"ie >= 10"
								]
							},
							useBuiltIns: "usage",
							corejs: 3
						}]
					],
					plugins: [
						// '@babel/plugin-proposal-class-properties',
						// '@babel/plugin-transform-shorthand-properties'

					],
					sourceType: 'unambiguous'
				  }
				}
			  },
			{
				test: /\.svelte$/,
				exclude: /node_modules/,
				use: {
					loader: 'svelte-loader',
					options: {
						emitCss: true,
						hotReload: true
					}
				}
			},
			{
				test: /\.css$/,
				use: [
					/**
					 * MiniCssExtractPlugin doesn't support HMR.
					 * For developing, use 'style-loader' instead.
					 * */
					prod ? MiniCssExtractPlugin.loader : 'style-loader',
					'css-loader'
				]
			}
		]
	},
	mode,
	plugins: [
		new MiniCssExtractPlugin({
			filename: '[name].css'
		})
	],
	devtool: prod ? false: 'source-map'
};

It does, but apparently it's not doing its job correctly. Might need to dig into some Babel stuff - which might be helpful if it means we can improve configuration in sapper-template.

However, even with that ironed out, the site uses CSS variables all over the place, which no amount of Babeling is going to help. I'm undecided whether making the site work on IE11 is an important goal.

@Conduitry Does that mean the 'legacy' compile flag is supposed to transpile ES6 features like arrow functions and such but isn't for some reason at the moment?

@mrPrateek95 I believe legacy compile flag doesn't transpile ES6 features, rather it changes the code to not use api not present in older browsers, such as dataset.
The reason there are issues like arrow functions not transpiling correctly is because babel doesn't seem to be doing its job right. It works if I use babel-cli and transpile files manually, but babel-loader with webpack seems to produce those issues.

For those working with rollup โ€“ there's also a way to do it without webpack. I had exactly the same requirement on a project. As I did not find much online, I wrote this blogpost about how I solved it. The trick is to add es6-shim or core-js for polyfilling. I recommend working with the latter (and babel). My rollup config now looks like this:

import babel from 'rollup-plugin-babel';

export default {
  โ€ฆ
  plugins: [
    โ€ฆ,
    // compile to good old IE11 compatible ES5
    babel({
      extensions: [ '.js', '.mjs', '.html', '.svelte' ],
      runtimeHelpers: true,
      exclude: [ 'node_modules/@babel/**' ],
      presets: [
        [
          '@babel/preset-env',
          {
            targets: '> 0.25%, not dead',
            useBuiltIns: 'usage',
            corejs: 3
          }
        ]
      ],
      plugins: [
        '@babel/plugin-syntax-dynamic-import',
        [
          '@babel/plugin-transform-runtime',
          {
            useESModules: true
          }
        ]
      ]
    }),
    production && terser()
  ],
  โ€ฆ
}

I acutally copied this from sapper. Make sure you add babel or bublรฉ before the terser and after the svelte-loader.

@angelozehr tried to run the app. Still I am getting some error.
image

image

@swapneshran
This is because IE 11 doesn't support Web Components Custom Elements.

You will need to add that plugin in your babel configuration.

This link should help:
https://github.com/github/babel-plugin-transform-custom-element-classes

Sorry for appending to a closed thread, but since this is the first hit that comes up when looking for IE11 and Sapper issues I thought I should post here. Sapper uses document.baseURI in goto and prefetch which isn't supported in IE11 and doesn't appear to be polyfilled by Babel or polyfill.io.

TypeError: Invalid scheme

is a hint that this might be biting you.

I found this patch which works for me when added to template.html along with the polyfill.io polyfills mentioned in Usage of shimport makes legacy support prohibitively challenging

source: webcomponents/webcomponents-platform#2

if ('baseURI' in Node.prototype === false) {
  Object.defineProperty(Node.prototype, 'baseURI', {
    get: function() {
      var base = (this.ownerDocument || this).querySelector('base');
      return (base || window.location).href;
    },
    configurable: true,
    enumerable: true
  });
}

Maybe a polyfill for this could be added to --legacy builds automatically in a future release?

You can examine the modified Sapper build I made at https://github.com/antony/sapper-ie to determine what pollyfills/rollup config you will need for IE11/Edge support for your own code.

I don't think time should be wasted making the Svelte website work in an obsolete browser (IE11) - anybody using that browser is not the target audience of the Svelte website. Lets focus on more important issues.

Thanks @antony, I'll checkout your project. While I'm happy for svelte/sapper to not consider IE a target market (who would if given a choice) I wish it were true that IE was obsolete, unfortunately that just isn't the case.

I realise global/general browser stat counters will tell you it is and if you're building a website for a tween popstar then you're probably right on the money but anyone building B2B apps, particularly if it's for big organisations or government, just don't see what you see. Here are some login stats for one of my projects for the last 6 months:

Browser Logins
IE 54,131
Chrome 46,191
Safari 17,436
Edge 13,747
Samsung Browser 4,233
Firefox 4,166

I realise that part of this thread refers specifically to the svelte website and I wholeheartedly agree that that doesn't need to support IE11, but plenty of developers like myself still do and would like to use Svelte/Sapper. Polyfills are fine, but I couldn't find one for baseURI, so I posted it here to help others.

I'm not denying the need for IE11 support. I spent weeks figuring out how to get Sapper to support it (hence the project I linked above).

Please don't confuse the terms obsolete and unused - the browser has been abandoned by Microsoft, it receives only critical security updates, it is obsolete. I'm not denying it has a userbase, especially in slow-moving corporates and B2B. Luckily we don't have to deal with those as a general rule.

I am recommending that the Svelte website doesn't support IE. However, I would encourage Svelte website support for IE if it is a way of dogfooding ongoing legacy browser support.

Finally someone articulates it very nicely...thanks @assmith! I get tired of millennials thinking that IE is dead and that it can be completely ignored.
I run a cloud-based investment recovery software service used mostly by F500 companies and almost every one of them are only allowed to run IE11. (still have users in remote warehouses who are on windows 7..)
https://medium.com/@burger.neal/the-end-of-life-of-internet-explorer-11-12736f9ff75f

So thanks for posting the help here on finding the polyfils, very helpful!

@angelozehr thanks for calling out buble. Now my dinky little website for a friend (the ppl she deals with are corporates and tradies ...) works with IE with nothing more than:

  import buble from 'rollup-plugin-buble';
  
  ...
  
  !production && livereload('public'),

  // BABEL like transpilation for Edge and IE11 browsers (splitters!)
  buble({
    objectAssign: 'Object.assign',
  }),

  production && terser()

NB: The objectAssign option is for handling spread operators.

IE support is for react and co

Hey, I had the same error in IE11 and stacked buble on top of babel. It's a bit ugly and may be pretty unperformant in larger scale but buble transpiles everything what babel doesn't. I have no clue why babel is not transpiling that but for now its working fine.

EDIT:
I am not using buble alone because of async arrow functions which buble does not suppor.

webpack.config.js
{
	test: /(\.m?js?$)|(\.svelte$)/,
	exclude: /\bcore-js\b/,
	use: [
		'buble-loader',
		'babel-loader'
	]
}

.babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

Ok the problem seems to occur when using .babelrc
Change your babel configuration to babel.config.js and tell the babel-loader to use this config.
I did it and now it's working perfectly fine with.

babel/babel#8672 (comment)

Hi @Mycl95 @tridattran

I tried with the workaround suggested in below comments link but still getting error for IE 11.

(#2621 (comment), #2621 (comment))

Sample repo https://github.com/varun-etc/sample_web_comp_ie or git clone https://github.com/varun-etc/sample_web_comp_ie.git

My webpack.config.js file.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');

const mode = process.env.NODE_ENV || 'development';

const prod = mode === 'production';

module.exports = {
	entry: {
		bundle: !prod
			? ['@webcomponents/custom-elements', './src/main.js']
			: ['@webcomponents/custom-elements', './src/components/components.module.js'],
	},
	resolve: {
		alias: {
			svelte: path.resolve('./node_modules', 'svelte'),
		},
		extensions: ['.mjs', '.js', '.svelte', '.css'],
	},
	output: !prod
		? {
				path: __dirname + '/public',
				filename: 'bundle.js',
				chunkFilename: 'bundle.[id].js',
		  }
		: {
				path: __dirname + '/lib',
				filename: 'index.js',
		  },
	module: {
		rules: [
			{
				test: /(\.m?js?$)|(\.svelte$)/,
				exclude: /\bcore-js\b/,
				  loader: 'babel-loader',
					options: {
						babelrc : false,
						configFile: path.resolve('babel.config.js'),
					},
					include: [
					  path.resolve('src'),
					  path.resolve('test'),
					  //path.resolve('node_modules/webpack-dev-server/client'),
					  //path.resolve('node_modules/@util/qcmagic')
					]
			  },		
			{
				test: /\.svelte$/,
				use: {
					loader: 'svelte-loader',
					options: {
						emitCss: true,
						hotReload: !prod,
						dev: !prod,
						customElement: true,
					},
				},
			},
			{
				test: /\.css$/,
				use: [
					/**
					 * MiniCssExtractPlugin doesn't support HMR.
					 * For developing, use 'style-loader' instead.
					 * */
					prod ? MiniCssExtractPlugin.loader : 'style-loader',
					'css-loader',
				],
			},
	        {
	          test: /\.(png|svg|jpg|gif)$/,
	          use: [
	            'file-loader',
	          ],
	        },	
		],
	},
	mode,
	plugins: [
		new MiniCssExtractPlugin({
			filename: '[name].css',
		}),
	],
	devtool: prod ? false : 'source-map',
};

bable.config.js file.

module.exports = function (api) {
	console.log("babel.config log !!!");
  api.cache(true);
  const presets = [
    [
      '@babel/preset-env',
      {
		    targets: {
      ie: 11
    }, 
        modules: false,
        useBuiltIns: 'usage'
      }
    ]
  ];
  const plugins= [
    [
      '@babel/plugin-transform-runtime', {
      corejs: 2,
      helpers: true,
      regenerator: true,
      useESModules: false
    }
    ]
  ];
  return {
    presets,
    plugins
  }
}

but still getting same error in IE 11, can somebody share sample working svelte app with webpack config & custom elements.

image

image

sno2 commented

If you want to support IE11 you must transpile the code to syntax that it supports and add a Promise polyfill.

svelte.dev is not transpiled with IE11 in mind (e.g. => is not allowed), and I don't think any polyfills needed to make shimport work in IE11 are included either.

Should IE11 be supported for svelte.dev?

Does a website for developers, coders, and tech geeks really need to support IE?

I've just written a small website in Svelte as a test case. We need to support IE11 as many large corporations still have IE11 as their main supported browser. Lots of banks do, telecomms companies etc. Regardless of whether people think Svelte is for "developers, coders, and tech geeks", to get acceptance in large clients it needs IE11 support. Banks have 1000s of Win7 laptops/PCs in used globally, IE11 is going to be around for a while yet in the real world.

I've wasted hours today trying to get it to work in IE11.

I've just written a small website in Svelte as a test case. We need to support IE11 as many large corporations still have IE11 as their main supported browser. Lots of banks do, telecomms companies etc. Regardless of whether people think Svelte is for "developers, coders, and tech geeks", to get acceptance in large clients it needs IE11 support. Banks have 1000s of Win7 laptops/PCs in used globally, IE11 is going to be around for a while yet in the real world.

I've wasted hours today trying to get it to work in IE11.

It is possible. Look at this repo by @antony that he mentioned earlier in this issue: https://github.com/antony/sapper-ie.

Iโ€™ve used it myself and it works.

I'll get into more trouble if I post my opinion on ie๐Ÿฆ•๐Ÿฆ• again ;)

The thing is Svelte has a lot of competition and if ie11 support makes add bloat (and take core team dev time) the lightweight output that's gonna hurt long term. Happy if others find a solution though.

@MarkFereday @silllli @quantuminformation Just transpile your code as shown in this example using babel with transorm_class and custom_element_class plugins Sample code in babel., also include polyfills listed below in your main page were you are trying to include your web components.

<script src="https://polyfill.io/v3/polyfill.min.js"></script>
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.4.3/webcomponents-bundle.js"></script>

I've just written a small website in Svelte as a test case. We need to support IE11 as many large corporations still have IE11 as their main supported browser. Lots of banks do, telecomms companies etc. Regardless of whether people think Svelte is for "developers, coders, and tech geeks", to get acceptance in large clients it needs IE11 support. Banks have 1000s of Win7 laptops/PCs in used globally, IE11 is going to be around for a while yet in the real world.

I've wasted hours today trying to get it to work in IE11.

We are aware that people need to support IE11. Myself included. That's why I wrote the sapper-ie project. The sapper and svelte templates themselves have smaller, more limited, but working Babel config also.

Is transpilation / supporting unmaintained browsers part of Svelte's responsiblity? No. Svelte's job is to output modern Javascript.

Is it the job of Babel? Yes. Does the recommended tool for bundling Svelte have first class support for Babel? Yes.

So I really don't think there is anything to do here.

I've just written a small website in Svelte as a test case. We need to support IE11 as many large corporations still have IE11 as their main supported browser. Lots of banks do, telecomms companies etc. Regardless of whether people think Svelte is for "developers, coders, and tech geeks", to get acceptance in large clients it needs IE11 support. Banks have 1000s of Win7 laptops/PCs in used globally, IE11 is going to be around for a while yet in the real world.
I've wasted hours today trying to get it to work in IE11.

It is possible. Look at this repo by @antony that he mentioned earlier in this issue: https://github.com/antony/sapper-ie.

Iโ€™ve used it myself and it works.

Thanks, that's the link I found last night and that helped me, got it working 1am last night. Happy-ish now, personally I think a link to that from the docs would be good. Nearly everything I have worked on in the last x years requires IE11 support even though we all know the arguments against IE11. These are big companies, can't argue against stupid.

p.s. nothing above reduces my enjoyment of using Svelte, just frustration at IE11.

I don't really want the IE fork to be an official project and I don't want to maintain it. I'll think about how we can better direct people via the FAQ or something though.

When loading the legacy bundle it is worth using the nomodule pattern:

<script src'https://assets.example.com/js/app.legacy.js' nomodule> Browsers that natively support ES6 ignore this tag and do not load the legacy bundle. There are exceptions with Safari 10.1 and some version of Edge, for they load both assets, but workarounds can be found easily on the web.

I found this template could support IE ๐Ÿ˜„

IE 11 is heavily entrenched in corporate USA.

The reason is because of significant prior investment in ActiveX components.

In other words:

  1. Numerous Fortune 1000 companies have no option but to run their ActiveX components in IE 11.
  2. When these companies standardize on a single browser, that browser is IE 11.
  3. Many of these companies do standardize on a single browser.
  4. It's unlikely that the Active X based applications will be replaced in the foreseeable future.

Therefore:

lack of IE11 support essentially disqualifies Svelte for use in some very large companies at this time.

No plainer way to put it, unfortunately.

Request:

  • a way to generate two applications: one optimized for IE11, and the other optimized for other browsers.

IE 11 is heavily entrenched in corporate USA.

The reason is because of significant prior investment in ActiveX components.

In other words:

1. Numerous Fortune 1000 companies have no option but to run their ActiveX components in IE 11.

2. When these companies standardize on a single browser, that browser is IE 11.

3. Many of these companies do standardize on a single browser.

4. It's unlikely that the Active X based applications will be replaced in the foreseeable future.

Therefore:

lack of IE11 support essentially disqualifies Svelte for use in some very large companies at this time.

No plainer way to put it, unfortunately.

Request:

* a way to generate two applications: one optimized for IE11, and the other optimized for other browsers.

I thought that's why the new Edge (Chromium) has an "Internet Explorer Mode".
I don't think it is the responsibility of every framework to make sure it works in a 7 years old browser. That's babel's job.

@robots4life thanks for the magical incantations !

A working example here with TypeScsript support as well. Live demo available.