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

Use Process.env instead of Oxygen.env #1314

Open
wants to merge 3 commits into
base: v1.x-2022-07
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mean-guests-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/hydrogen': minor
---

Deprecate Oxygen.env. We now support process.env directly in server components in node and worker environments.
6 changes: 3 additions & 3 deletions .github/deployments/cloudflare/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ async function handleEvent(event) {
return await handleAsset(url, event);
}

// TODO: Switch to module syntax and transfer args to Oxygen.env
if (!globalThis.Oxygen) {
globalThis.Oxygen = {};
// TODO: Switch to module syntax and transfer args to process.env
if (!globalThis.process) {
globalThis.process = {env: {}};
}

return await handleRequest(event.request, {
Expand Down
6 changes: 3 additions & 3 deletions docs/framework/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ export default Component() {

### Private variables

In Hydrogen, any variable from `.env` files that isn't prefixed with `PUBLIC_` is treated as a server runtime variable in non-production environments. These variables aren't exposed to the browser and can only be accessed from server components using the global `Oxygen.env` object:
In Hydrogen, any variable from `.env` files that isn't prefixed with `PUBLIC_` is treated as a server runtime variable in non-production environments. These variables aren't exposed to the browser and can only be accessed from server components using the global `process.env` object:

{% codeblock file, filename: 'Page.server.jsx' %}

```
``` js
export default Page() {
const token = Oxygen.env.MY_SECRET_API_TOKEN
const token = process.env.MY_SECRET_API_TOKEN

// ...
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default (pluginOptions: HydrogenVitePluginOptions) => {
return await server.transformIndexHtml(url, indexHtml);
}

await polyfillOxygenEnv(server.config);
addEnvVarsToProcessEnv(server.config);

// The default vite middleware rewrites the URL `/graphqil` to `/index.html`
// By running this middleware first, we avoid that.
Expand Down Expand Up @@ -110,13 +110,8 @@ export default (pluginOptions: HydrogenVitePluginOptions) => {
} as Plugin;
};

declare global {
// eslint-disable-next-line no-var
var Oxygen: {env: any; [key: string]: any};
}

async function polyfillOxygenEnv(config: ResolvedConfig) {
const env = await loadEnv(config.mode, config.root, '');
function addEnvVarsToProcessEnv(config: ResolvedConfig) {
const env = loadEnv(config.mode, config.root, '');

const publicPrefixes = Array.isArray(config.envPrefix)
? config.envPrefix
Expand All @@ -125,10 +120,10 @@ async function polyfillOxygenEnv(config: ResolvedConfig) {
for (const key of Object.keys(env)) {
if (publicPrefixes.some((prefix) => key.startsWith(prefix))) {
delete env[key];
} else {
process.env[key] = env[key];
}
}

globalThis.Oxygen = {env};
}

async function findHydrogenConfigPath(root: string, userProvidedPath?: string) {
Expand Down
3 changes: 0 additions & 3 deletions packages/hydrogen/src/platforms/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ type CreateServerOptions = {
};

export async function createServer({cache}: CreateServerOptions = {}) {
// @ts-ignore
globalThis.Oxygen = {env: process.env};

const app = connect();

app.use(compression() as NextHandleFunction);
Expand Down
13 changes: 2 additions & 11 deletions packages/hydrogen/src/platforms/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,14 @@ import indexTemplate from '__INDEX_TEMPLATE__?raw';

const handleRequest = entrypoint as RequestHandler;

declare global {
// eslint-disable-next-line no-var
var globalThis: {
Oxygen: {env: any};
[key: string]: any;
};
}

export default {
async fetch(
request: Request,
env: unknown,
context: {waitUntil: (promise: Promise<any>) => void}
) {
if (!globalThis.Oxygen) {
globalThis.Oxygen = {env};
}
// @ts-ignore NodeJS.ProcessEnv is not relevant here, because we're in a Worker.
globalThis.process = {env};

try {
return (await handleRequest(request, {
Expand Down
3 changes: 2 additions & 1 deletion packages/hydrogen/src/streaming.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export const ssrRenderToReadableStream = _ssrRenderToReadableStream as (
) => Promise<ReadableStream<Uint8Array> & {allReady: Promise<void>}>;

export async function isStreamingSupported() {
return Boolean(globalThis.Oxygen?.env?.HYDROGEN_ENABLE_WORKER_STREAMING);
// TODO: Check if streaming is supported natively
return Boolean(process?.env?.HYDROGEN_ENABLE_WORKER_STREAMING);
}

export async function bufferReadableStream(
Expand Down
5 changes: 1 addition & 4 deletions packages/hydrogen/src/utilities/storefrontApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ export function getStorefrontApiRequestHeaders({
}) {
const headers = {} as Record<string, any>;

const secretToken =
typeof Oxygen !== 'undefined'
? Oxygen?.env?.[OXYGEN_SECRET_TOKEN_ENVIRONMENT_VARIABLE]
: null;
const secretToken = process.env[OXYGEN_SECRET_TOKEN_ENVIRONMENT_VARIABLE];

/**
* Only pass one type of storefront token at a time.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ export default function Env() {
try {
// This is replaced with a string at build time
publicVariable = import.meta.env.PUBLIC_VARIABLE;
// This one crashes because Oxygen is not defined in browser
privateVariable = import.meta.env.SSR ? '' : Oxygen.env.PRIVATE_VARIABLE;
// This one crashes because process is not defined in browser
privateVariable = import.meta.env.SSR ? '' : process.env.PRIVATE_VARIABLE;
} catch (error) {}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Env() {

<div className="secrets-server">
<div>PUBLIC_VARIABLE:{import.meta.env.PUBLIC_VARIABLE || ''}|</div>
<div>PRIVATE_VARIABLE:{Oxygen.env.PRIVATE_VARIABLE || ''}|</div>
<div>PRIVATE_VARIABLE:{process.env.PRIVATE_VARIABLE || ''}|</div>
</div>

<div className="secrets-client">
Expand Down
4 changes: 2 additions & 2 deletions packages/playground/test-utils/load-prod-env.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const {loadEnv} = require('vite');

module.exports.loadProdEnv = async function (cwd = __dirname) {
const env = await loadEnv('production', cwd, '');
module.exports.loadProdEnv = function (cwd = __dirname) {
const env = loadEnv('production', cwd, '');
Object.keys(env).forEach((key) => {
if (['VITE_', 'PUBLIC_'].some((prefix) => key.startsWith(prefix))) {
delete env[key];
Expand Down
7 changes: 3 additions & 4 deletions packages/playground/test-utils/start-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ const {loadProdEnv} = require('./load-prod-env');
function createServerWithEnv({cwd = process.cwd()} = {}) {
const {createServer} = require(path.join(cwd, 'dist', 'server'));

return loadProdEnv(cwd).then((env) => {
Object.assign(process.env, env);
return createServer();
});
const env = loadProdEnv(cwd);
Object.assign(process.env, env);
return createServer();
}

if (require.main === module) {
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/test-utils/start-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function createServer({root = process.cwd()} = {}) {
const mf = new Miniflare({
scriptPath: path.resolve(root, 'dist/worker/index.js'),
sitePath: path.resolve(root, 'dist/client'),
bindings: await loadProdEnv(root),
bindings: loadProdEnv(root),
});

const app = mf.createServer();
Expand Down
12 changes: 10 additions & 2 deletions packages/playground/test-utils/worker-entry.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import {getAssetFromKV} from '@cloudflare/kv-asset-handler';

export default function setup({handleRequest, indexTemplate}) {
// Mock Oxygen global
globalThis.Oxygen = {env: globalThis};
// TODO: Switch to module syntax and grab variables that way instead.
const varAllowList = ['PRIVATE_VARIABLE', 'HYDROGEN_ENABLE_WORKER_STREAMING'];

globalThis.process = {env: {}};

varAllowList.forEach((key) => {
if (globalThis[key]) {
process.env[key] = globalThis[key];
}
});

function isAsset(url) {
return /\.(png|jpe?g|gif|css|js|svg|ico|map)$/i.test(url.pathname);
Expand Down