question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature: Generalized `ssrLoadModule()`

See original GitHub issue

Clear and concise description of the problem

Vite uses html files as entry points at both dev and build time. I created a plugin that abstracts this by generating the html content with an esm module before vite internally transforms it. During dev, is relies on ViteDevServer.ssrLoadModule() as if it was a form of dynamic import() but with vite transforms and fast invalidation.

But there are two major problems that get in the way of many important plugin use cases:

  1. ssrLoadModule() was made to load “client-type” code in node, failing to load anything like import fs from "fs/promises" (within the normal vite dev configuration, at least). require() will not work as a substitute for ssrLoadModule().
  2. ssrLoadModule() relies on a ViteDevServer, meaning that there is no way to apply its value (of applying vite transforms to e.g. (j|t)sx? modules) during vite’s build mode.

This has forced my plugin into a corner of only being able to work with vanilla node during build time and not being allowed to import any node api’s (even dynamically within an if (false) block!) during dev time. This makes my “lowest common denominator” allowed code almost useless, for arbitrary reasons.

Suggested solution

Snowpack has already declared the intention of moving towards fully generalized node SSR, which is exactly what we need. The best solution is basically to integrate what my plugin was aiming to implement directly into vite (abstract index.html as the entry point). But the easiest solution is to simply generalize ssrLoadModule() into a version that:

  1. Explicitly is made to load anything that vite can process as if it were just a dynamic import() of node esm
  2. Works with a module graph that does not necessarily have to be inside a ViteDevServer, enabling its usage within e.g. a build plugin’s load() hook just as easily as in dev server middleware

Alternative

I hacked together a vite-incompatible function that simply built a temporary node esm file out of my prerendering code (including JSX) using esbuild and import()ed that file as file:/temporarily/built/module.mjs?cache-buster=Math.random(). It worked exactly how I expected as a proof of concept, with the only issues being efficiency for caching/invalidation (vite’s module graph is valuable here) and that it was incompatible with vite’s plugins (I had to hack the jsxInject, any variable define’s, and had no automatic path rebasing).

Obviously, a vite-native version would be far more streamlined and allow for many more useful plugin applications.

Additional context

No response

Validations

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
bluwycommented, Mar 12, 2022

Hi @wlib. I wonder if this feature request still needed?

  1. ssrLoadModule() was made to load “client-type” code in node, failing to load anything like import fs from "fs/promises" (within the normal vite dev configuration, at least). require() will not work as a substitute for ssrLoadModule().

ssrLoadModule is able to load node-only code with import fs from "fs/promises" IIRC, so this should work today.

2. ssrLoadModule() relies on a ViteDevServer, meaning that there is no way to apply its value (of applying vite transforms to e.g. (j|t)sx? modules) during vite’s build mode.

Transforming files in build mode should use normal Vite plugins as you have more control of how the final build output/chunks comes out. I don’t quite understand how ssrLoadModule should affect build mode? Hope you can clarify more on that.

I think ultimately the ecosystem has grown a lot recently on this area, especially with Vitest spearheading the usage of Vite’s SSR transforms in NodeJS. For example, vite-node is used to power Vitest by leveraging Vite as a Node runtime.

0reactions
bluwycommented, Jun 26, 2022

Closing due to lack of response, but I think the above comment covers what this issue is proposing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Preparing SSR for General Availability: Problematic ... - GitHub
Able to provide specific reproduction of a dependency having issues in SSR; Are an SSR/SSG implementor and require features to be implemented into...
Read more >
Server-Side Rendering - Vite
Produce a client build as normal;; Produce an SSR build, which can be directly loaded via import() so that we don't have to...
Read more >
require is not defined vite | The Search Engine You Control
You.com is an ad-free, private search engine that you control. Customize search results with 150 apps alongside web results. Access a zero-trace private ......
Read more >
Recommended - SlideShare
assetsInclude : A function to check if an id is considered an asset. build Type Signature: Example Usage: * Load a given URL...
Read more >
What About Vite SSR? - JavaScript in Plain English
ssrLoadModule to read the SSR server entry file and return the function to ... In general, entry-server.js is a function only responsible for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found