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

[examples/express-react-vercel] Error on vike pre-rendering #48

Closed
rtritto opened this issue Jan 22, 2025 · 14 comments
Closed

[examples/express-react-vercel] Error on vike pre-rendering #48

rtritto opened this issue Jan 22, 2025 · 14 comments
Labels
bug Something isn't working

Comments

@rtritto
Copy link
Contributor

rtritto commented Jan 22, 2025

Forked vike-node/examples/express-react-vercel on repo https://github.com/rtritto/examples-vike-node-express-react-vercel.

[email protected]
[email protected]

After the first deploy on Vercel, on vike build, the vike pre-rendering fails. Build logs:

[12:30:31.174] Cloning github.com/rtritto/examples-vike-node-express-react-vercel (Branch: master, Commit: 861a3e0)
[12:30:31.494] Cloning completed: 321.000ms
[12:30:31.617] Previous build cache not available
[12:30:31.973] Running "vercel build"
[12:30:32.858] Vercel CLI 39.3.0
[12:30:33.785] Installing dependencies...
[12:30:57.572] npm warn deprecated [email protected]: This package is no longer supported.
[12:30:57.595] npm warn deprecated [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
[12:30:57.615] npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
[12:30:57.672] npm warn deprecated [email protected]: This package is no longer supported.
[12:30:57.733] npm warn deprecated [email protected]: Rimraf versions prior to v4 are no longer supported
[12:30:57.735] npm warn deprecated [email protected]: This package is no longer supported.
[12:30:59.692] 
[12:30:59.693] added 271 packages in 26s
[12:30:59.693] 
[12:30:59.693] 27 packages are looking for funding
[12:30:59.694]   run `npm fund` for details
[12:30:59.746] Running "npm run build"
[12:31:00.018] 
[12:31:00.019] > build
[12:31:00.019] > vike build
[12:31:00.019] 
[12:31:00.715] vite v5.4.14 building for production...
[12:31:00.757] transforming...
[12:31:02.880] 187 modules transformed.
[12:31:02.983] rendering chunks...
[12:31:03.084] computing gzip size...
[12:31:04.106] dist/client/_temp_manifest.json                                 2.65 kB │ gzip:  0.49 kB
[12:31:04.106] dist/client/assets/static/vike-react-b64a028b.BcWtY8Ol.css      0.06 kB │ gzip:  0.08 kB
[12:31:04.106] dist/client/assets/static/pages_Layout-69d9ce51.DPWg3fKn.css    0.11 kB │ gzip:  0.11 kB
[12:31:04.106] dist/client/assets/entries/pages_static.DGUtdkRV.js             1.28 kB │ gzip:  0.43 kB
[12:31:04.106] dist/client/assets/entries/pages_dynamic.DqB1NKBf.js            1.95 kB │ gzip:  0.70 kB
[12:31:04.107] dist/client/assets/entries/pages_index.DUmIcNGT.js              1.95 kB │ gzip:  0.69 kB
[12:31:04.108] dist/client/assets/chunks/chunk-DXne60Kj.js                     4.64 kB │ gzip:  2.08 kB
[12:31:04.111] dist/client/assets/entries/entry-client-routing.B82XtDxW.js    70.56 kB │ gzip: 22.60 kB
[12:31:04.112] dist/client/assets/chunks/chunk-sEzhbL0Y.js                   145.48 kB │ gzip: 47.33 kB
[12:31:04.113] ✓ built in 3.37s
[12:31:04.130] vite v5.4.14 building SSR bundle for production...
[12:31:04.135] transforming...
[12:31:04.187] ✓ 11 modules transformed.
[12:31:04.205] rendering chunks...
[12:31:04.214] dist/server/package.json                                      0.02 kB
[12:31:04.215] dist/server/_temp_manifest.json                               1.80 kB
[12:31:04.215] dist/server/assets/static/pages_Layout-69d9ce51.DPWg3fKn.css  0.11 kB
[12:31:04.215] dist/server/chunks/chunk-XaePnBNx.js                          1.54 kB
[12:31:04.215] dist/server/entries/pages_dynamic.mjs                         2.65 kB
[12:31:04.215] dist/server/entries/pages_index.mjs                           2.65 kB
[12:31:04.215] dist/server/entries/pages_static.mjs                          2.70 kB
[12:31:04.215] dist/server/index.mjs                                         4.89 kB
[12:31:04.216] ✓ built in 83ms
[12:31:04.217] vike v0.4.218 pre-rendering HTML...
[12:31:04.260] Error: [@brillout/[email protected]][Wrong Usage] Execute the server entry built for production (e.g. $ node dist/server/index.mjs). Don't execute the original server entry (e.g. $ ts-node server/index.ts) nor run $ vike preview.
[12:31:04.261]     at importServerProductionEntry (/vercel/path0/node_modules/@brillout/vite-plugin-server-entry/dist/runtime/importServerProductionEntry.js:13:29)
[12:31:04.261]     at loadImportBuild (file:///vercel/path0/node_modules/vike/dist/esm/node/runtime/globalContext/loadImportBuild.js:13:15)
[12:31:04.261]     at initGlobalContext (file:///vercel/path0/node_modules/vike/dist/esm/node/runtime/globalContext.js:174:36)
[12:31:04.261]     at initGlobalContext_runPrerender (file:///vercel/path0/node_modules/vike/dist/esm/node/runtime/globalContext.js:125:11)
[12:31:04.261]     at runPrerender (file:///vercel/path0/node_modules/vike/dist/esm/node/prerender/runPrerender.js:85:11)
[12:31:04.261]     at runPrerenderFromAutoRun (file:///vercel/path0/node_modules/vike/dist/esm/node/prerender/runPrerender.js:51:9)
[12:31:04.261]     at Module.build (file:///vercel/path0/node_modules/vike/dist/esm/node/api/build.js:20:9)
[12:31:04.261]     at cmdBuild (file:///vercel/path0/node_modules/vike/dist/esm/node/cli/entry.js:44:9)
[12:31:04.288] Error: Command "npm run build" exited with 1
[12:31:04.532] 

Reproduction

@rtritto
Copy link
Contributor Author

rtritto commented Jan 22, 2025

Is this issue related to #44?

@rtritto
Copy link
Contributor Author

rtritto commented Jan 22, 2025

@rtritto
Copy link
Contributor Author

rtritto commented Jan 22, 2025

Related code that throws:
https://github.com/brillout/vite-plugin-server-entry/blob/1f8bd218f1bb4ba63efe3551ec00fc49f2d2fbdd/src/runtime/crawlServerEntry.ts#L90-L93

Where:
distFileNameFound = 'index.mjs'
serverIndexFileNameBase = 'index'
tolerateNotFound = undefined

@brillout
Copy link
Member

brillout commented Jan 23, 2025

Let me finish my current priorities (which may very well be related to this issue), I'll then have a look at this. ETA this / beginning of next week.

@brillout
Copy link
Member

I can reproduce, let me have a look (today/tomorrow).

@brillout
Copy link
Member

Should be fixed in [email protected]. Let us know if you still run into any issues.

@rtritto
Copy link
Contributor Author

rtritto commented Jan 25, 2025

Now, with vike build, the file dist/server/entry.mjs is always generated even if Vike plugin for Vite doesn't have prerender option enabled.

Current

  • A.
    // vite.config.ts
    import vike from 'vike/plugin'
    
    export default {
      plugins: [
        vike()
      ]
    }
    vike build --> dist/server/entry.mjs
  • B.
    // vite.config.ts
    import vike from 'vike/plugin'
    
    export default {
      plugins: [
        vike({ prerender: true })
      ]
    }
    vike build --> dist/server/entry.mjs

Expected

The dist/server/entry.mjs file is used only for pre-rendering (case B.), so with A. case, it should not be generated.

Am I right?

@brillout
Copy link
Member

It cannot be known at build-time whether the Vike API prerender() will be called or not.

@rtritto
Copy link
Contributor Author

rtritto commented Jan 25, 2025

You can control with:

  1. share vikeVitePluginOptions (that contains prerender option) to buildEntry:

    vike/node/plugin/index.ts

    function plugin(vikeVitePluginOptions: VikeVitePluginOptions = {}): any {
      const plugins: Plugin[] = [
        // ...
    -    ...buildEntry(),
    +    ...buildEntry(vikeVitePluginOptions),
        // ...
      ]
      Object.assign(plugins, { __vikeVitePluginOptions: vikeVitePluginOptions })
      return plugins
    }
  2. pass prerender option to @brillout/vite-plugin-server-entry/plugin:

    /vike/node/plugin/plugins/buildEntry/index.ts

    import { serverProductionEntryPlugin } from '@brillout/vite-plugin-server-entry/plugin'
    //...
    -function buildEntry(): Plugin[] {  
    +function buildEntry(vikeVitePluginOptions: unknown): Plugin[] {
    
      let config: ResolvedConfig
      let vikeConfigGlobal: VikeConfigGlobal
      return [
        {
          name: 'vike:buildEntry',
          enforce: 'post',
          async configResolved(config_) {
            config = config_
            const vikeConfig = await getVikeConfig(config)
            vikeConfigGlobal = vikeConfig.vikeConfigGlobal
          }
        },
        ...serverProductionEntryPlugin({
    +      prerender: vikeVitePluginOptions.prerender,
          getServerProductionEntry: () => {
            return getServerProductionEntryCode(config, vikeConfigGlobal)
          },
          libraryName: 'Vike'
        })
      ]
    }
  3. handle the prerender option in @brillout/vite-plugin-server-entry

    vite-plugin-server-entry/src/plugin/index.ts

    type PluginConfigProvidedByLibrary = {
      getServerProductionEntry: () => string
      libraryName: string
      inject?: boolean | string[]
    +  prerender?: boolean
    }
    
    function serverProductionEntryPlugin(pluginConfigProvidedByLibrary: PluginConfigProvidedByLibrary): Plugin_[] {
      const pluginName = `@brillout/vite-plugin-server-entry:${pluginConfigProvidedByLibrary.libraryName.toLowerCase()}`
      // ...
      return [
        {
          name: pluginName,
          apply: 'build',
          // We need to run this plugin after other plugin instances, so that assertApiVersions() works also for libraries using older plugin versions
          enforce: 'post',
          configResolved() {
    
    -        // We always generate dist/server/entry.mjs even if `inject: true` because it's needed for pre-rendering: the server shouldn't start when pre-rendering starts.
    +        if (pluginConfigProvidedByLibrary.prerender) {
    +          // Generate dist/server/entry.mjs
            const serverEntryName = getServerEntryName(config)
            config.build.rollupOptions.input = injectRollupInputs({ [serverEntryName]: serverEntryVirtualId }, config)
    +        }
          },
        },
        // ...
      ] as Plugin[]
    }

@rtritto
Copy link
Contributor Author

rtritto commented Jan 26, 2025

As the prerender doc, the use cases are:

  • prerender all: vike/plugin({ prerender: true })
  • partial and conditional prerendering

For the second point, the dist/server/entry.mjs file should include only related pages with prerendering enabled.

@rtritto
Copy link
Contributor Author

rtritto commented Jan 26, 2025

@brillout what do you think about?

@brillout
Copy link
Member

It cannot be known at build-time whether the Vike API prerender() will be called or not.

For example prerender({ vikeConfig: { prerender: true } }).

@rtritto
Copy link
Contributor Author

rtritto commented Jan 27, 2025

This logic could be implemented:

  • vike/plugin({ prerender: true }) --> produce dist/server/entry.mjs (case where prerendering is always used)
  • vike/plugin({ prerender: false }) --> don't produce dist/server/entry.mjs (case where prerendering is never used)
  • vike/plugin() --> produce dist/server/entry.mjs (it's the partial/conditional/build-time rendering case where prerender({ vikeConfig: { prerender: true } }) can be use)

@brillout
Copy link
Member

Not sure, but I'll revisit this later — once I'm done with my current refactoring (which is related to all this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants