Skip to content

Creating a v2 Tauri App with Svelte Causes Errors on MacOS 10.13 #948

Description

@clone206

Steps to Reproduce

npm create tauri-app@latest
  • Choose Svelte as the frontend framework. Either TS or JS will have the issue.
  • Build for production, Mac x86_64, with "devtools" feature enabled
  • Install on MacOS 10.13
  • Run and open developer tools

Expected Behavior

App should have identical functionality in MacOS 10.13 as in later versions when created with this scaffolding. No errors should be present in the console.

Observed Behavior

The installed app fails to display the UI on MacOS 10.13. An empty window is loaded. Syntax errors, missing variable/functions exceptions are displayed in the console.

In my case this appears to be due to compatibility issues with the system WebView version, which seems to correspond to Safari 11. This was confirmed by searching for the version number found for the system WebKit framework listed in the System Report.

Workaround

I was able to get the app to load by manually adding the below script tag with polyfills to the index page's head and setting the target and deps target to es2015 in the vite config. I'm sure there is a better way via packages/plugins, but I wanted to find the minimal fix with Svelte.

Potential Fix

Add the below polyfill to the scaffolded index page and target es2015 in vite config file template, or use a polyfill package/plugin in the Vite config file template.

Further Notes

Of course, it would be up to the developer to generate CSS that displays properly on MacOS 10.13/Safari 11, but from my initial impressions the scafolded app's layout displayed properly. In my own app, there are layout issues due to the system webview's lack of full support for flexbox.

Creating e.g. a react or vue app may or may not have similar issues on MacOS 10.13, but I didn't try.

<script>
    // Polyfills
    if (!window.globalThis) window.globalThis = window;
    if (!Object.fromEntries) {
      Object.fromEntries = function (entries) {
        var res = {};
        for (var i = 0; i < entries.length; i++) {
          res[entries[i][0]] = entries[i][1];
        }
        return res;
      };
    }
    (function () {
      if (typeof window !== 'undefined' && typeof window.queueMicrotask === 'function') {
        return; // Native function is available
      }
      // Polyfill using Promise.resolve().then()
      window.queueMicrotask = function (callback) {
        Promise.resolve().then(callback).catch(err =>
          // Handle any errors that might occur within the microtask
          setTimeout(() => { throw err; }, 0)
        );
      };
    })();
    if (!String.prototype.replaceAll) {
      String.prototype.replaceAll = function (str, newStr) {
        // If the search value is a RegExp object, use replace() as is.
        // The original replace() method handles global regexes correctly.
        if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
          return this.replace(str, newStr);
        }
        // If the search value is a plain string, create a new RegExp with the 'g' (global) flag
        // and use replace() to substitute all occurrences.
        // The original string is left unchanged, and a new one is returned, as per spec.
        return this.replace(new RegExp(str, 'g'), newStr);
      };
    }
</script>
export default defineConfig(async () => ({
  build: {
    target: "es2015"
  },
  optimizeDeps: {
		esbuildOptions: {
			target: 'es2015'
		}
  },
// ... 
}));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions