sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.45k stars 1.89k forks source link

Directory import is not supported resolving ES modules imported /.svelte/output/server/app.js #612

Closed Evertt closed 3 years ago

Evertt commented 3 years ago

Describe the bug When running npm run build on a project that uses RxJS I get the following error:

Directory import '/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rxjs/operators' is not supported resolving ES modules imported from /Users/evert/Sites/svelte-kit-tailwind-jit/.svelte/output/server/app.js Did you mean to import rxjs/dist/cjs/operators/index.js?

If I indeed manually change that line in /.svelte/output/server/app.js from this:

import {share, filter, map, finalize} from "rxjs/operators";

To this:

import {share, filter, map, finalize} from "rxjs/dist/cjs/operators/index.js";

then I can successfully run npm run start and everything works.

To Reproduce Just install RxJS and import some operators somewhere. I tested this on kit version 1.0.0-next.55.

Expected behavior This to just work without a hitch.

Stacktrace

Stack trace Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rxjs/operators' is not supported resolving ES modules imported from /Users/evert/Sites/svelte-kit-tailwind-jit/.svelte/output/server/app.js Did you mean to import rxjs/dist/cjs/operators/index.js? at new NodeError (node:internal/errors:329:5) at finalizeResolution (node:internal/modules/esm/resolve:319:17) at moduleResolve (node:internal/modules/esm/resolve:758:10) at Loader.defaultResolve [as _resolve] (node:internal/modules/esm/resolve:869:11) at Loader.resolve (node:internal/modules/esm/loader:86:40) at Loader.getModuleJob (node:internal/modules/esm/loader:230:28) at ModuleWrap. (node:internal/modules/esm/module_job:57:40) at link (node:internal/modules/esm/module_job:56:36)

Information about your SvelteKit Installation:

The output of `npx envinfo --system --npmPackages svelte,@sveltejs/kit --binaries --browsers` System: OS: macOS 11.2.3 CPU: (8) x64 Apple M1 Memory: 19.48 MB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 15.8.0 - ~/.nvm/versions/node/v15.8.0/bin/node Yarn: 1.22.10 - ~/.nvm/versions/node/v15.8.0/bin/yarn npm: 7.6.1 - ~/.nvm/versions/node/v15.8.0/bin/npm Browsers: Chrome: 89.0.4389.90 Safari: 14.0.3 npmPackages: @sveltejs/kit: ^1.0.0-next.55 => 1.0.0-next.55 svelte: ^3.29.0 => 3.35.0

Severity For now I'm just playing around with SvelteKit. So it's okay with me if I can't run npm run build as long as I can run npm run dev, which for now seems to be working fine.

babichjacob commented 3 years ago

One option that works is importing from "rxjs/operators/index.js" instead of "rxjs/operators". I don't know what the implications on file size of this are.

Evertt commented 3 years ago

@babichjacob it doesn't seem to work for me. When I try that then rollup complains during the build process that it can't resolve "rxjs/operators/index.js"

Rollup failed to resolve import "rxjs/operators/index.js" from "src/swr.ts". Error: [vite]: Rollup failed to resolve import "rxjs/operators/index.js" from "src/swr.ts". This is most likely unintended because it can break your application at runtime. If you do want to externalize this module explicitly add it to `build.rollupOptions.external` at onRollupWarning (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/vite/dist/node/chunks/dep-efe32886.js:44294:19) at Object.onwarn (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/vite/dist/node/chunks/dep-efe32886.js:44144:17) at Object.onwarn (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:19724:20) at ModuleLoader.handleResolveId (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18474:26) at /Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18441:22 at processTicksAndRejections (node:internal/process/task_queues:94:5) at async Promise.all (index 1) at async ModuleLoader.fetchStaticDependencies (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18439:34) at async Promise.all (index 0) at async ModuleLoader.fetchModule (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18416:9)

I also tried this:

