惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Security Latest
Security Latest
C
Cisco Blogs
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Secure Thoughts
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
D
Docker
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Recent Announcements
Recent Announcements
T
The Exploit Database - CXSecurity.com
G
Google Developers Blog
Schneier on Security
Schneier on Security
小众软件
小众软件
爱范儿
爱范儿
GbyAI
GbyAI
J
Java Code Geeks
T
Tailwind CSS Blog
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
B
Blog RSS Feed
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Y
Y Combinator Blog
S
Schneier on Security
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 叶小钗
F
Fortinet All Blogs
M
MIT News - Artificial intelligence
PCI Perspectives
PCI Perspectives
V
V2EX
V2EX - 技术
V2EX - 技术
O
OpenAI News
W
WeLiveSecurity

Bryan Robinson's Blog

Does our technology still work for us? Product pricing, dev bad habits, and the role of the pit of success Astro Server Island for latest Bluesky post (heavily cached!) New Website, but really is it? Netlify Durable Cache: Caching for a third-party world Introducing the Hygraph Astro Content Loader Integrating Astro.js Starlight Documentation into a Next.js Project Using Proxies Jamstack is meaningless 😱 Book Release: Eleventy by Example – Learn 11ty with 5 in-depth projects 11ty Second 11ty: Creating Template Filters 11ty Second 11ty: Global Data files (JS and JSON) 11ty second 11ty: The Render Plugin Part 1 Help needed: Netlify Frontend environment variables with Astro.js Quick experiment with the Slinkity 11ty plugin Creating a dynamic color converter with 11ty Serverless Using 11ty JavaScript Data files to mix Markdown and CMS content into one collection How to show your template code in 11ty blog posts New City, New Job, New Content Using Nunjucks Climbing the 11ty Performance leaderboard with Cloudinary, critical CSS and more Three JAMstack movements to watch in 2020 Create a Codepen promo watermark with no additional HTML, CSS or JS 3 underused CSS features to learn for 2020 Use CSS Subgrid to layout full-width content stripes in an article template Adapt client-side JavaScript for use in 11ty (Eleventy) data files CSS Gap creates a bright future for margins in Flex as well as Grid Create your first CSS Custom Properties (Variables) Use CSS Grid to create a self-centering full-width element Creating an 11ty Plugin - SVG Embed Tool Now offering design and code reviews at PeerReviews.dev Routing contact-form emails to different addresses with Netlify, Zapier and SendGrid Create an Eleventy (11ty) theme based on a free HTML template Client work and the JAMstack Grid vs. Flex: A Tale of a "Simple" Promo Space Using Eleventy The Tech Barrier to Entry What Can We Learn from CERN Let Practical CSS Grid - Launching My First Course Build Trust on the Web incorporating User Worries with your User Stories 2019 The Year of Markup-First Development Refactoring CSS into a Sass mixin Starting a new journey with Code Contemporary Dynamic Static Sites with Netlify and iOS Shortcuts Top 3 uses for the ::before and ::after CSS pseudo elements How To: Use CSS Grid to Mix and Match Design Patterns Use CSS ::before and ::after for simple, spicy image overlays Modern CSS: Four Things Every Developer and Designer Should Know About CSS 3 Strategies for Getting Started with CSS Grid CSS Tip: Use rotate() and skew() together to introduce some clean punk rock to your CSS The 5 Stages of Grid Love How To: A CSS-Only Mobile Off Canvas Navigation How To: Use CSS Grid Layout to Make a Simple, Fluid Card Grid Make a More Flexible Cover Screen with CSS Grid Can CSS Grid open up interesting CMS Layout options? Firefox 52 to Introduce New Box-Alignment Values Falling Forward — Rethinking Progressive Enhancement, Graceful Degradation and Developer Morality Start Exploring the Magic of CSS Grid Layout I Converted My Blog to CSS Grid Layout and Regret Nothing Feature Queries are on the Rise CSS Shapes — Let the Text Flow Around You Flexbox -- Let Memorializing Prince and Print vs. The Web I went to Italy and noticed UX fails How to Get Designers to Contribute in Open Source The True Gift of Your Former Code
Type-safe environment variables in Astro 5.0
2024-11-16 · via Bryan Robinson's Blog

Astro’s 5.0 beta has released a stable version of its astro:env module. This allows for developers to configure a schema for their environment variables and then take advantage of new feature this opens.

When checking the new features for Astro 5.0, I realized this is a continuation of the Astro team’s long-standing history of taking features that we as developers take as the status quo, and updating them with new features that allow for a better developer experience. To me, this is right up there with adding type checking to frontmatter in Markdown. I’d never have thought to improve that functionality on my own, but I have a better experience now that the feature is here.

