sveltejs / svelte.dev

The Svelte omnisite
https://svelte.dev
112 stars 74 forks source link

Error when importing npm package: 'x' is not exported #848

Open iluuu1994 opened 3 years ago

iluuu1994 commented 3 years ago

This repl is awesome! :heart: I have a small issue.

https://svelte.dev/repl/820b649c9edd4acd9e9b33d727dd3414?version=3.42.6

<script>
    import {createForm} from 'svelte-forms-lib';
</script>

'dequal' is not exported by https://unpkg.com/dequal@2.0.2/lite/index.js, imported by https://unpkg.com/svelte-forms-lib@1.10.7/lib/util.js

Looking at the contents of https://unpkg.com/dequal@2.0.2/lite/index.js dequal is exported though on the last line.

exports.dequal = dequal;

Any idea what's going on here?

Conduitry commented 3 years ago

As far as I can tell, there are two places where this specific issue could be attacked. I think they would both be reasonable new features for the REPL, but I don't know which is more likely to be more helpful or easier.

One the one hand, the in-browser bundler code for CommonJS->ESM conversion doesn't support exposing keys on the exports object as named exports - https://github.com/sveltejs/svelte-repl/blob/master/src/workers/bundler/plugins/commonjs.js

On the other hand, unpkg is resolving (redirecting) https://unpkg.com/dequal/lite to https://unpkg.com/dequal@2.0.2/lite/index.js (the CJS version) as opposed to https://unpkg.com/dequal@2.0.2/lite/index.mjs (the ESM version). I don't know whether it's using the module's exports map (https://unpkg.com/dequal@2.0.2/package.json) or not. But the REPL could conceivably handle this on our end, resolving things to the import (ESM) version, which would remove the need for more robust CJS->ESM conversion.

theetrain commented 1 year ago

Would it be possible to leverage Skypack's dist parameter? I noticed some packages that mix CJS modules and ESM will run into problems when served by Unpkg in the REPL.

Example: https://svelte.dev/repl/00b452b61a424de9b818e79bf029f37f?version=3.55.0 Yields the error:

'enableCache' is not exported by https://unpkg.com/@iconify/svelte@3.0.1/dist/functions.js, 
imported by https://unpkg.com/@iconify/svelte@3.0.1/dist/Icon.svelte

The error's source: https://unpkg.com/@iconify/svelte@3.0.1/dist/functions.js

At the bottom of that file, I can see that exports.enableCache = enableCache; uses CJS modules. The Icon.svelte file importing this function uses ESM syntax, which is why the module cannot be resolved.

Skypack solves this by converting all files in a module to use ES2020. Here's the same module in Skypack: https://cdn.skypack.dev/@iconify/svelte@latest/dist=es2020 Which eventually points to the same enableCache function, but using ESM https://cdn.skypack.dev/-/@iconify/svelte@v3.0.1-DvmBlI0TTw9EtJnJwLOK/dist=es2019,mode=imports/optimized/@iconify/svelte.js

It's currently not possible to do this in the Svelte REPL:

<script>
    import Icon from "https://cdn.skypack.dev/@iconify/svelte@latest/dist=es2020";
</script>

But if I could, this would help with CJS-to-ESM conversions. Or, the REPL can switch from Unpkg to Skypack.