Skip to content
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

Windows Error: Function called outside component initialization #460

Closed
GrygrFlzr opened this issue Mar 6, 2021 · 9 comments · Fixed by #544
Closed

Windows Error: Function called outside component initialization #460

GrygrFlzr opened this issue Mar 6, 2021 · 9 comments · Fixed by #544
Labels

Comments

@GrygrFlzr
Copy link
Member

GrygrFlzr commented Mar 6, 2021

This is caused by Vite loading two separate svelte runtimes which causes things like setContext to fail. There is no workaround, as this requires a change in Vite's import normalization.


Describe the bug
Starting a new project using the main branch of kit results in an overlay error, and the component isn't interactive.

Logs
Browser console

[HMR][Svelte] Unrecoverable error in <Root>: next update will trigger a full reload

Overlay error

Failed to init component
<Root>
Error: Function called outside component initialization
    at get_current_component (http://localhost:3000/node_modules/.pnpm/svelte@3.35.0/node_modules/svelte/internal/index.mjs?v=66871719:649:15)
    at setContext (http://localhost:3000/node_modules/.pnpm/svelte@3.35.0/node_modules/svelte/internal/index.mjs?v=66871719:679:5)
    at instance (http://localhost:3000/.svelte/dev/generated/root.svelte?import:480:2)
    at init (http://localhost:3000/@fs/Users/GrygrFlzr/Documents/projects/sk-451/node_modules/.pnpm/svelte@3.35.0/node_modules/svelte/internal/index.mjs?v=66871719:1474:11)
    at new Root (http://localhost:3000/.svelte/dev/generated/root.svelte?import:574:3)
    at createProxiedComponent (http://localhost:3000/@fs/C:/Users/GrygrFlzr/Documents/projects/kit/node_modules/.pnpm/svelte-hmr@0.13.0-2_svelte@3.35.0/node_modules/svelte-hmr/runtime/svelte-hooks.js:245:9)
    at new ProxyComponent (http://localhost:3000/@fs/C:/Users/GrygrFlzr/Documents/projects/kit/node_modules/.pnpm/svelte-hmr@0.13.0-2_svelte@3.35.0/node_modules/svelte-hmr/runtime/proxy.js:240:20)
    at new Proxy<Root> (http://localhost:3000/@fs/C:/Users/GrygrFlzr/Documents/projects/kit/node_modules/.pnpm/svelte-hmr@0.13.0-2_svelte@3.35.0/node_modules/svelte-hmr/runtime/proxy.js:340:11)
    at Renderer.start (http://localhost:3000/.svelte/dev/runtime/internal/start.js:431:15)
    at async start (http://localhost:3000/.svelte/dev/runtime/internal/start.js:763:2)

To Reproduce
In the kit monorepo:

pnpm i
pnpm -r build

In another project folder:

npm init svelte@next
# no to typescript, use css

Point package.json's @sveltejs/kit to the path of the kit package:

{
  // ...
  "devDependencies": {
    "@sveltejs/kit": "file:~/Documents/projects/kit/packages/kit",
    // ...
  },
  // ...
}

Then install the dependencies and run dev:

pnpm i --shamefully-hoist
pnpm dev

Expected behavior
No errors

Information about your SvelteKit Installation:

@sveltejs/kit commit 055a822

  System:
    OS: Windows 10 10.0.19042
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 12.08 GB / 31.95 GB
  Binaries:
    Node: 14.15.3 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 7.6.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 88.0.4324.190
    Edge: Spartan (44.19041.423.0), Chromium (88.0.705.74)
    Internet Explorer: 11.0.19041.1
  npmPackages:
    @sveltejs/kit: file:~/Documents/projects/kit/packages/kit => 1.0.0-next.37
    svelte: ^3.29.0 => 3.35.0

Severity
Unusable.

Additional context
pnpm is required to support the monorepo linking.

I'm not entirely sure what's Windows-specific about this issue, but our CI seems to report success for the Ubuntu tests: https://github.com/sveltejs/kit/runs/2046784747

@rixo
Copy link

rixo commented Mar 7, 2021

I can confirm I see that on Windows, not Linux.

Apparently one Svelte runtime is resolved / rewritten by Vite from "inside Vite's project root", whereas another one is resolved from "outside", resulting in an import ULR for /node_modules/svelte/internal/index.mjs vs @fs/.../internal/index.mjs.

The @fs/... absolute imports are apparently from the .svelte components (root.svelte), while the relative one comes from other Svelte runtime modules (store/index.mjs).

Those are only casual observations for now, because I have a hell of a hard time debugging on Windows, but it feels like Vite is doing something like if (importPath.startsWith(rootProjectPath)) rewriteToRelativeUrl() else rewriteToAbsoluteUrl() and, on Windows, maybe there's a slash vs backslash difference between importPath and rootProjectPath, somehow, and so thre's a mismatch.

Maybe it's our fault, sending backslashes and slashes on different occasions, but I still feel this difference should be ironed out on Windows, at Vite level, so maybe there would be something to do there as well.

@rixo
Copy link

rixo commented Mar 7, 2021

Closing in on the cause. In the end, it's not a backslash, it's a C:.

It happens here. Vite transforms paths inside project root (i.e. Vite's config.root) to short URLs relative to project root, and all the other paths to "absolute" URLs of the form /@fs/absolute/path/to/the/file.

Vite sees its project root as C:/something.

The problem is, for the the same file, it sometime receives the path as /path/to/file and sometime as C:/path/to/file, and so casts them to different URLs. This results in duplicated versions of the same module in the browser.

In our case, it sees svelte/internal resolved to path /something/..., whereas it sees relative ./internal (from inside svelte/internal.mjs resolved to path C:/something/.... So it cast one of them to an absolute /@fs/... URL (incorrectly), and the other one to a short "project root relative" URL. That's why we end up with 2 Svelte runtime in the browser. To confirm, I have changed the import in svelte/index.mjs to svelte/internal, and it fixed the bug reported here.

In fact, it seems that on Windows most "inside root" paths are incorrectly cast to absolute URLs of the /@fs/... form, but that's probably transparent in most cases.

This means the bug fix probably belongs neither in Kit, nor in the Vite plugin. I'm not sure where it really belongs, but I have a strong suspicion that it is in @rollup/plugin-node-resolve, for sometime resolving paths to C:/ and other times to just / (not verified). I suppose the correct ones are the complete C:/ ones, otherwise there would be collisions across drives.

This also means this bug should not be specific to pnpm. @GrygrFlzr can you check if you have this same problem with yarn or npm?

@GrygrFlzr
Copy link
Member Author

Thanks to @rixo's findings I managed to repro this using:

  • vite
  • svelte
  • svelte-hmr
  • @svitejs/vite-plugin-svelte

Without needing kit. See https://github.com/GrygrFlzr/vite-windows-imports which reproduces this with all three (npm / yarn / pnpm).

@GrygrFlzr
Copy link
Member Author

Here's the full dependency tree of the minimal repro above:

Dependency Tree
devDependencies:
@svitejs/vite-plugin-svelte 0.10.0-0
├─┬ @rollup/pluginutils 4.1.0
│ ├── estree-walker 2.0.2
│ └── picomatch 2.2.2
├─┬ chalk 4.1.0
│ ├─┬ ansi-styles 4.3.0
│ │ └─┬ color-convert 2.0.1
│ │   └── color-name 1.1.4
│ └─┬ supports-color 7.2.0
│   └── has-flag 4.0.0
├─┬ debug 4.3.1
│ └── ms 2.1.2
├── hash-sum 2.0.0
├── require-relative 0.8.7
├── slash 3.0.0
├── source-map 0.7.3
├── svelte 3.35.0 peer
├─┬ svelte-hmr 0.13.0-2
│ └── svelte 3.35.0 peer
└─┬ vite 2.0.5 peer
  ├── esbuild 0.8.56
  ├── fsevents 2.3.2
  ├─┬ postcss 8.2.7
  │ ├── colorette 1.2.2
  │ ├── nanoid 3.1.20
  │ └── source-map 0.6.1
  ├─┬ resolve 1.20.0
  │ ├─┬ is-core-module 2.2.0
  │ │ └─┬ has 1.0.3
  │ │   └── function-bind 1.1.1
  │ └── path-parse 1.0.6
  └─┬ rollup 2.40.0
    └── fsevents 2.3.2
@types/express 4.17.11
├─┬ @types/body-parser 1.19.0
│ ├─┬ @types/connect 3.4.34
│ │ └── @types/node 14.14.32
│ └── @types/node 14.14.32
├─┬ @types/express-serve-static-core 4.17.18
│ ├── @types/node 14.14.32
│ ├── @types/qs 6.9.6
│ └── @types/range-parser 1.2.3
├── @types/qs 6.9.6
└─┬ @types/serve-static 1.13.9
  ├── @types/mime 1.3.2
  └── @types/node 14.14.32
express 4.17.1
├─┬ accepts 1.3.7
│ ├─┬ mime-types 2.1.29
│ │ └── mime-db 1.46.0
│ └── negotiator 0.6.2
├── array-flatten 1.1.1
├─┬ body-parser 1.19.0
│ ├── bytes 3.1.0
│ ├── content-type 1.0.4
│ ├─┬ debug 2.6.9
│ │ └── ms 2.0.0
│ ├── depd 1.1.2
│ ├─┬ http-errors 1.7.2
│ │ ├── depd 1.1.2
│ │ ├── inherits 2.0.3
│ │ ├── setprototypeof 1.1.1
│ │ ├── statuses 1.5.0
│ │ └── toidentifier 1.0.0
│ ├─┬ iconv-lite 0.4.24
│ │ └── safer-buffer 2.1.2
│ ├─┬ on-finished 2.3.0
│ │ └── ee-first 1.1.1
│ ├── qs 6.7.0
│ ├─┬ raw-body 2.4.0
│ │ ├── bytes 3.1.0
│ │ ├─┬ http-errors 1.7.2
│ │ │ ├── depd 1.1.2
│ │ │ ├── inherits 2.0.3
│ │ │ ├── setprototypeof 1.1.1
│ │ │ ├── statuses 1.5.0
│ │ │ └── toidentifier 1.0.0
│ │ ├─┬ iconv-lite 0.4.24
│ │ │ └── safer-buffer 2.1.2
│ │ └── unpipe 1.0.0
│ └─┬ type-is 1.6.18
│   ├── media-typer 0.3.0
│   └─┬ mime-types 2.1.29
│     └── mime-db 1.46.0
├─┬ content-disposition 0.5.3
│ └── safe-buffer 5.1.2
├── content-type 1.0.4
├── cookie 0.4.0
├── cookie-signature 1.0.6
├─┬ debug 2.6.9
│ └── ms 2.0.0
├── depd 1.1.2
├── encodeurl 1.0.2
├── escape-html 1.0.3
├── etag 1.8.1
├─┬ finalhandler 1.1.2
│ ├─┬ debug 2.6.9
│ │ └── ms 2.0.0
│ ├── encodeurl 1.0.2
│ ├── escape-html 1.0.3
│ ├─┬ on-finished 2.3.0
│ │ └── ee-first 1.1.1
│ ├── parseurl 1.3.3
│ ├── statuses 1.5.0
│ └── unpipe 1.0.0
├── fresh 0.5.2
├── merge-descriptors 1.0.1
├── methods 1.1.2
├─┬ on-finished 2.3.0
│ └── ee-first 1.1.1
├── parseurl 1.3.3
├── path-to-regexp 0.1.7
├─┬ proxy-addr 2.0.6
│ ├── forwarded 0.1.2
│ └── ipaddr.js 1.9.1
├── qs 6.7.0
├── range-parser 1.2.1
├── safe-buffer 5.1.2
├─┬ send 0.17.1
│ ├─┬ debug 2.6.9
│ │ └── ms 2.0.0
│ ├── depd 1.1.2
│ ├── destroy 1.0.4
│ ├── encodeurl 1.0.2
│ ├── escape-html 1.0.3
│ ├── etag 1.8.1
│ ├── fresh 0.5.2
│ ├─┬ http-errors 1.7.3
│ │ ├── depd 1.1.2
│ │ ├── inherits 2.0.4
│ │ ├── setprototypeof 1.1.1
│ │ ├── statuses 1.5.0
│ │ └── toidentifier 1.0.0
│ ├── mime 1.6.0
│ ├── ms 2.1.1
│ ├─┬ on-finished 2.3.0
│ │ └── ee-first 1.1.1
│ ├── range-parser 1.2.1
│ └── statuses 1.5.0
├─┬ serve-static 1.14.1
│ ├── encodeurl 1.0.2
│ ├── escape-html 1.0.3
│ ├── parseurl 1.3.3
│ └─┬ send 0.17.1
│   ├─┬ debug 2.6.9
│   │ └── ms 2.0.0
│   ├── depd 1.1.2
│   ├── destroy 1.0.4
│   ├── encodeurl 1.0.2
│   ├── escape-html 1.0.3
│   ├── etag 1.8.1
│   ├── fresh 0.5.2
│   ├─┬ http-errors 1.7.3
│   │ ├── depd 1.1.2
│   │ ├── inherits 2.0.4
│   │ ├── setprototypeof 1.1.1
│   │ ├── statuses 1.5.0
│   │ └── toidentifier 1.0.0
│   ├── mime 1.6.0
│   ├── ms 2.1.1
│   ├─┬ on-finished 2.3.0
│   │ └── ee-first 1.1.1
│   ├── range-parser 1.2.1
│   └── statuses 1.5.0
├── setprototypeof 1.1.1
├── statuses 1.5.0
├─┬ type-is 1.6.18
│ ├── media-typer 0.3.0
│ └─┬ mime-types 2.1.29
│   └── mime-db 1.46.0
├── utils-merge 1.0.1
└── vary 1.1.2
svelte 3.35.0
svelte-hmr 0.12.9
└── svelte 3.35.0 peer
vite 2.0.5
├── esbuild 0.8.56
├── fsevents 2.3.2
├─┬ postcss 8.2.7
│ ├── colorette 1.2.2
│ ├── nanoid 3.1.20
│ └── source-map 0.6.1
├─┬ resolve 1.20.0
│ ├─┬ is-core-module 2.2.0
│ │ └─┬ has 1.0.3
│ │   └── function-bind 1.1.1
│ └── path-parse 1.0.6
└─┬ rollup 2.40.0
  └── fsevents 2.3.2

@rollup/plugin-node-resolve is not in the tree - does vite inline it out or something?

@GrygrFlzr
Copy link
Member Author

GrygrFlzr commented Mar 7, 2021

So to sum up:

Importing svelte/internal from @svitejs/vite-plugin-svelte and from svelte-hmr is resolved as /node_modules/svelte/internal/index.mjs

Importing ./internal/index.mjs from inside svelte/index.mjs is resolved as /@fs/Users/GrygrFlzr/Documents/projects/vite-windows-imports/node_modules/svelte/internal/index.mjs

Does this narrow it down to being an issue with vite?
EDIT: I filed an issue at vitejs/vite#2422

@rixo
Copy link

rixo commented Mar 7, 2021

It might be worth making Vite aware of the Windows specific issue but I still believe it's a problem in @rollup/plugin-node-resolve. Those missing C:/ paths seem incorrect to me, and I believe they come from there. If so, Vite couldn't do anything to fix it, except assume any absolute looking path come from the same drive, which would be shaky.

I'm looking to see if I can make a very minimal repro with just this plugin.

@rixo
Copy link

rixo commented Mar 7, 2021

Hmm... After some quick experimentation, both Rollup and @rollup/plugin-node-resolve seem pretty consistent in resolving paths with the expected C:. So the problem may come from another resolve plugin in the end, maybe one injected by Vite itself?

Don't have much more time to investigate right now... But I think it's a good thing that there's an issue in Vite's tracker.

@rixo
Copy link

rixo commented Mar 7, 2021

@rollup/plugin-node-resolve is not in the tree - does vite inline it out or something?

I missed your earlier comment (shouldn't do things in a hurry 😅 ). Indeed it's not in there... I don't know if Vite is bundling it or reimplementing it. Rather seems the latter, since they apparently behave differently.

@benmccann
Copy link
Member

PR pending for this at vitejs/vite#2435

@benmccann benmccann pinned this issue Mar 12, 2021
@benmccann benmccann changed the title Windows - Error: Function called outside component initialization Windows Error: Function called outside component initialization Mar 12, 2021
@GrygrFlzr GrygrFlzr added this to the public beta milestone Mar 14, 2021
@benmccann benmccann mentioned this issue Mar 15, 2021
@benmccann benmccann unpinned this issue Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants