Skip to content

Directory import not supported in build mode #6193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
7 tasks done
alecandido opened this issue Dec 20, 2021 · 20 comments
Closed
7 tasks done

Directory import not supported in build mode #6193

alecandido opened this issue Dec 20, 2021 · 20 comments
Labels
p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@alecandido
Copy link

Describe the bug

The problem consist in import from folders only containing a package.json file, whose attribute main, module, types are pointing somewhere else, while running in build mode.

I'm sorry that the issue is coming from another framework, unfortunately I'm not much familiar with direct use of Vite, but I'm pretty sure the issue is related to build tools, so it's not specific to the framework.
I was unsure if it's coming from Rollup, or whatever is underlying Vite, but I guess you can help redirect if appropriate.

The full story is the following:

  • I was making a project with SvelteKit
  • I tried using rxdb
  • I already experienced some issues, because of mix between node on browser js
    • e.g. I had to deal with issues like missing events
    • the final workaround have been to add shims for process (window.process = window.process || {};) and global (window.global = window;), and to make a custom build, adding all RxPlugin and PouchPlugin inside onMount, in order to do it only inside the browser
  • then, the imports looked like:
    import { createRxDatabase, addRxPlugin } from 'rxdb/plugins/core'; 
    and everything was working with svelte-kit dev
  • as soon as I tried to use svelte-kit build, then I obtained the error message provided in the logs (for one of the imports, it happens for all of them)
  • actually the reason is that the import path is pointing to a folder only containing a package.json file like the following:
    https://github.com./pubkey/rxdb/blob/e5731c6953410c02aa66cbab5ac5e44d433b3a58/plugins/core/package.json#L1-L8
    containing attributes main, jsnext:main, modules, types that are pointing to other files
  • the workaround found at the moment is to change the import as suggested:
    import { createRxDatabase, addRxPlugin } from 'rxdb/dist/lib/core.js';
    but this way there is non package.json associated, and, e.g., types are completely lost (so typescript hints cannot be used, and the editor complaints it can't find declaration file)

This behavior is clearly connect with build and bundling, and so I resorted to looking into Vite.
Moreover, it's different between svelte-kit dev and svelte-kit build, and since svelte-kit is not a build tool on its own, but it's said to rely on Vite, I guess the issue is connected do Vite.

Hope you can help to use the first version of the input, or redirect to the relevant place.

Reproduction

  • make a new project (I used SvelteKit, but don't believe to be relevant)
  • install rxdb
  • make a custom build, following intructions
  • run in build mode

System Info

System:
    OS: Linux 5.13 Ubuntu 21.10 21.10 (Impish Indri)
    CPU: (4) x64 Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
    Memory: 494.57 MB / 7.56 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 14.18.1 - /usr/bin/node
    Yarn: 1.22.15 - /usr/bin/yarn
    npm: 6.14.15 - /usr/bin/npm
  Browsers:
    Brave Browser: 95.1.31.91
    Firefox: 95.0

Used Package Manager

pnpm

Logs

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '<project>/node_modules/rxdb/plugins/core' is not supported resolving ES modules imported from <project>/.svelte-kit/output/server/chunks/index-92d6ff96.js
Did you mean to import [email protected][email protected]/node_modules/rxdb/dist/lib/core.js?
    at new NodeError (internal/errors.js:322:7)
    at finalizeResolution (internal/modules/esm/resolve.js:304:17)
    at moduleResolve (internal/modules/esm/resolve.js:731:10)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:842:11)
    at Loader.resolve (internal/modules/esm/loader.js:89:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:76:40)
    at link (internal/modules/esm/module_job.js:75:36)

Validations

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

The error is coming from node (see here). You can use node --experimental-specifier-resolution=node when running the build to support directory import, but otherwise this doesn't look like a Vite/SvelteKit bug to me. You can also make an issue in rxdb to output ESM so directory imports are supported via conditional exports.

Closing this based on the above explanation. Thanks for the write-up in the description, was helpful in tracking down the issue.

@bluwy bluwy closed this as completed Dec 23, 2021
@alecandido
Copy link
Author

Actually I've already found that SO answer, but that's a different thing from what I asked for: node --experimental-specifier-resolution=node enable to import a folder, importing the index.js file in it.

In this case there is no index.js file inside, but a package.json pointing somewhere else, and this is not supported by node --experimental-specifier-resolution=node.

Moreover, I'm not directly calling node, so I would not know how to pass the flag (I tried to find a way, but I failed; it's not solving the problem in any case, but it would be useful to know it anyhow).

