1
0
mirror of synced 2025-12-19 09:57:57 -05:00

Load env variables based on APP_ENV or -e flag (#2878)

(minor)
This commit is contained in:
Aleksandra Sikora
2021-12-03 16:05:37 +01:00
committed by GitHub
parent 19ad91709e
commit 4aba0d31f6
50 changed files with 476 additions and 57 deletions

View File

@@ -15,6 +15,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
- name: Count size
uses: preactjs/compressed-size-action@v2
with:

View File

@@ -30,9 +30,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v14-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
@@ -74,9 +74,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v14-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
@@ -98,6 +98,10 @@ jobs:
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
- name: Setup kernel to increase watchers
if: runner.os == 'Linux'
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
@@ -120,6 +124,10 @@ jobs:
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
# Needed to get cypress binary
- run: yarn cypress install
- name: Install sass
@@ -157,9 +165,9 @@ jobs:
# path: |
# ${{ steps.yarn-cache-dir-path.outputs.dir }}
# **/node_modules
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-${{ hashFiles('yarn.lock') }}
# restore-keys: |
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
@@ -222,6 +230,10 @@ jobs:
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
# TODO: remove after we fix watchpack watching too much
- name: Setup kernel to increase watchers
@@ -256,9 +268,9 @@ jobs:
# path: |
# ${{ steps.yarn-cache-dir-path.outputs.dir }}
# **/node_modules
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-${{ hashFiles('yarn.lock') }}
# restore-keys: |
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
@@ -285,7 +297,10 @@ jobs:
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
# TODO: remove after we fix watchpack watching too much
- name: Setup kernel to increase watchers
if: runner.os == 'Linux'
@@ -318,9 +333,9 @@ jobs:
# path: |
# ${{ steps.yarn-cache-dir-path.outputs.dir }}
# **/node_modules
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
# key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-${{ hashFiles('yarn.lock') }}
# restore-keys: |
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
# ${{ runner.os }}-${{ runner.node_version}}-yarn-v14-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build

View File

@@ -4,6 +4,12 @@
## Notes For Core Team
### To Publish a new NPM Package under `@blitzjs/` namespace
1. cd into the package directory
2. Run `npm publish --tag danger --access public`
- `--access public` is required because scoped packages are set to private by default
### Syncing Next.js Fork
1. Run `yarn push-nextjs`

View File

@@ -1,5 +1,7 @@
process.env.NODE_ENV = "test"
require("dotenv-flow").config({ silent: true })
import { loadEnvConfig } from "@blitzjs/env"
loadEnvConfig()
import "./register-ts-paths"
import db from "db"

View File

@@ -3,4 +3,6 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom/extend-expect"
require("dotenv-flow").config({ silent: true })
import { loadEnvConfig } from "@blitzjs/env"
loadEnvConfig()

View File

@@ -1,3 +1,3 @@
# `@next/env`
# `@blitzjs/env`
Next.js' util for loading dotenv files in with the proper priorities

View File

@@ -66,7 +66,7 @@ export function processEnv(
}
export function loadEnvConfig(
dir: string,
dir: string = process.cwd(),
dev?: boolean,
log: Log = console
): {
@@ -79,8 +79,11 @@ export function loadEnvConfig(
const isTest = process.env.NODE_ENV === 'test'
const mode = isTest ? 'test' : dev ? 'development' : 'production'
const dotenvFiles = [
const appEnv = process.env.APP_ENV
let dotenvFiles = [
`.env.${mode}.local`,
appEnv && `.env.${appEnv}.local`,
appEnv && `.env.${appEnv}`,
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
@@ -106,7 +109,7 @@ export function loadEnvConfig(
path: envFile,
contents,
})
} catch (err) {
} catch (err: any) {
if (err.code !== 'ENOENT') {
log.error(`Failed to load env from ${envFile}`, err)
}

View File

@@ -1,7 +1,6 @@
{
"private": true,
"name": "@next/env",
"version": "11.1.0",
"name": "@blitzjs/env",
"version": "0.43.0",
"keywords": [
"react",
"next",
@@ -14,7 +13,7 @@
"url": "https://github.com/vercel/next.js",
"directory": "packages/next-env"
},
"author": "Next.js Team <support@vercel.com>",
"author": "Blitz.js",
"license": "MIT",
"main": "dist/index.js",
"types": "types/index.d.ts",

View File

@@ -30,10 +30,12 @@ const args = arg(
'--version': Boolean,
'--help': Boolean,
'--inspect': Boolean,
'--env': String,
// Aliases
'-v': '--version',
'-h': '--help',
'-e': '--env'
},
{
permissive: true,
@@ -61,6 +63,7 @@ if (!foundCommand && args['--help']) {
${Object.keys(commands).join(', ')}
Options
--env, -e App environment name
--version, -v Version number
--help, -h Displays this message
@@ -83,6 +86,10 @@ if (args['--help']) {
forwardedArgs.push('--help')
}
if (args['--env']) {
process.env.APP_ENV = args['--env']
}
const defaultEnv = command === 'dev' ? 'development' : 'production'
const standardEnv = ['production', 'development', 'test']

View File

@@ -8,7 +8,7 @@ import { normalizePagePath } from '../server/normalize-page-path'
import { warn } from './output/log'
import { ClientPagesLoaderOptions } from './webpack/loaders/next-client-pages-loader'
import { ServerlessLoaderQuery } from './webpack/loaders/next-serverless-loader'
import { LoadedEnvFiles } from '@next/env'
import { LoadedEnvFiles } from '@blitzjs/env'
import { convertPageFilePathToRoutePath } from './utils'
import { NextConfigComplete } from '../server/config-shared'

View File

@@ -1,4 +1,4 @@
import { loadEnvConfig } from '@next/env'
import { loadEnvConfig } from '@blitzjs/env'
import chalk from 'chalk'
import crypto from 'crypto'
import { promises, writeFileSync } from 'fs'

View File

@@ -90,7 +90,7 @@ const nextServerlessLoader: webpack.loader.Loader = function () {
)
const envLoading = `
const { processEnv } = require('@next/env')
const { processEnv } = require('@blitzjs/env')
processEnv(${Buffer.from(loadedEnvFiles, 'base64').toString()})
`

View File

@@ -37,7 +37,7 @@ import {
normalizePagePath,
denormalizePagePath,
} from '../server/normalize-page-path'
import { loadEnvConfig } from '@next/env'
import { loadEnvConfig } from '@blitzjs/env'
import { PrerenderManifest } from '../build'
import { PagesManifest } from '../build/webpack/plugins/pages-manifest-plugin'
import { getPagePath } from '../server/require'

View File

@@ -73,8 +73,8 @@
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/runtime": "7.12.5",
"@blitzjs/env": "0.43.0",
"@hapi/accept": "5.0.2",
"@next/env": "11.1.0",
"@next/polyfill-module": "11.1.0",
"@next/react-dev-overlay": "11.1.0",
"@next/react-refresh-utils": "11.1.0",

View File

@@ -1,4 +1,4 @@
import { loadEnvConfig } from '@next/env'
import { loadEnvConfig } from '@blitzjs/env'
import findUp from 'next/dist/compiled/find-up'
import { init as initWebpack } from 'next/dist/compiled/webpack/webpack'
import { CONFIG_FILE, PHASE_DEVELOPMENT_SERVER } from '../shared/lib/constants'

View File

@@ -14,7 +14,7 @@ import {
} from './config-shared'
import { loadWebpackHook } from './config-utils'
import { ImageConfig, imageConfigDefault, VALID_LOADERS } from './image-config'
import { loadEnvConfig } from '@next/env'
import { loadEnvConfig } from '@blitzjs/env'
import { hasNextSupport } from '../telemetry/ci-info'
const debug = require('debug')('blitz:config')

View File

@@ -82,7 +82,7 @@ import {
resultFromChunks,
resultToChunks,
} from './utils'
import { loadEnvConfig } from '@next/env'
import { loadEnvConfig } from '@blitzjs/env'
import './node-polyfill-fetch'
import { PagesManifest } from '../build/webpack/plugins/pages-manifest-plugin'
import { removePathTrailingSlash } from '../client/normalize-trailing-slash'

View File

@@ -2,7 +2,7 @@ import { formatUrl } from './router/utils/format-url'
import type { BuildManifest } from '../../server/get-page-files'
import type { ComponentType } from 'react'
import type { DomainLocale } from '../../server/config'
import type { Env } from '@next/env'
import type { Env } from '@blitzjs/env'
import type { IncomingMessage, ServerResponse } from 'http'
import type { NextRouter } from './router/router'
import type { ParsedUrlQuery } from 'querystring'

View File

@@ -12,7 +12,7 @@ import {
import webdriver from 'next-webdriver'
import { join } from 'path'
jest.setTimeout(1000 * 60 * 1)
jest.setTimeout(1000 * 60 * 3)
const appDir = join(__dirname, '../')

View File

@@ -0,0 +1,5 @@
PROCESS_ENV_KEY="env"
ENV_FILE_KEY=env
NEXT_PUBLIC_TEST_DEST=another
ENV_KEY_IN_NEXT_CONFIG="hello from next.config.js"
NEXT_PUBLIC_ENV_KEY_IN_NEXT_CONFIG="hello again from next.config.js"

View File

@@ -0,0 +1 @@
PRODUCTION_ENV_FILE_KEY=production

View File

@@ -0,0 +1,4 @@
NEXT_PUBLIC_TEST_DEST=staging-route
ENV_KEY_IN_NEXT_CONFIG="hello from staging app"
NEXT_PUBLIC_ENV_KEY_IN_NEXT_CONFIG="hello again from staging app"
ENV_FILE_DEVELOPMENT_OVERRIDE_TEST=staging

View File

@@ -0,0 +1 @@
ENV_FILE_DEVELOPMENT_OVERRIDE_TEST=staginglocal

View File

@@ -0,0 +1,17 @@
module.exports = {
cleanDistDir: false,
// update me
env: {
nextConfigEnv: process.env.ENV_KEY_IN_NEXT_CONFIG,
nextConfigPublicEnv: process.env.NEXT_PUBLIC_ENV_KEY_IN_NEXT_CONFIG,
},
async redirects() {
return [
{
source: '/hello',
permanent: false,
destination: `/${process.env.NEXT_PUBLIC_TEST_DEST}`,
},
]
},
}

View File

@@ -0,0 +1,4 @@
{
"name": "env-config-app-env",
"dependencies": {}
}

View File

@@ -0,0 +1,24 @@
const variables = [
'PROCESS_ENV_KEY',
'ENV_FILE_KEY',
'ENV_FILE_EMPTY_FIRST',
'PRODUCTION_ENV_FILE_KEY',
'LOCAL_PRODUCTION_ENV_FILE_KEY',
'ENV_FILE_DEVELOPMENT_OVERRIDE_TEST',
'ENV_FILE_PRODUCTION_OVERRIDEOVERRIDE_TEST',
'ENV_FILE_PRODUCTION_LOCAL_OVERRIDEOVERRIDE_TEST',
]
const items = {
nextConfigEnv: process.env.nextConfigEnv,
nextConfigPublicEnv: process.env.nextConfigPublicEnv,
}
variables.forEach((variable) => {
items[variable] = process.env[variable]
})
export default async (req, res) => {
// Only for testing, don't do this...
res.json(items)
}

View File

@@ -0,0 +1 @@
export default () => <p>{process.env.NEXT_PUBLIC_TEST_DEST}</p>

View File

@@ -0,0 +1,35 @@
const variables = [
'PROCESS_ENV_KEY',
'ENV_FILE_KEY',
'ENV_FILE_EMPTY_FIRST',
'PRODUCTION_ENV_FILE_KEY',
'LOCAL_PRODUCTION_ENV_FILE_KEY',
'ENV_FILE_DEVELOPMENT_OVERRIDE_TEST',
'ENV_FILE_PRODUCTION_OVERRIDEOVERRIDE_TEST',
'ENV_FILE_PRODUCTION_LOCAL_OVERRIDEOVERRIDE_TEST',
]
export async function getStaticProps() {
const items = {}
variables.forEach((variable) => {
if (process.env[variable]) {
items[variable] = process.env[variable]
}
})
return {
// Do not pass any sensitive values here as they will
// be made PUBLICLY available in `pageProps`
props: { env: items },
revalidate: 1,
}
}
export default ({ env }) => (
<>
<p>{JSON.stringify(env)}</p>
<div id="nextConfigEnv">{process.env.nextConfigEnv}</div>
<div id="nextConfigPublicEnv">{process.env.nextConfigPublicEnv}</div>
</>
)

View File

@@ -0,0 +1,35 @@
const variables = [
'PROCESS_ENV_KEY',
'ENV_FILE_KEY',
'ENV_FILE_EMPTY_FIRST',
'PRODUCTION_ENV_FILE_KEY',
'LOCAL_PRODUCTION_ENV_FILE_KEY',
'ENV_FILE_DEVELOPMENT_OVERRIDE_TEST',
'ENV_FILE_PRODUCTION_OVERRIDEOVERRIDE_TEST',
'ENV_FILE_PRODUCTION_LOCAL_OVERRIDEOVERRIDE_TEST',
]
export async function getStaticProps() {
const items = {}
variables.forEach((variable) => {
if (typeof process.env[variable] !== 'undefined') {
items[variable] = process.env[variable]
}
})
return {
// Do not pass any sensitive values here as they will
// be made PUBLICLY available in `pageProps`
props: { env: items },
revalidate: 1,
}
}
export default ({ env }) => (
<>
<p>{JSON.stringify(env)}</p>
<div id="nextConfigEnv">{process.env.nextConfigEnv}</div>
<div id="nextConfigPublicEnv">{process.env.nextConfigPublicEnv}</div>
</>
)

View File

@@ -0,0 +1,34 @@
const variables = [
'PROCESS_ENV_KEY',
'ENV_FILE_KEY',
'ENV_FILE_EMPTY_FIRST',
'PRODUCTION_ENV_FILE_KEY',
'LOCAL_PRODUCTION_ENV_FILE_KEY',
'ENV_FILE_DEVELOPMENT_OVERRIDE_TEST',
'ENV_FILE_PRODUCTION_OVERRIDEOVERRIDE_TEST',
'ENV_FILE_PRODUCTION_LOCAL_OVERRIDEOVERRIDE_TEST',
]
export async function getServerSideProps() {
const items = {}
variables.forEach((variable) => {
if (typeof process.env[variable] !== 'undefined') {
items[variable] = process.env[variable]
}
})
return {
// Do not pass any sensitive values here as they will
// be made PUBLICLY available in `pageProps`
props: { env: items },
}
}
export default ({ env }) => (
<>
<p>{JSON.stringify(env)}</p>
<div id="nextConfigEnv">{process.env.nextConfigEnv}</div>
<div id="nextConfigPublicEnv">{process.env.nextConfigPublicEnv}</div>
</>
)

View File

@@ -0,0 +1,163 @@
/* eslint-env jest */
import url from 'url'
import fs from 'fs-extra'
import { join } from 'path'
import cheerio from 'cheerio'
import {
nextBuild,
nextStart,
renderViaHTTP,
findPort,
launchApp,
killApp,
fetchViaHTTP,
} from 'next-test-utils'
jest.setTimeout(1000 * 60 * 2)
let app
let appPort
const appDir = join(__dirname, '../app')
const getEnvFromHtml = async (path) => {
const html = await renderViaHTTP(appPort, path)
const $ = cheerio.load(html)
const env = JSON.parse($('p').text())
env.nextConfigEnv = $('#nextConfigEnv').text()
env.nextConfigPublicEnv = $('#nextConfigPublicEnv').text()
return env
}
const runTests = (mode = 'dev') => {
const isDevOnly = mode === 'dev'
const checkEnvData = (data) => {
expect(data.ENV_FILE_KEY).toBe('env')
expect(data.PRODUCTION_ENV_FILE_KEY).toBe(
isDevOnly ? undefined : 'production'
)
expect(data.ENV_FILE_DEVELOPMENT_OVERRIDE_TEST).toEqual('staginglocal')
expect(data.nextConfigEnv).toBe('hello from staging app')
expect(data.nextConfigPublicEnv).toBe('hello again from staging app')
}
it('should pass staging env to next.config.js', async () => {
const res = await fetchViaHTTP(appPort, '/hello', undefined, {
redirect: 'manual',
})
const { pathname } = url.parse(res.headers.get('location'))
expect(res.status).toBe(307)
expect(pathname).toBe('/staging-route')
})
it('should provide env for SSG', async () => {
const data = await getEnvFromHtml('/some-ssg')
checkEnvData(data)
})
it('should provide env correctly for SSR', async () => {
const data = await getEnvFromHtml('/some-ssp')
checkEnvData(data)
})
it('should provide env correctly for API routes', async () => {
const data = JSON.parse(await renderViaHTTP(appPort, '/api/all'))
checkEnvData(data)
})
it('should load env from .env', async () => {
const data = await getEnvFromHtml('/')
expect(data.ENV_FILE_KEY).toEqual('env')
})
}
describe('Env Config', () => {
describe('dev mode', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {
env: {
APP_ENV: 'staging',
},
})
})
afterAll(() => killApp(app))
runTests('dev')
})
describe('server mode', () => {
beforeAll(async () => {
const { code } = await nextBuild(appDir, [], {
env: {
APP_ENV: 'staging',
},
})
if (code !== 0) throw new Error(`Build failed with exit code ${code}`)
appPort = await findPort()
app = await nextStart(appDir, appPort, {
env: {
APP_ENV: 'staging',
},
})
})
afterAll(() => killApp(app))
runTests('server')
})
describe('serverless mode', () => {
let nextConfigContent = ''
const nextConfigPath = join(appDir, 'next.config.js')
const envFiles = [
'.env',
'.env.staging',
'.env.staging.local',
'.env.production',
].map((file) => join(appDir, file))
beforeAll(async () => {
nextConfigContent = await fs.readFile(nextConfigPath, 'utf8')
await fs.writeFile(
nextConfigPath,
nextConfigContent.replace(
'// update me',
`target: 'experimental-serverless-trace',`
)
)
const { code } = await nextBuild(appDir, [], {
env: {
APP_ENV: 'staging',
},
})
if (code !== 0) throw new Error(`Build failed with exit code ${code}`)
appPort = await findPort()
// rename the files so they aren't loaded by `next start`
// to test that they were bundled into the serverless files
for (const file of envFiles) {
await fs.rename(file, `${file}.bak`)
}
app = await nextStart(appDir, appPort, {
env: {
APP_ENV: 'staging',
},
})
})
afterAll(async () => {
for (const file of envFiles) {
await fs.rename(`${file}.bak`, file)
}
await fs.writeFile(nextConfigPath, nextConfigContent)
await killApp(app)
})
runTests('serverless')
})
})

View File

@@ -10,7 +10,7 @@
"dependencies": {
"react": "^16.7.0",
"react-dom": "^16.7.0",
"@next/env": "^10.0.9",
"@blitzjs/env": "0.43.0",
"@next/polyfill-module": "^10.0.9",
"@next/react-dev-overlay": "^10.0.9",
"@next/react-refresh-utils": "^10.0.9"

View File

@@ -79,7 +79,7 @@ describe('pnpm support', () => {
await usingTempDir(async (tempDir) => {
const nextTarballPath = await pack(tempDir, 'next')
const dependencyTarballPaths = {
// '@next/env': await pack(tempDir, 'next-env'),
'@blitzjs/env': await pack(tempDir, 'next-env'),
// '@next/polyfill-module': await pack(tempDir, 'next-polyfill-module'),
// '@next/react-dev-overlay': await pack(tempDir, 'react-dev-overlay'),
// '@next/react-refresh-utils': await pack(tempDir, 'react-refresh-utils'),

View File

@@ -8,6 +8,7 @@
"nextjs/packages/next-mdx",
"nextjs/packages/eslint-config-next",
"nextjs/packages/eslint-plugin-next",
"nextjs/packages/next-env",
"examples/*",
"recipes/*"
],
@@ -28,14 +29,16 @@
"wait:nextjs": "wait-on -d 1000 nextjs/packages/next/dist/build/index.js",
"wait:nextjs-types": "wait-on -d 1000 nextjs/packages/next/dist/build/index.d.ts",
"dev:nextjs": "yarn workspace next dev",
"dev:next-env": "yarn workspace @blitzjs/env dev",
"dev:nextjs-types": "yarn wait:nextjs && yarn workspace next types && echo 'Finished building nextjs types'",
"dev:blitz": "cross-env BLITZ_PROD_BUILD=true preconstruct watch",
"dev:tsc": "yarn dev:nextjs-types && tsc --watch --pretty --preserveWatchOutput",
"dev:cli": "yarn wait:nextjs-types && yarn workspace @blitzjs/cli dev",
"dev:templates": "yarn workspace @blitzjs/generator dev",
"dev": "concurrently --names \"nextjs,blitz,typecheck,cli,templates\" -c \"magenta,cyan,green,yellow,black\" -p \"{name}\" \"npm:dev:nextjs\" \"npm:dev:blitz\" \"npm:dev:tsc\" \"npm:dev:cli\" \"npm:dev:templates\"",
"dev": "concurrently --names \"nextjs,blitz,typecheck,cli,templates,next-env\" -c \"magenta,cyan,green,yellow,black,blue\" -p \"{name}\" \"npm:dev:nextjs\" \"npm:dev:blitz\" \"npm:dev:tsc\" \"npm:dev:cli\" \"npm:dev:templates\" \"npm:dev:next-env\"",
"build:nextjs": "yarn workspace next prepublish",
"build": "yarn build:nextjs && cross-env BLITZ_PROD_BUILD=true preconstruct build && ultra -r --filter \"packages/*\" buildpkg && tsc",
"build:next-env": "yarn workspace @blitzjs/env prepublish",
"build": "yarn build:nextjs && yarn build:next-env && cross-env BLITZ_PROD_BUILD=true preconstruct build && ultra -r --filter \"packages/*\" buildpkg && tsc",
"lint": "eslint --ext \".js,.ts,.tsx\" .",
"link-cli": "yarn workspace blitz link",
"unlink-cli": "yarn workspace blitz unlink",
@@ -103,7 +106,6 @@
"@types/debug": "4.1.5",
"@types/detect-port": "1.3.0",
"@types/diff": "5.0.0",
"@types/dotenv-flow": "3.1.0",
"@types/flush-write-stream": "1.0.0",
"@types/from2": "2.3.0",
"@types/fs-extra": "8.1.0",

View File

@@ -1,4 +1,6 @@
// eslint-disable-next-line import/no-default-export
import {loadEnvConfig} from "@blitzjs/env"
module.exports = function globalSetup(globalConfig) {
require("dotenv-flow").config({silent: true})
const projectDir = process.cwd()
loadEnvConfig(projectDir)
}

View File

@@ -33,6 +33,10 @@ async function main() {
const cli = require(cliPkgPath)
if (options.e || options.env) {
process.env.APP_ENV = options.e || options.env
}
const hasVersionFlag = options._.length === 0 && (options.v || options.version)
const hasVerboseFlag = options._.length === 0 && (options.V || options.verbose)

View File

@@ -37,7 +37,6 @@
"chalk": "^4.1.0",
"cross-spawn": "7.0.3",
"dotenv-expand": "^5.1.0",
"dotenv-flow": "^3.2.0",
"enquirer": "2.3.6",
"esm": "3.2.25",
"fs-extra": "^9.1.0",

View File

@@ -7,6 +7,10 @@ export class Build extends Command {
static flags = {
help: flags.help({char: "h"}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -9,6 +9,10 @@ export class CodeGen extends Command {
static flags = {
help: flags.help({char: "h"}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -14,6 +14,10 @@ export class Console extends Command {
static flags = {
help: flags.help({char: "h"}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -69,6 +69,10 @@ ${require("chalk").bold("seed")} Generates seeded data in database via Prisma.
char: "f",
description: `Path to the seeds file, relative to the project root folder. Examples: db/seeds, db/seeds.ts, db/seeds/index.ts, db/my-seeds`,
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
static strict = false

View File

@@ -21,6 +21,10 @@ export class Dev extends Command {
"no-incremental-build": flags.boolean({
description: "Disable incremental build and start from a fresh cache",
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -11,6 +11,10 @@ export class Export extends Command {
char: "o",
description: "set the output dir (defaults to 'out')",
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -116,6 +116,10 @@ export class Generate extends Command {
char: "d",
description: "Show what files will be created without writing them to disk",
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
static examples = [

View File

@@ -94,6 +94,10 @@ export class Install extends Command {
default: false,
description: "Install the recipe automatically without user confirmation",
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
static args = [

View File

@@ -1,4 +1,5 @@
import {log} from "@blitzjs/display"
import {loadEnvConfig} from "@blitzjs/env"
import type {AppGeneratorOptions} from "@blitzjs/generator"
import {getLatestVersion} from "@blitzjs/generator"
import {flags} from "@oclif/command"
@@ -167,7 +168,8 @@ export class New extends Command {
const spinner = log.spinner(log.withBrand("Initializing SQLite database")).start()
try {
// Required in order for DATABASE_URL to be available
require("dotenv-expand")(require("dotenv-flow").config({silent: true}))
const projectDir = process.cwd()
loadEnvConfig(projectDir)
const result = await runPrisma(["migrate", "dev", "--name", "Initial migration"], true)
if (!result.success) throw new Error()

View File

@@ -1,4 +1,4 @@
import {Command} from "@oclif/command"
import {Command, flags} from "@oclif/command"
import {Readable} from "stream"
const getPrismaBin = async () => {
@@ -55,6 +55,13 @@ export class PrismaCommand extends Command {
static description = "Loads env variables then proxies all args to Prisma CLI"
static aliases = ["p"]
static flags = {
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
static strict = false
async run() {

View File

@@ -18,6 +18,10 @@ export class Start extends Command {
inspect: flags.boolean({
description: "Enable the Node.js inspector",
}),
env: flags.string({
char: "e",
description: "Set app environment name",
}),
}
async run() {

View File

@@ -2,12 +2,18 @@ require("v8-compile-cache")
const cacheFile = require("path").join(__dirname, ".blitzjs-cli-cache")
const lazyLoad = require("@salesforce/lazy-require").default.create(cacheFile)
lazyLoad.start()
import {loadEnvConfig} from "@blitzjs/env"
import {run as oclifRun} from "@oclif/command"
import {compileConfig} from "next/dist/server/config-shared"
import {getProjectRoot} from "next/dist/server/lib/utils"
const options = require("minimist")(process.argv.slice(2))
if (options.e || options.env) {
process.env.APP_ENV = options.e || options.env
}
// Load the .env environment variable so it's available for all commands
require("dotenv-expand")(require("dotenv-flow").config({silent: true}))
loadEnvConfig()
async function buildConfigIfNeeded() {
if (["help", "-h", "autocomplete", "new", "s", "start"].includes(process.argv[2])) {

View File

@@ -3197,11 +3197,6 @@
dependencies:
webpack-bundle-analyzer "4.3.0"
"@next/env@11.1.0":
version "11.1.0"
resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.0.tgz#cae83d8e0a65aa9f2af3368f8269ffd9d911746a"
integrity sha512-zPJkMFRenSf7BLlVee8987G0qQXAhxy7k+Lb/5hLAGkPVHAHm+oFFeL+2ipbI2KTEFlazdmGY0M+AlLQn7pWaw==
"@next/polyfill-module@11.1.0":
version "11.1.0"
resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.0.tgz#ee6b9117a1f9bb137479dfa51d5a9e38e066a62f"
@@ -4629,10 +4624,12 @@
resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.0.0.tgz#eb71e94feae62548282c4889308a3dfb57e36020"
integrity sha512-jrm2K65CokCCX4NmowtA+MfXyuprZC13jbRuwprs6/04z/EcFg/MCwYdsHn+zgV4CQBiATiI7AEq7y1sZCtWKA==
"@types/dotenv-flow@3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@types/dotenv-flow/-/dotenv-flow-3.1.0.tgz#e9ba53f95f3d40bbc0df99b206f649b2acfca0c6"
integrity sha512-qaWT42KDePdAGZFryYoV7EZnuuYZAO4KPVDWUV9OBOyJx7xCgKKERtVB7jBCM2mtKVI+OMMDK2ef11PWcHJz3g==
"@types/dotenv@8.2.0":
version "8.2.0"
resolved "https://registry.yarnpkg.com/@types/dotenv/-/dotenv-8.2.0.tgz#5cd64710c3c98e82d9d15844375a33bf1b45d053"
integrity sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==
dependencies:
dotenv "*"
"@types/duplexify@*":
version "3.6.0"
@@ -5866,6 +5863,11 @@
async-retry "1.2.3"
lru-cache "5.1.1"
"@zeit/ncc@0.20.4":
version "0.20.4"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.20.4.tgz#00f0a25a88cac3712af4ba66561d9e281c6f05c9"
integrity sha512-fmq+F/QxPec+k/zvT7HiVpk7oiGFseS6brfT/AYqmCUp6QFRK7vZf2Ref46MImsg/g2W3g5X6SRvGRmOAvEfdA==
"@zeit/next-css@1.0.2-canary.2":
version "1.0.2-canary.2"
resolved "https://registry.yarnpkg.com/@zeit/next-css/-/next-css-1.0.2-canary.2.tgz#0eeb877e7469892b65471c1ec7c14346b8f240df"
@@ -9924,14 +9926,12 @@ dotenv-expand@^5.1.0:
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
dotenv-flow@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/dotenv-flow/-/dotenv-flow-3.2.0.tgz#a5d79dd60ddb6843d457a4874aaf122cf659a8b7"
integrity sha512-GEB6RrR4AbqDJvNSFrYHqZ33IKKbzkvLYiD5eo4+9aFXr4Y4G+QaFrB/fNp0y6McWBmvaPn3ZNjIufnj8irCtg==
dependencies:
dotenv "^8.0.0"
dotenv@*:
version "10.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
dotenv@^8.0.0, dotenv@^8.2.0:
dotenv@8.2.0, dotenv@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==