lib/core-common/src/utils/envs.ts
import { getEnvironment } from 'lazy-universal-dotenv';
import { nodePathsToArray } from './paths';
// Load environment variables starts with STORYBOOK_ to the client side.
export function loadEnvs(options: { production?: boolean } = {}): {
stringified: Record<string, string>;
raw: Record<string, string>;
} {
const defaultNodeEnv = options.production ? 'production' : 'development';
const env: Record<string, string> = {
NODE_ENV: process.env.NODE_ENV || defaultNodeEnv,
NODE_PATH: process.env.NODE_PATH || '',
STORYBOOK: process.env.STORYBOOK || 'true',
// This is to support CRA's public folder feature.
// In production we set this to dot(.) to allow the browser to access these assets
// even when deployed inside a subpath. (like in GitHub pages)
// In development this is just empty as we always serves from the root.
PUBLIC_URL: options.production ? '.' : '',
};
Object.keys(process.env)
.filter((name) => /^STORYBOOK_/.test(name))
.forEach((name) => {
env[name] = process.env[name];
});
const base = Object.entries(env).reduce(
(acc, [k, v]) => Object.assign(acc, { [k]: JSON.stringify(v) }),
{} as Record<string, string>
);
const { stringified, raw } = getEnvironment({ nodeEnv: env.NODE_ENV });
const fullRaw = { ...env, ...raw };
fullRaw.NODE_PATH = nodePathsToArray(fullRaw.NODE_PATH || '');
return {
stringified: { ...base, ...stringified },
raw: fullRaw,
};
}
export const stringifyEnvs = (raw: Record<string, string>): Record<string, string> =>
Object.entries(raw).reduce<Record<string, string>>((acc, [key, value]) => {
acc[key] = JSON.stringify(value);
return acc;
}, {});
export const stringifyProcessEnvs = (raw: Record<string, string>): Record<string, string> => {
const envs = Object.entries(raw).reduce<Record<string, string>>(
(acc, [key, value]) => {
acc[`process.env.${key}`] = JSON.stringify(value);
return acc;
},
{
// Default fallback
'process.env.XSTORYBOOK_EXAMPLE_APP': '""',
}
);
// FIXME: something like this is necessary to support destructuring like:
//
// const { foo } = process.env;
//
// However, it also means that process.env.foo = 'bar' will fail, so removing this:
//
// envs['process.env'] = JSON.stringify(raw);
return envs;
};