@alecandido
Copy link
Author

Actually I've already found that SO answer, but that's a different thing from what I asked for: node --experimental-specifier-resolution=node enable to import a folder, importing the index.js file in it.

@bluwy can you please reopen it, at least for this reason?

@bluwy bluwy reopened this Dec 23, 2021
@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

I see. I thought the error was happening on the build output, instead it's happening on the build process. Can you provide a repro either on github or stackblitz to present the issue? It'll help anyone else to quickly debug your issue too. It might also be worth trying to repro this without sveltekit if possible.

@haoqunjiang

This comment has been minimized.

@alecandido
Copy link
Author

alecandido commented Dec 23, 2021

Yes, I'll try to produce a minimal example.

In any case, I guess to have found at least a workaround, just reading Kit FAQs.

I guess the problem is in the library usage, and most likely Vite itself can do little for it. As you said it boils down to node, so I don't know if it's possible to shim or anything else.

The idea is that if your library it's a client-only library, you want to prevent to run at build time, and for this you need not only to avoid calls, but even import (occasionally).
So the workaround would be to replace:

import { whatever } from 'myclientonlylib/subfolder';

with:

import { onMount } from 'svelte';

onMount(async () => { 
    const { whatever } = await import('myclientonlylib/subfolder');
}

@alecandido
Copy link
Author

I think it's the same issue as #6061, caused by #5665

Ok, I refreshed too late. Then maybe Vite can do something, at least to solve the import issue (then client-side lib usage of course is not something that has to be fixed at all, it has just to happen in the browser only).

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

Yeah I think it's a bug in Vite then. The workaround looks fine to me though if the package is client-only.

Thanks for the heads up @sodatea. Checking #5665, it looks like it's fixing this exact issue though, unless I'm wrong. And should we keep this issue separate to #6061?

@bluwy bluwy added p3-minor-bug An edge case that only affects very specific usage (priority) and removed pending triage labels Dec 23, 2021
@haoqunjiang
Copy link
Member

🤔I'm not very sure about this issue, I haven't run the code yet. Maybe it's not the same one.

But as I checked, that PR does break the devextreme library, and the cause is related to directory imports.
So I guess some assumptions in the PR may be incorrect, though I haven't figured out why.

@alecandido
Copy link
Author

alecandido commented Dec 23, 2021

I made an example project on stackblitz, though maybe not perfectly minimal.

Actually, in SvelteKit you need to use adapter-static to generate the build time issue. I guees it would be the same specifying prerender = true.
Most likely, this is needed because otherwise SvelteKit would not run the import at build time, but later on the server. Toggling prerendering makes the error to pop up immediately.

@haoqunjiang
Copy link
Member

😂 Sorry, I just figured out the exact problem of the other issue. It's due to a dot in the directory path.
So I think the two issues are not related.

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

Thanks for the repro @alecandido. It looks like the issue happens in the adapter step, so it's likely not a Vite bug here. I'll try to dig into this more later before closing this.

@alecandido
Copy link
Author

Actually adapter-static is really doing little, all the code is 80 lines.

I guess the relevant bit is really that is prerendering everything, but I'm not sure.

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

Prerender executes the code in node, that's why you're getting the error from node. I was able to find a workaround. You can set the build command to node --experimental-specifier-resolution=node ./node_modules/@sveltejs/kit/svelte-kit.js build to fix the error. This is a limitation of "type": "module" and CJS packages (rxdb) in general, but it should technically be avoided in the first place since rxdb/plugins/core has sideEffects: false in the package.json. I also checked that Vite is properly resolving this, so I'm not sure why Rollup is still preserving this import in the SSR bundle chunk. Either ways, this would be a separate issue for another time.

@bluwy bluwy closed this as completed Dec 23, 2021
@alecandido
Copy link
Author

Ok, not the easiest workaround, but still fine.

Do you believe this would be relevant to raise for Kit?

In any case, many thanks for your effort!

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

No problem :) I think the issue might reside in Rollup or Vite of the generated SSR bundle code. But Kit is working as usual here as it's basing off the generated bundle, so no need for an issue there.