Rollup failed to resolve import "rxjs/dist/types/operators/index" from "src/swr.ts". Error: [vite]: Rollup failed to resolve import "rxjs/dist/types/operators/index" from "src/swr.ts". This is most likely unintended because it can break your application at runtime. If you do want to externalize this module explicitly add it to `build.rollupOptions.external` at onRollupWarning (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/vite/dist/node/chunks/dep-efe32886.js:44294:19) at Object.onwarn (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/vite/dist/node/chunks/dep-efe32886.js:44144:17) at Object.onwarn (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:19724:20) at ModuleLoader.handleResolveId (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18474:26) at /Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18441:22 at processTicksAndRejections (node:internal/process/task_queues:94:5) at async Promise.all (index 1) at async ModuleLoader.fetchStaticDependencies (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18439:34) at async Promise.all (index 0) at async ModuleLoader.fetchModule (/Users/evert/Sites/svelte-kit-tailwind-jit/node_modules/rollup/dist/shared/rollup.js:18416:9)

edit

I can get build to finish without an error by using import { ... } from "rxjs/dist/cjs/operators/index.js" in my TypeScript file and then adding this:

build: {
    rollupOptions: {
        external: ["rxjs/dist/cjs/operators/index.js"]
    }
}

To the kit.vite object in my svelte.config.cjs. But then npm run start still doesn't work, because even though the server built correctly, now the client was built incorrectly and can't use the rxjs operators.

alteredorange commented 3 years ago

Similar issues with Firebase Admin and Amazon S3 SDK. Everything works fine in dev, but on build: For Firebase Admin throws admin.initializeApp is not a funciton error.

    at file://.svelte/output/server/app.js:3557:9
    at ModuleJob.run (node:internal/modules/esm/module_job:154:23)
    at async Loader.import (node:internal/modules/esm/loader:166:24)
    at async prerender (file:///node_modules/.pnpm/@sveltejs/kit@1.0.0-next.59_svelte@3.35.0+vite@2.1.2/node_modules/@sveltejs/kit/dist/chunks/index5.js:512:14)
    at async Builder.prerender (file:///node_modules/.pnpm/@sveltejs/kit@1.0.0-next.59_svelte@3.35.0+vite@2.1.2/node_modules/@sveltejs/kit/dist/chunks/index5.js:744:4)
    at async adapt (/node_modules/.pnpm/@sveltejs/adapter-node@1.0.0-next.10/node_modules/@sveltejs/adapter-node/index.js:26:4)
    at async adapt (file:///node_modules/.pnpm/@sveltejs/kit@1.0.0-next.59_svelte@3.35.0+vite@2.1.2/node_modules/@sveltejs/kit/dist/chunks/index5.js:766:2)
    at async file:///node_modules/.pnpm/@sveltejs/kit@1.0.0-next.59_svelte@3.35.0+vite@2.1.2/node_modules/@sveltejs/kit/dist/cli.js:512:5

for Amazon S3 SDK, 'request' is not exported by __vite-browser-external, imported by node_modules/.pnpm/@aws-sdk/credential-provider-imds@3.8.0/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js is the error.

Error: 'request' is not exported by __vite-browser-external, imported by node_modules/.pnpm/@aws-sdk/credential-provider-imds@3.8.0/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
    at error (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:5308:30)
    at Module.error (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:9717:16)
    at Module.traceVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:10105:29)
    at ModuleScope.findVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:8875:39)
    at FunctionScope.findVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:2658:38)
    at ChildScope.findVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:2658:38)
    at FunctionScope.findVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:2658:38)
    at ChildScope.findVariable (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:2658:38)
    at Identifier.bind (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:4043:40)
    at CallExpression.bind (/node_modules/.pnpm/rollup@2.42.3/node_modules/rollup/dist/shared/rollup.js:2745:23)

Any help would be greatly appreciated, thanks!

samccone commented 3 years ago

Specifically this seems quite related to this upstream issue: https://github.com/nodejs/node/issues/27408

and this note: https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.

