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

feat: copy .env file in standalone mode #34143

Merged
merged 8 commits into from Feb 10, 2022
Merged
2 changes: 1 addition & 1 deletion packages/next/build/babel/loader/index.ts
Expand Up @@ -45,7 +45,7 @@ const nextBabelLoaderOuter = function nextBabelLoaderOuter(
nextBabelLoader.call(this, loaderSpan, inputSource, inputSourceMap)
)
.then(
([transformedSource, outputSourceMap]) =>
([transformedSource, outputSourceMap]: any) =>
callback?.(null, transformedSource, outputSourceMap || inputSourceMap),
(err) => {
callback?.(err)
Expand Down
8 changes: 7 additions & 1 deletion packages/next/build/index.ts
Expand Up @@ -427,7 +427,7 @@ export default async function build(
pages404: boolean
basePath: string
redirects: Array<ReturnType<typeof buildCustomRoute>>
rewrites:
rewrites?:
| Array<ReturnType<typeof buildCustomRoute>>
| {
beforeFiles: Array<ReturnType<typeof buildCustomRoute>>
Expand Down Expand Up @@ -2036,6 +2036,12 @@ export default async function build(
for (const file of [
...requiredServerFiles.files,
path.join(config.distDir, SERVER_FILES_MANIFEST),
...loadedEnvFiles.reduce<string[]>((acc, envFile) => {
if (['.env', '.env.production'].includes(envFile.path)) {
acc.push(envFile.path)
}
return acc
}, []),
]) {
const filePath = path.join(dir, file)
await promises.copyFile(
Expand Down
Expand Up @@ -28,7 +28,7 @@ function generateClientManifest(
compilation: any,
assetMap: BuildManifest,
rewrites: CustomRoutes['rewrites']
): string {
): string | undefined {
const compilationSpan = spans.get(compilation) || spans.get(compiler)
const genClientManifestSpan = compilationSpan?.traceChild(
'NextJsBuildManifest-generateClientManifest'
Expand Down
2 changes: 1 addition & 1 deletion packages/next/trace/trace.ts
Expand Up @@ -85,7 +85,7 @@ export class Span {
this.attrs[key] = String(value)
}

traceFn(fn: any) {
traceFn<T>(fn: () => T): T {
try {
return fn()
} finally {
Expand Down
17 changes: 17 additions & 0 deletions test/production/required-server-files.test.ts
Expand Up @@ -31,6 +31,13 @@ describe('should set-up next', () => {
'data.txt': new FileRef(
join(__dirname, 'required-server-files/data.txt')
),
'.env': new FileRef(join(__dirname, 'required-server-files/.env')),
'.env.local': new FileRef(
join(__dirname, 'required-server-files/.env.local')
),
'.env.production': new FileRef(
join(__dirname, 'required-server-files/.env.production')
),
},
nextConfig: {
eslint: {
Expand Down Expand Up @@ -722,4 +729,14 @@ describe('should set-up next', () => {
const $ = cheerio.load(html)
expect($('#slug-page').text()).toBe('[slug] page')
})

it('should copy and read .env file', async () => {
const res = await fetchViaHTTP(appPort, '/api/env')

const envVariables = await res.json()

expect(envVariables.env).not.toBeUndefined()
expect(envVariables.envProd).not.toBeUndefined()
expect(envVariables.envLocal).toBeUndefined()
})
})
1 change: 1 addition & 0 deletions test/production/required-server-files/.env
@@ -0,0 +1 @@
FOO=bar
1 change: 1 addition & 0 deletions test/production/required-server-files/.env.local
@@ -0,0 +1 @@
LOCAL_SECRET=local-secret
1 change: 1 addition & 0 deletions test/production/required-server-files/.env.production
@@ -0,0 +1 @@
PROD_SECRET=prod-secret
7 changes: 7 additions & 0 deletions test/production/required-server-files/pages/api/env.js
@@ -0,0 +1,7 @@
export default function handler(_, res) {
res.json({
env: process.env.FOO,
envLocal: process.env.LOCAL_SECRET,
envProd: process.env.PROD_SECRET,
})
}