@alecandido
Copy link
Author

@bluwy still reading the above mentioned FAQ (I'm taking some time to digest), there are another couple of considerations:

  • as you said, being side-effect free it should not be loaded in SSR, then if in Vite is working, maybe the issue is in the way Kit uses Vite: at the end of the day Rollup is fed by Vite (or am I missing something?)
  • another workaround is the suggested module of yours, vite-plugin-iso-import, that allows preserving the static import, and enforce SSR stripping (but it's even another dependency, so personally I prefer to avoid)

@bluwy
Copy link
Member

bluwy commented Dec 24, 2021

  • as you said, being side-effect free it should not be loaded in SSR, then if in Vite is working, maybe the issue is in the way Kit uses Vite: at the end of the day Rollup is fed by Vite (or am I missing something?)

Yeah perhaps there's an issue with how Kit uses Vite, probably in terms of the build config passed to Vite, but I'll have to find time and isolate it to Vite only to disect the cause of the bug.

  • another workaround is the suggested module of yours, vite-plugin-iso-import, that allows preserving the static import, and enforce SSR stripping (but it's even another dependency, so personally I prefer to avoid)

vite-plugin-iso-import shouldn't be needed here as the package is already side-effect free, but yes it's another workaround too for this issue

@alecandido
Copy link
Author

I had a quick look, and I guess that:

  • if it was something svelte related, it might be in kit, but even svelte itself
  • in some sense svelte is doing something, because is partially compiling components and splitting between ssr and client code, and it's actually playing with imports, but I guess is not doing anything advanced (it's not bundling, so not even tree shaking)
  • in kit if it should happen, it could be related to prender, but I checked and nothing related to import seems to happen (nor it is directly interacting with vite), so I guess it should be in build, where (if I'm not wrong) if the vite config are defined
  • nevertheless, there is another candidate, i.e. vite-plugin-svelte

Since I'm completely new the codebase, here I stop, and I'll leave the exploration to you, @bluwy, or someone that is more in touch with the code (unless you can point me out a promising place to start from).

@bluwy
Copy link
Member

bluwy commented Dec 31, 2021

Forgot to reply 😅 But I've certainly been looking into this from time-to-time. I haven't got it fully figured out, to remove the unused imports in the SSR bundle. Though to be fair, it's more of a workaround for the real issue, that is node and rxdb compatibility.

Ultimately, I think it'll benefit if rxdb exports ESM and use pkg.exports. But it doesn't look welcoming to create an issue there.


If you're interested in the deeper details for my attempt at fixing this in Vite, currently dependencies that are externalized (not bundled) are kept in the final bundle code as import "some-lib", even though it doesn't has any value import.

I'm suspecting it's because we didn't tell Rollup that some-lib is side-effect free, so it keeps it there. So my goal is to tell Rollup about it, either with treeshake.moduleSideEffects, or a custom Rollup plugin to swiftly handle everything. (I'm at this point now)

Most importantly, these are all just theories and I haven't actually tested if this would work.

Note: This is still not a bug in Vite as it's only working around the real issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

No branches or pull requests

3 participants