For the rxjs/operator case specifically I attempted to work around this by running the following

node --experimental-specifier-resolution=node node_modules/\@sveltejs/kit/dist/cli.js build

However my new error is

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/samccone/Desktop/repos/edit/node_modules/rxjs/operators' imported from /Users/samccone/Desktop/repos/edit/.svelte/output/server/app.js
Did you mean to import rxjs/dist/cjs/operators/index.js?

Which I have to imagine is due to the indirection of the package.json file inside of the operators folder image


I was able to add

  "exports": {
    ".": "./dist/cjs/index.js",
    "./operators": [
      {
        "import": "./dist/esm5/operators/index.js",
        "require": "./dist/cjs/operators/index.js"
      },
      "./dist/cjs/operators/index.js"
    ]
  },

inside of rxjs's root package.json which made the build successful, however now the development server errors with:

Error: Cannot find module 'rxjs/operators' from '/Users/samccone/Desktop/repos/edit/src/store'
    at Function.resolveSync [as sync] (/Users/samccone/Desktop/repos/edit/node_modules/resolve/lib/sync.js:90:15)
    at resolveFrom$2 (/Users/samccone/Desktop/repos/edit/node_modules/vite/dist/node/chunks/dep-efe32886.js:3883:29)
    at resolve (/Users/samccone/Desktop/repos/edit/node_modules/vite/dist/node/chunks/dep-efe32886.js:68928:22)
    at nodeRequire (/Users/samccone/Desktop/repos/edit/node_modules/vite/dist/node/chunks/dep-efe32886.js:68907:25)
    at ssrImport (/Users/samccone/Desktop/repos/edit/node_modules/vite/dist/node/chunks/dep-efe32886.js:68865:20)
    at eval (/src/store/image_upload.ts:7:31)
    at instantiateModule (/Users/samccone/Desktop/repos/edit/node_modules/vite/dist/node/chunks/dep-efe32886.js:68893:166)
    at processTicksAndRejections (node:internal/process/task_queues:94:5) (x2)

rxjs workaround

cp -r node_modules/rxjs src/

In your src file:

import { mergeMap } from './rxjs/dist/esm5/internal/operators/mergeMap';
import { scan } from './rxjs/dist/esm5/internal/operators/scan';
lschmierer commented 3 years ago