Setup

Let’s talk about the setup for this feature. First and foremost, we need to be running Astro 5.0. This is currently in beta, but it’s very stable from what I’ve seen and Astro’s goal has been to get it to production by the end of the year.

If you’re starting from scratch, run the create command with these flags:

npm create astro@latest -- --ref next

If you’re upgrading an existing project run (while still in beta, otherwise just run upgrade):

npx @astrojs/upgrade beta

Other than the latest version of Astro, we also need a .env file in our project.

Here’s a sample that I’ll be using throughout the blog post.

API_URL=this is my string here anyone can have it 
ONLY_SERVER="this is my server string, but it will be in the bundle" 
SERVER_SECRET="this is a server string, that won't be bundled" 
NUMBER=13

Configuring your project with typed environment variables

With the addition of the .env file, we now have environment variables that can be used.

To use them, we use Vite’s default environment object: import.meta.env. Each of our variables is a property of that object. To take advantage of type checking and safety, we need to provide Astro with a schema to map each variable to its type. To do that, we create a new object in our astro.config.mjs file.

import { defineConfig, envField } from 'astro/config';

// https://astro.build/config
export default defineConfig({
    env: {
        schema: {
            API_URL: envField.string({
                context: "client", access: "public", optional: true
            }),
            NUMBER: envField.number({
                context: "client", access: "public"
            }),
            ONLY_SERVER: envField.string({
                context: "server", access: "public"
            }),
            SERVER_SECRET: envField.string({
                context: "server", access: "secret"
            }),
        }
    }
});

This lets Astro know a few things about each of the environment variables:

  • Its name: this should match the variable name in the .env file. The key of each property should match the key of the variable in .env
  • The type: This is done via the envField typing. .string() creates a string type; .number() a number type and so on. Available types: string, number, boolean, and enum (fun side note: enum lets you set acceptable values for the variable)
  • The context: This is either client or server and will allow you to receive errors if you try to use server variables in a client script
  • The access: Should this be public (all client variables) or should this be secret (things like API keys, etc.). A secret variable won’t be included in the bundle that Astro builds.
  • There’s also a HUGE number of additional options that we won’t cover in this post, but are really interesting. Things like setting default values, whether a string should be a URL, should it be optional, should a number be between certain values and more. Check out the reference docs for the 5.0 beta for more options.

At this point, we have type-safe environment variables for use. Let’s talk about putting them into our codebase.

Using type-safe environment variables in Astro contexts

It’s important to note, this only works in Astro contexts. Middlewares, routes, endpoints, components and modules. This won’t work in the configuration file itself or in non-Astro scripts.

We’ll take this at its basics and just use them in our /src/pages/index.astro route.

We start by importing the variables. This can be either in the frontmatter of the page or in a script for the client. We import them from the astro:env package, but from a “subdirectory” of the package that corresponds to either the client context or the server. This gives us plenty of clarity into what’s happening.

---
// import from the proper context
import {API_URL, NUMBER} from 'astro:env/client'
import {ONLY_SERVER, SERVER_SECRET} from "astro:env/server"

console.log({API_URL, ONLY_SERVER, SERVER_SECRET})
---

<script>
	/* This will throw a type error */
	import {SERVER_SECRET} from "astro:env/server"
	/* This will NOT throw a type error */
	import {API_URL} from 'astro:env/client'
	
	console.log(API_URL, SERVER_SECRET)
</script>

If you implement that as written, your frontend will throw a type error. Inside of a client <script> the import for /server isn’t allowed. Instead of just getting an “undefined” error, though, we get a proper type error that makes sense. Obviously, this is not what we want, so after testing, delete that from the client script.

Now to test things even more, go into your .env file and remove the SERVER_SECRET variable. The next time the site tries to build (you may need to restart the astro dev command locally), a type error will be thrown. This time, the fact that SERVER_SECRET is missing. Again, no question here. Everything is spelled out.

A bit of type coercion

Did you know that if you put a number in your environment variables that it’s actually a string? I hadn’t honestly thought about it, but it’s true.

Since we have a number in our .env file, let’s test it out.

In your index route, let’s get the NUMBER variable in the standard way and check the type.

---
import {NUMBER, BOOLEAN} from 'astro:env/client'
---

That’s a string!

Now, let’s compare it to importing via astro:env .

---
import {NUMBER, BOOLEAN} from 'astro:env/client'

console.log(typeof import.meta.env.NUMBER, typeof NUMBER)
---

That’s a number. Astro is handling our coercion for us! A handy extra piece of functionality.

Conclusion

Will this completely revolutionize your codebase? No. But it’s darn handy to have. I think the more I dive into the various options, the more I’ll see bigger applications for this.