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

Throws on reading import.meta.env.BASE_URL in Deno environment #1387

Closed
1 task
ben-laird opened this issue Jan 20, 2024 · 10 comments
Closed
1 task

Throws on reading import.meta.env.BASE_URL in Deno environment #1387

ben-laird opened this issue Jan 20, 2024 · 10 comments
Labels
upstream Issues that need to be addressed upstream in Astro or another library

Comments

@ben-laird
Copy link

What version of starlight are you using?

^0.16.0

What version of astro are you using?

^4.2.1

What package manager are you using?

pnpm

What operating system are you using?

Mac

What browser are you using?

Safari

Describe the Bug

Context

I'd like to use Starlight to make a docs site for a library I've published, but my repo uses Deno instead of Node, and I'd like to keep the docs site and the library code in the same repo.

Reproduction

  1. Clone the repo
  2. Run deno task dev (currently using Deno 1.39.4)
  3. Visit https://localhost:4321
  4. Error Cannot read properties of undefined (reading 'env')

Terminal logs:

Task dev deno run -A --unstable npm:astro dev
Re-optimizing dependencies because vite config has changed
13:53:12 [vite] Re-optimizing dependencies because vite config has changed

 astro  v4.2.1 ready in 1212 ms

┃ Local    http://localhost:4321/
┃ Network  use --host to expose

13:53:12 watching for file changes...
13:53:17 [ERROR] Cannot read properties of undefined (reading 'env')
  Stack trace:
    at /Users/benlaird/Desktop/Life/Projects/Dev/bug-squashing/withastro/astro-u1/node_modules/.deno/@astrojs+starlight@0.16.0/node_modules/@astrojs/starlight/utils/base.ts, <anonymous>:4:225
    [...] See full stack trace in the browser, or rerun with --verbose.

Full stack trace:

TypeError: Cannot read properties of undefined (reading 'env')
    at eval (/Users/benlaird/Desktop/Life/Projects/Dev/bug-squashing/withastro/astro-u1/node_modules/.deno/@astrojs+starlight@0.16.0/node_modules/@astrojs/starlight/utils/base.ts, <anonymous>:4:225)
    at async instantiateModule (file:///Users/benlaird/Desktop/Life/Projects/Dev/bug-squashing/withastro/astro-u1/node_modules/.deno/astro@4.2.1/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:50861:9)

Erroring file:

// node_modules/.deno/@astrojs+starlight@0.16.0/node_modules/@astrojs/starlight/utils/base.ts
import { stripLeadingSlash, stripTrailingSlash } from './path';

const base = stripTrailingSlash(import.meta.env.BASE_URL); // Deno language server errors here, "Property 'env' does not exist on type 'ImportMeta'."

/** Get the a root-relative URL path with the site’s `base` prefixed. */
export function pathWithBase(path: string) {
	path = stripLeadingSlash(path);
	return path ? base + '/' + path : base + '/';
}

/** Get the a root-relative file URL path with the site’s `base` prefixed. */
export function fileWithBase(path: string) {
	path = stripLeadingSlash(path);
	return path ? base + '/' + path : base;
}

Expectation

Simply, this reproduction repo should not throw any errors.

Note I'd like to submit a PR for this issue (this is a great project and I'd love to help), although I have very little idea where the error is truly happening, what with Deno, Vite, Astro, and Starlight all underpinning my code; I'm going to leave the Participation checkbox unchecked for now. In addition, I'm still fairly new to open source contributions, so I don't want to degrade the codebase in any way.

Thanks so much for your help!

Link to Minimal Reproducible Example

https://github.com/bug-squashing/starlight-u1

Participation

  • I am willing to submit a pull request for this issue.
@delucis
Copy link
Member

delucis commented Jan 22, 2024

Thanks for the issue @ben-laird!

import.meta.env is Vite’s way of exposing environment variables instead of process.env. Not sure if it not being defined is a known issue? Or if you need to tell Deno to allow access to those with --allow-env?

Officially, Astro does not support building with Deno (only deploying to a Deno server environment), so not sure how easy this will be to fix (I’ve never used Deno personally) — and may even need fixing further upstream in Vite as mentioned above.

@delucis delucis added the upstream Issues that need to be addressed upstream in Astro or another library label Jan 22, 2024
@ben-laird
Copy link
Author

ben-laird commented Jan 22, 2024

After a quick read of Deno's docs, import.meta.env probably will never be defined in a Deno environment. Deno instead uses a map-style way of representing env variables through Deno.Env. There's a chance the fix may just be to detect whether Deno or Node is running and inject environment variables in that way. I do agree that there should be an issue filed upstream with Vite about why import.meta.env is undefined in Deno, or why Deno apparently doesn't allow Vite to modify the import.meta namespace. What would you recommend I include in the Vite issue?

EDIT - Used this link and this as sources

@delucis
Copy link
Member

delucis commented Jan 23, 2024

It looks like Vite officially supports Deno, so if you can create a minimal reproduction that shows the import.meta.env missing there, I guess they'd take a look?

@ben-laird
Copy link
Author

I made a minimal reproduction using pure Vite, no other frameworks, and when running deno task dev in that repo, import.meta.env.BASE_URL was defined and was /, unlike in the Starlight version where the .env part was undefined.

Even funnier, when I changed that offending file in the Starlight minimal repro to use import.meta.url, a variable Deno provides, the error moved to a js file apparently using import.meta.env, although the exact line number was incorrect, so I could never find the problem.

On top of that, it's not even that Vite/Deno doesn't have access to environment variable logic, because the dev script in the Starlight minimal repro runs with all Deno permissions allowed (the -A flag); apparently whether it does or not doesn't matter, because in the Vite minimal repro the import.meta.env object worked just fine, despite the process being given none of Deno's permissions.

