laravel / precognition

Anticipate the outcome of a future HTTP request.
https://laravel.com/docs/precognition
MIT License
134 stars 33 forks source link

Module not found when build SSR with laravel inertia react #30

Closed hendivalon closed 1 year ago

hendivalon commented 1 year ago

Laravel Precognition Plugin Version

0.3.2

Laravel Version

10.14.1

Plugin

React w/ Inertia

Description

No issue using client side. But in SSR, I found this problem when using the package. I just install fresh laravel with inertia-react as test project then install the precognation

See below :

Inertia SSR server started.
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/hendi/Sites/testing/node_modules/laravel-precognition/dist/client' imported from /Users/hendi/Sites/testing/node_modules/laravel-precognition/dist/index.js
    at new NodeError (node:internal/errors:399:5)
    at finalizeResolution (node:internal/modules/esm/resolve:326:11)
    at moduleResolve (node:internal/modules/esm/resolve:945:10)
    at defaultResolve (node:internal/modules/esm/resolve:1153:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Steps To Reproduce

Here i just done

jessarcher commented 1 year ago

Hi @hendivalon,

This seems to be related to Vite externalizing SSR dependencies.

If I add the following to vite.config.js, then it resolves the error for me.

  export default defineConfig({
      // ...

+     ssr: {
+         noExternal: [
+             'laravel-precognition',
+             'laravel-precognition-react',
+             'laravel-precognition-react-inertia',
+         ],
+     }
});

I'll have a chat with @timacdonald and see if there's something we can do to prevent needing this, otherwise, we could potentially apply it automatically in the Laravel Vite plugin.

timacdonald commented 1 year ago

I can't see any reason for needing this, however I also am unable to diagnose why this is happening.

If I manually change the import to include a file extension, it seems to fix SSR.

- export { client } from './client';
+ export { client } from './client.js';

But I again have no idea why this would be the case.

I would appreciate assistance if anyone has any ideas on this one.

irsyadadl commented 1 year ago

Honestly @timacdonald, I have made it since inertia ssr out. Just like this all time on every project, vite.config.js.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.tsx',
            ssr: 'resources/js/ssr.tsx',
            refresh: true,
        }),
        react(),
    ],
    build: {
        chunkSizeWarningLimit: 1500,
    },
    ssr: {
        noExternal: [
            '@uiw/react-md-editor',
            'react-markdown',
            '@uiw/react-markdown-preview',
            'lodash',
            '@tabler/icons-react',
            'react-share',
            'react-copy-to-clipboard',
            'laravel-precognition',
            'laravel-precognition-react',
            'laravel-precognition-react-inertia',
        ],
    },
});
timacdonald commented 1 year ago

There must be something about these dependencies that means they can't be externalised, though?

We have complete control over precognition, so I would like to address the issue so we don't have to do this. I just don't know what the thing that we need to do is! haha

irsyadadl commented 1 year ago

Okay, I totally understand what you saying.

chunterb commented 1 year ago

I believe this comes down to the runtime difference. SSR uses Node behind the scenes. When using ESM with Node, you are required to add file extensions when using import.

This is done automatically for you when run client-side only. Hence why we're not getting an error outside of SSR.

Check this out - https://nodejs.org/api/esm.html#terminology.

NickSdot commented 1 year ago

I can't see any reason for needing this, however I also am unable to diagnose why this is happening.

If I manually change the import to include a file extension, it seems to fix SSR.


- export { client } from './client';

+ export { client } from './client.js';

But I again have no idea why this would be the case.

I would appreciate assistance if anyone has any ideas on this one.

Fyi, extension-less imports are basically deprecated / no longer supported.

Ref: https://github.com/vitejs/vite/issues/178#issuecomment-630138450

timacdonald commented 1 year ago

Thanks, @NickSdot! I spent far to long figuring this out, but we now have a fix up: https://github.com/laravel/precognition/pull/37

timacdonald commented 1 year ago

Gonna close this in favour of the PR. Thanks for the help, ya'll