lukeed / navaid

A navigation aid (aka, router) for the browser in 850 bytes~!
MIT License
778 stars 26 forks source link

Error: UMD and IIFE output formats are not supported for code-splitting builds. #5

Closed Naragod closed 5 years ago

Naragod commented 5 years ago

I am following the example in the template provided after creating an app from the official svelte demo and I received the above ^ error when I set my rollup configuration file format to iife.

input: 'src/main.js', output: { sourcemap: true, format: 'iife', name: 'app', file: 'public/bundle.js' },

Or is this a rollup issue?

lukeed commented 5 years ago

It's not a navaid nor a Rollup issue. The IIFE and UMD formats outright cannot be code-split.

You have to use the ESM, AMD, or SystemJS outputs, as configured in the template. I also spoke a tiny bit about this here.

In short, both IIFE and UMD formats are (purposefully) self-contained. By definition, you can't export/"read" pieces of a UMD/IIFE file because its scope/contents are fully enclosed.

Hope that helps a bit~!

frederikhors commented 5 years ago

So this is a problem if I want to use navaid in my new svelte standard rollup template.

How to fix now?

lukeed commented 5 years ago

Why? You're not forced to use code-splitting. And there are a few ways to make code-splitting (with ESM) work inside order browsers.

frederikhors commented 5 years ago

How? We need examples luke, we are not go(o)d as you are unfortunately.

lukeed commented 5 years ago

No it's not that at all. You're right in that these are relatively new patterns/tools to the landscape, so it does come to be an example/education issue.

What about the svelte-demo doesn't make sense or don't you like? And, maybe separately, what new kind of example are you looking for?

Naragod commented 5 years ago

Can you explain the following line: https://github.com/lukeed/svelte-demo/blob/master/public/index.html#L15

I replaced my reference to bundle.js and now my code works and is hot loading. It was the missing piece.

In the svelte demo, there is a reference to bundle.js. Is the reference to index.js the same index.js file in your src folder? Why did it work?

janzheng commented 4 years ago

Can you explain the following line: https://github.com/lukeed/svelte-demo/blob/master/public/index.html#L15

I replaced my reference to bundle.js and now my code works and is hot loading. It was the missing piece.

In the svelte demo, there is a reference to bundle.js. Is the reference to index.js the same index.js file in your src folder? Why did it work?

ok for future reference, we're getting the IIFE / UMD error because the svelte-demo example uses dynamic importing, which allows for preloading and stuff. Unfortunately, this doesn't play well with the basic Svelte template, which uses format: 'iife' in the rollup config file, and IIFE nor UMD seem to support dynamic importing.

The quickest way to get around this problem is to not use the dynamic imports. To do this, go to App.svelte and for example replace the line run(import('../routes/Home.svelte')) with

Route = Home;
window.scrollTo(0, 0);

and make sure to import Home from '../routes/Home.svelte' like any regular component, and replace every line that starts with run(import... with setting Route equal to a regular component. This isn't as clever as a dynamic import, but it lets you quickly use the svelte-demo example for your own needs.

chopfitzroy commented 4 years ago

Hey @lukeed,

I notice you using dimport in the index.html itself, would it be possible to get an example of using it in the App.svelte itself? I tried updating the import statements to use dimport which solved my bundling issue, but I still get issues actually rendering the site in the browser.

This is what I ended up with:

<main>
  <svelte:component this={Route} {params} />
</main>

<script>
  import Navaid from "navaid";
  import dimport from 'dimport';
  import { onDestroy } from "svelte";

  let Route;
  let active;
  let params = {};
  let uri = location.pathname;

  $: active = uri.split("/")[1] || "home";

  function run(thunk, obj) {
    const target = uri;
    thunk.then(m => {
      if (target !== uri) return;
      params = obj || {};
      if (m.preload) {
        m.preload({ params }).then(() => {
          if (target !== uri) return;
          Route = m.default;
          window.scrollTo(0, 0);
        });
      } else {
        Route = m.default;
        window.scrollTo(0, 0);
      }
    });
  }

  const router = Navaid("/")
    .on("/", () => run(dimport("./views/Home.svelte")))
    .on("/about", () => run(dimport("./views/About.svelte")))
    .on("/blog", () => run(dimport("./views/Blog.svelte")))
    .on("/blog/:postid", obj => run(dimport("./views/Article.svelte"), obj))
    .listen();

  onDestroy(router.unlisten);
</script>

Cheers.

lukeed commented 4 years ago

@CrashyBang because dimport() is non-native (think of it as an HTTP request) it can only work with known destinations -- unlike import() which Rollup will find-n-replace with updated URL pathing.

If you must keep a UMD target (why? jw), then j recommend your src/main.js (or equivalent) is built as UMD and it and only it has a single dimport() for the App. Then, the App and all Svelte components use import() since these Svelte components should be bundled as ESM (with known destination).

It gets a little confusing, but it's required since you apparently want to keep a target format that doesn't/can't play nicely with dynamic import statements.

chopfitzroy commented 4 years ago

Hey @lukeed ,

Not in anyway married to umd format, quite happy to use esm but I guess I just liked the idea of using dimport locally as opposed to over a cdn.

I think I am not quite understanding how I should be using dimport.

Cheers.

lukeed commented 4 years ago

Lol reading again, I dunno where I got that UMD idea from 😂

It's still somewhat relevant though - if you wanna use dimport, you have to know where/what your destination files are going to be. Put differently dimport("./views/Home.svelte") won't work because that path reflects your source structure, not your built output.

chopfitzroy commented 4 years ago

Hey @lukeed,

Okay that makes total sense, so if I wanted to use it in my src then the string I am passing to dimport would actually need to be relative to my bundle output?

Or I could just use esm and allow the build process to handle the native imports and then use dimport on the compiled output, which makes total sense, sorry for the confusion.

Cheers,

lukeed commented 4 years ago

Correct, relative to expected output or use absolute paths (easier to reason about).

The demo repo mounts dimport on the HTML just because that's a quicker way to get dimport to "check" everything. Once it loads the main bundle (or any file), it will then convert all native imports to itself if need be.

mspanish commented 4 years ago

This is odd, I do not get this error using a Svelte template on my Linux machine. My dev builds load fine. Then I switched to my Windows laptop and get this error - nothing has changed. I thought maybe I needed to updated some npm modules or something - and did that, and it doesn't change anything. Same error.

Update: solved it by adding this to the rollup config:

inlineDynamicImports: true,

danangponorogo commented 3 years ago

@mspanish, Alhamdulillah, thank you very much for the clue, finally the error disappeared. To make it clearer, in the code below I will write the rollup.config.js section again, hopefully it's easier to understand.

export default { input: 'src/main.js', output: { sourcemap: true, format: 'iife', name: 'app', file: 'public/build/bundle.js', inlineDynamicImports: true },

dimaslanjaka commented 8 months ago

It's not a navaid nor a Rollup issue. The IIFE and UMD formats outright cannot be code-split.

You have to use the ESM, AMD, or SystemJS outputs, as configured in the template. I also spoke a tiny bit about this here.

In short, both IIFE and UMD formats are (purposefully) self-contained. By definition, you can't export/"read" pieces of a UMD/IIFE file because its scope/contents are fully enclosed.

Hope that helps a bit~!

the template config not found

lukeed commented 8 months ago

https://github.com/lukeed/svelte-demo/blob/master/bin/config/rollup.js#L60