I don't even know if this is an upstream issue, because it seemingly does not reside with Vite.

@delucis
Copy link
Member

delucis commented Jan 23, 2024

when I changed that offending file in the Starlight minimal repro to use import.meta.url, a variable Deno provides, the error moved to a js file apparently using import.meta.env

Yeah, Starlight depends on import.meta.env in a few places both for BASE_URL and for a DEV flag. Thanks for testing with a simple Vite project — if import.meta.env is working there, my guess is that the issue lies with some extra logic Astro has for populating that.

@bluwy
Copy link
Member

bluwy commented Jan 23, 2024

It's currently failing in Deno because our env handling is referencing process.env.* via here, as process global doesn't exist in Deno, it's undefined, so accessing .env errors. I could make it work by injecting import process from 'node:process', but it's tricky to deconflict this if the user also wrote the import. Plus after getting this fixed, it's still erroring on:

Could not process image request: MissingSharp: Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.
    at loadSharp (/Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/assets/services/sharp.js, <anonymous>:19:11)
    at async Object.transform (/Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/assets/services/sharp.js, <anonymous>:31:15)
    at async Module.GET (/Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/assets/endpoint/node.js, <anonymous>:68:30)
    at async callEndpoint (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/core/endpoint/index.js:124:16)
    at async DevPipeline.#tryRenderRoute (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/core/pipeline.js:119:16)
    at async DevPipeline.renderRoute (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/core/pipeline.js:58:20)
    at async handleRoute (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/vite-plugin-astro-server/route.js:253:18)
    at async run (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/vite-plugin-astro-server/request.js:50:14)
    at async runWithErrorHandling (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/vite-plugin-astro-server/controller.js:64:5)
    at async handleRequest (file:///Users/bjorn/Work/repros/starlight-u1/node_modules/.deno/astro@4.2.3/node_modules/astro/dist/vite-plugin-astro-server/request.js:44:3) {
  loc: undefined,
  title: "Could not find Sharp.",
  hint: "See Sharp's installation instructions for more information: https://sharp.pixelplumbing.com/install."... 383 more characters,
  frame: undefined,
  type: "AstroError",
  name: "MissingSharp"
}

Astro currently doesn't explicitly support Deno, so I think this isn't exactly a bug. There's likely more that needs tweaking if we want to get proper Deno support working.

@ben-laird
Copy link
Author

Can confirm this is a problem in Astro, not in Deno or Vite. I made another minimal reproduction, this time using only Astro. When running the dev server with Deno (using deno task dev) and explicitly using import.meta.env.BASE_URL in the markup, the dev server throws with the same error. Oddly, this does not go away when the markup in question is commented out. You'll see it commented out here in the minimal reproduction repo. I didn't realize Astro/remember Vite used inline string replacement to inject environment variables.

Here's a slice of the file where I invoked import.meta.env:

<!-- src/pages/index.astro -->
<!-- ... -->
		<h1>Welcome to <span class="text-gradient">Astro</span></h1>
		<p class="instructions">
			To get started, open the directory <code>src/pages</code> in your project.<br
			/>
			<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message
			above.
		</p>
		<!-- <p>import.meta.env.BASE_URL is {import.meta.env.BASE_URL}</p> -->
		<!-- ^ This throws the same error, even when commented out -->
<!-- ... -->

Hopefully this helps! Should I file an issue with Astro proper and use this minimal reproduction in my issue?

@delucis
Copy link
Member

delucis commented Jan 25, 2024

Thanks for the clarification @bluwy — appreciate it! And thank you for all the digging @ben-laird 💖

@ben-laird I think the team might be happy to merge small, low maintenance PRs that improve compatibility, but until Astro decides official Deno support is required, I guess they’re unlikely to take on long-term maintenance ensuring stability (this would require running test suites in Deno etc. and team members dogfooding Astro in Deno, so it’s not a small task). As such, issues will also likely be closed as Deno support would be considered a feature request not a bug. Probably the best path would be to chime in on the existing feature request — withastro/roadmap#97 — although someone like yourself who is a keen user would be invaluable in figuring out further wrinkles.

If I follow @bluwy’s suggestions, you might have some luck injecting that import process from 'node:process' somewhere and then could try using an alternative Image Service if Sharp is not supported (there are also some notes on getting Sharp to work in Deno that might help).

Given anything that would need changing to fix this would be upstream in Astro, I hope you don’t mind me closing this — unfortunately not much Starlight can do just yet.

@delucis delucis closed this as not planned Won't fix, can't repro, duplicate, stale Jan 25, 2024
@ben-laird
Copy link
Author

No offense taken on closing the issue, it really was an Astro thing anyways. I'll see what I can do on pushing for more dedicated Deno support, although I understand the commitment that would require, what with test suites and dogfooding and other things. I've tried injecting node:process in various places with no real luck, so I guess my only recourse is bringing more attention to supporting Deno in dev and not just production. Thanks so much @delucis and @bluwy for your help on this, I've really enjoyed working with you.

@einarmagnus
Copy link

I came across this problem too, wanting to run a small script to do some thing where I want that script to import some tooling I build for my astro site.

I ended up making it work like this (while also having to add .ts to all imports along along the way, which seems to work with no issues for astro):

let env;
if (Object.hasOwn(globalThis, "Deno")) {
  // hide from vite's analysis
  const url = Math.random().toString().slice(100)
    + "https://deno.land/std@0.216.0/dotenv/mod.ts";
  const { load } = await import(url);
  env = await load();
} else {
   env = import.meta.env || process.env;
}

this also meant adding a deno.json where I mirror my compilerOptions.paths from tsconfig.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upstream Issues that need to be addressed upstream in Astro or another library
Projects
None yet
Development

No branches or pull requests

4 participants