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

Don't throw unreplaced macro when running without Vite #19

Open
gustavopch opened this issue Jan 24, 2024 · 2 comments · May be fixed by #42
Open

Don't throw unreplaced macro when running without Vite #19

gustavopch opened this issue Jan 24, 2024 · 2 comments · May be fixed by #42

Comments

@gustavopch
Copy link

gustavopch commented Jan 24, 2024

I am using serverOnly$ to ensure Vite doesn't bundle a function that's supposed to be executed on the server. But I actually also need to run that function in a simple Node.js script that doesn't use Vite. When I run my script, I get this error:

Error: vite-env-only: unreplaced macro

Did you forget to add the 'vite-env-only' plugin to your Vite config?

So I propose that that error is only thrown when running via Vite.

Not sure if there's a better way to check, but possibly something like this:

 const maybe = <T>(_: T): T | undefined => {
+  const usingVite = import.meta.env &&
+    'MODE' in import.meta.env &&
+    'BASE_URL' in import.meta.env &&
+    'PROD' in import.meta.env &&
+    'DEV' in import.meta.env &&
+    'SSR' in import.meta.env
+
+  if (!usingVite) {
+    return _;
+  }
+
   throw Error(
     [
       `${pkgName}: unreplaced macro`,
       "",
       `Did you forget to add the '${pkgName}' plugin to your Vite config?`,
       "👉 https://github.com/pcattori/vite-env-only?tab=readme-ov-file#installation",
     ].join("\n"),
   )
 }
@bradymwilliams
Copy link

bradymwilliams commented Apr 2, 2024

diff --git a/node_modules/vite-env-only/dist/index.js b/node_modules/vite-env-only/dist/index.js
index 440090b..2fdec0f 100644
--- a/node_modules/vite-env-only/dist/index.js
+++ b/node_modules/vite-env-only/dist/index.js
@@ -280,6 +280,16 @@ var transform = (code, id, options) => {
 
 // src/macro.ts
 var maybe = (_) => {
+    const usingVite = import.meta.env &&
+    'MODE' in import.meta.env &&
+    'BASE_URL' in import.meta.env &&
+    'PROD' in import.meta.env &&
+    'DEV' in import.meta.env &&
+    'SSR' in import.meta.env
+
+    if (!usingVite) {
+    return _;
+  }
   throw Error(
     [
       `${name}: unreplaced macro`,

thanks, added a patch for 2.2.0 using your fix

@pcattori
Copy link
Owner

Originally, I hesitated to implement this feature since it felt like the error provided a base layer of safety.
But when I tried to define what I meant by "safety" I realized that the error doesn't actually prevent the code from being included in the module graph.
It only replaces the runtime error, but not the code shipped to that environment.

An alternative I thought of was to have unsafe_serverOnly$(...) or serverOnly$(..., { unsafe: true }) or something like that.
But that means opting in or out of safety where the macro is used, which is the wrong place; the whole point is that the same macro gets accessed sometimes from within Vite and sometimes outside of Vite.

Another option would be to have a VITE_ENV_ONLY=server or similar env var so that the error is only thrown when the macro is used outside of the expected env. But again, this doesn't prevent code from being included in the module graph.

So to summarize, I think you're right that a simple runtime check for Vite is the best approach. If you are using the Vite plugin, things continue to work the same way. If you aren't using the Vite plugin, there's no bundling going on so there's no module graph artifact to try to protect in the first place.

@pcattori pcattori linked a pull request May 24, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants