Search code examples
svelterollupjssapper

external, and globals in sapper client build using rollup


Building using rollup supports externals and globals.

We can import a module in code, and say it as external, then rollup doesn't include it in bundle.

If we give global to it, it 'sets' that import resultant to global in umd bundle.

But doing same thing using when using sapperkeeps module as external, then server build working normally, but client build isn't considering globals, but trying to do 'import' in browser, and is failing, with TypeError ,

': Failed to resolve module specifier “…”' .

Is it possible to keep a library as external in sapper client build, and direct it to use global instead of importing ? Or i am getting some very fundamentals wrong here?


Solution

  • When you keep a module external to the bundle, what that actually means is that the import declaration is preserved in the generated code. So if you have something like

    import foo from 'foo';
    

    then your server code will have something like

    const foo = require('foo');
    

    (which works, because of the Node module resolution algorithm), and in your client JS you'll end up with the exact same import... which doesn't work in browsers, because import paths need to be relative. (This may change in future with import maps.)

    The easiest solution is not to use external, and just let Rollup handle it (you could do this just for the client). But if you did want to use a global instead, you could perhaps use @rollup/plugin-virtual:

    plugins: [
      virtual({
        foo: `export default window.foo`
      }),
      // ...
    ]
    

    and then add a <script> tag in your src/template.html that pointed to a file in static.