I have the same issue with the Firebase JS SDK (which is supposed to work in server and browser environments https://firebase.google.com/docs/web/environments-js-sdk).

As a workaround, I tried importing

import firebase from 'firebase/app/dist/index.cjs';

instead of

import firebase from 'firebase/app';

This, however, throws errors on execution (on Firebase functions) and prints the following warning on build time:

[2021-03-28T20:15:57.520Z]  @firebase/app: 
      Warning: This is a browser-targeted Firebase bundle but it appears it is being
      run in a Node environment.  If running in a Node environment, make sure you
      are using the bundle specified by the "main" field in package.json.

      If you are using Webpack, you can specify "main" as the first item in
      "resolve.mainFields":
      https://webpack.js.org/configuration/resolve/#resolvemainfields

      If using Rollup, use the @rollup/plugin-node-resolve plugin and specify "main"
      as the first item in "mainFields", e.g. ['main', 'module'].
      https://github.com/rollup/@rollup/plugin-node-resolve

The warning is kind of confusing, because dist/index.cjs.js is actually specified as main in node_modules/firebase/app/package.json.

When running svelte-kit dev, everything works as expected, though.

BibbyChung commented 3 years ago

I solve this issues. But it's a temporary solution. Waiting the best solution....

import {share, filter, map, finalize} from "rxjs/dist/cjs/operators/index.js";

to

import { map } from 'rxjs/internal/operators/map.js';
import { filter } from 'rxjs/internal/operators/filter.js';
import { share } from 'rxjs/internal/operators/share.js';
import { finalize } from 'rxjs/internal/operators/finalize.js';
lukechu10 commented 3 years ago

None of these workarounds work for me because rxjs/operators is imported by a dependency which I do not control. This is probably the only thing preventing me from migrating from sapper.

samccone commented 3 years ago

Hi all, I have a fix for rxjs https://github.com/ReactiveX/rxjs/pull/6192

IMHO this is not a problem with sveltekit, and rather is a challenge with the node ecosystem. Since sveltekit is using package: module I expect we are going to continue to see this class of problem moving forward.

The path for fixing things is going to be to send PRs upstream to your libraries to fix.

@Rich-Harris @benmccann +1 to close this issue imho.

Rich-Harris commented 3 years ago

Even though SvelteKit projects default to "type":"module", we could add a "type":"commonjs" package.json to the built output and target CJS. I suspect that would solve the module resolution errors

benlesh commented 3 years ago

Thanks to @samccone, that fix is in and deployed in rxjs@7.0.0-beta.14.

lschmierer commented 3 years ago

IMHO this is not a problem with sveltekit, and rather is a challenge with the node ecosystem. Since sveltekit is using package: module I expect we are going to continue to see this class of problem moving forward.

I agree with @samccone.

For Firebase users.. Google just released a modularized SDK in Alpha earlier this year: https://modularfirebase.web.app

jacob-8 commented 3 years ago

@lschmierer I've been trying to get the modularized Firebase SDK to work client and server side with no success in solving this module resolution error. See my repro at https://github.com/jwrunner/SSR-import-firebase-exp-bug which I used as a starter for adding the exports (listed below) to the firebase/app/package.json in an attempt to sniff out a possible bug fix to contribute to the firebase@exp repo. The following didn't help:

"exports": {
    ".": {
      "browser": "./dist/index.esm.js",
      "import": "./dist/index.esm.js",
      "node": "./dist/index.cjs.js",
      "default": "./dist/index.cjs.js"
    }
  }

@samccone Any pointers on how to proceed with a bug fix for the modular Firebase package?

lschmierer commented 3 years ago

@jwrunner I am sorry, I haven’t actually tried using the modularized SDK.

Evertt commented 3 years ago

Also I just tried it with the new modularized firebase and it doesn't work. I still get the same error in de build process.

austinbakker commented 3 years ago

I am currently getting the same error. Trying to generate a SPA for firebase hosting, but i am getting the following error The XMLHttpRequest compatibility library was not found. . Did anyone find a workaround?

benmccann commented 3 years ago

For Firebase, please use SDK v9 which provides a modular SDK approach that's currently in beta. The old versions are very difficult to get working especially with SSR and also resulted in a much larger client download size.

MarcusCemes commented 3 years ago

@benmccann I encountered some issues with the ESM v9 build, namely with the functions import. It has some top-level code that runs on- mport that references self (a.k.a window) that errors during build. I created an issue in their repository, but they don't seem to be willing to fix this for now. Before I cause too much damage, am I doing something wrong?

I've found a temporary fix by moving firebase into devDependencies (which is apparently not necessary anymore), which avoids inlining firebase into server/app.js and does a regular ESM import ... from instead. It seems like the ESM loader (I imagine this is Node.js, not Vite) effectively ignores the top-level code and goes straight for the imported functions, which is great (hopefully it won't break anything...?), but firebase seems to be bundled even on pages without any JS, which I'll have to investigate more when I have time.

There's a detailed description and example at https://github.com/firebase/firebase-js-sdk/issues/4846

FossPrime commented 3 years ago

For compatibility with deno... I just went ahead and added all my extensions... I had already mostly done that during the MJS era.

It should be easy to make a js script to go though all your source and replace anything missing an extension to .js or index.js if it doesn't exist. Regex for finding scripts without extensions'(?:'\./[^.]+)'$

In Code, for unnamed CJS package exports: Find all in you src directory, using regex: (import \{)(.*)(FHCPkg.*pkg$)

ReplaceAll: import FHCPkg from 'bad-commonjs-module'\nconst {$2$3