sveltejs / rollup-plugin-svelte

Compile Svelte components with Rollup
MIT License
505 stars 79 forks source link

Unable to export a component using es5 require statement #149

Closed soullivaneuh closed 4 years ago

soullivaneuh commented 4 years ago

This is maybe a bad configuration issue, but I didn't find any useful help on my search.

I have a Nav.svelte component using gravatar:

<script>
  import Tailwindcss from '../Tailwindcss.svelte';
  const gravatar = require('gravatar')

  export let homeUrl;
  export let gravatarEmail;

  $: gravatarUrl = gravatar.url(gravatarEmail, { d: 'retro' });
</script>

This component is exported onto a npm package created from this template months ago. Here is the current Rollup configuration:

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import pkg from './package.json';

const preprocess = require('./preprocess');

const name = pkg.name
  .replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3')
  .replace(/^\w/, (m) => m.toUpperCase())
  .replace(/-\w/g, (m) => m[1].toUpperCase());

export default {
  input: 'src/index.js',
  output: [
    {
      file: pkg.module,
      format: 'es',
    },
    {
      file: pkg.main,
      format: 'umd',
      name,
    },
  ],
  plugins: [
    svelte({ preprocess }),
    resolve(),
  ],
};

The compilation "works" but just put a require on the index.mjs file:

function instance($$self, $$props, $$invalidate) {
    const gravatar = require("gravatar");
    let { homeUrl } = $$props;
    let { gravatarEmail } = $$props;

    $$self.$$set = $$props => {
        if ("homeUrl" in $$props) $$invalidate(0, homeUrl = $$props.homeUrl);
        if ("gravatarEmail" in $$props) $$invalidate(2, gravatarEmail = $$props.gravatarEmail);
    };

    let gravatarUrl;

    $$self.$$.update = () => {
        if ($$self.$$.dirty & /*gravatarEmail*/ 4) {
             $$invalidate(1, gravatarUrl = gravatar.url(gravatarEmail, { d: "retro" }));
        }
    };

    return [homeUrl, gravatarUrl, gravatarEmail];
}

class Nav extends SvelteComponent {
    constructor(options) {
        super();
        if (!document.getElementById("svelte-1pv65z1-style")) add_css$1();
        init(this, options, instance, create_fragment, safe_not_equal, { homeUrl: 0, gravatarEmail: 2 });
    }
}

Resulting on a browser error:

Uncaught ReferenceError: require is not defined

I don't know how to resolve this issue. Is this referenced somewhere on the official documentation? :thinking:

Thanks

soullivaneuh commented 4 years ago

I also try to use @rollup/plugin-commonjs:

diff --git a/rollup.config.js b/rollup.config.js
index 18346f6..3716934 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -1,5 +1,6 @@
 import svelte from 'rollup-plugin-svelte';
 import resolve from '@rollup/plugin-node-resolve';
+import commonjs from '@rollup/plugin-commonjs';
 import pkg from './package.json';

 const preprocess = require('./preprocess');
@@ -25,5 +26,6 @@ export default {
   plugins: [
     svelte({ preprocess }),
     resolve(),
+    commonjs(),
   ],
 };

But this results to on error:

> rollup --exports named -c

src/index.js → dist/index.mjs, dist/index.js...
[!] TypeError: Cannot read property 'length' of undefined
TypeError: Cannot read property 'length' of undefined
    at new MagicString (/home/sullivan/p/gitlab.com/nexylan/ui/node_modules/rollup/dist/shared/node-entry.js:477:37)
    at Module.setSource (/home/sullivan/p/gitlab.com/nexylan/ui/node_modules/rollup/dist/shared/node-entry.js:10087:28)
    at /home/sullivan/p/gitlab.com/nexylan/ui/node_modules/rollup/dist/shared/node-entry.js:12366:20
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
Conduitry commented 4 years ago

There might be a Rollup plugin or configuration that turns require()s into imports, but this would be unrelated to Svelte.

As a general rule, I would suggest writing your components with ESM imports and have them compile to requires where necessary for use on the server.

lukeed commented 4 years ago

Also, on its own, Rollup ignores require statements altogether. So Svelte is forwarding require('gravatar') to Rollup, which purposefully does nothing to it.

soullivaneuh commented 4 years ago

There might be a Rollup plugin or configuration that turns require()s into imports, but this would be unrelated to Svelte.

Was not sure, this is why I opened here.

Also, on its own, Rollup ignores require statements altogether.

So there is no way to make it working with rollup at all? :thinking:

soullivaneuh commented 4 years ago

As a general rule, I would suggest writing your components with ESM imports and have them compile to requires where necessary for use on the server.

@Conduitry I'm quite new here, I am not sure about what your are telling me to do. :thinking:

benmccann commented 4 years ago

You should do import gravatar from 'gravatar'