1
1
import childProcess from 'node:child_process'
2
2
import fs from 'fs/promises'
3
3
import path from 'node:path'
4
- import { type ProjectPackager , type ProjectSettings , loadFile } from '../common/project'
5
- import loadConfig from '../commands/helpers/loadConfig'
6
- import appRouterRevalidate from './cache/handlers/appRouterRevalidate'
4
+ import { type ProjectPackager , type ProjectSettings } from '../common/project'
5
+ import appRouterRevalidateTemplate from './cache/handlers/appRouterRevalidate'
7
6
8
7
interface BuildOptions {
9
8
packager : ProjectPackager
@@ -21,78 +20,52 @@ interface BuildAppOptions {
21
20
22
21
export const OUTPUT_FOLDER = 'serverless-next'
23
22
24
- const setNextOptions = async ( nextConfigPath : string , s3BucketName : string ) : Promise < ( ) => Promise < void > > => {
25
- // set s3 bucket name for cache handler during build time
23
+ const setNextEnvs = ( s3BucketName : string ) => {
26
24
process . env . STATIC_BUCKET_NAME = s3BucketName
27
-
28
- const cacheConfig = await loadConfig ( )
29
- const currentConfig = await loadFile ( nextConfigPath )
30
- const updatedConfig = {
31
- ...currentConfig ,
32
- output : 'standalone' ,
33
- serverRuntimeConfig : {
34
- ...currentConfig . serverRuntimeConfig ,
35
- nextServerlessCacheConfig : cacheConfig
36
- } ,
37
- cacheHandler : require . resolve ( path . join ( '..' , 'cacheHandler' , 'index.js' ) )
38
- }
39
-
40
- const currentContent = await fs . readFile ( nextConfigPath , 'utf-8' )
41
-
42
- let updatedContent = `module.exports = ${ JSON . stringify ( updatedConfig , null , 4 ) } ;\n`
43
-
44
- // Check if the file has .mjs extension
45
- if ( nextConfigPath . endsWith ( '.mjs' ) ) {
46
- updatedContent = `export default ${ JSON . stringify ( updatedConfig , null , 4 ) } ;\n`
47
- }
48
-
49
- await fs . writeFile ( nextConfigPath , updatedContent , 'utf-8' )
50
-
51
- // Function to revert back to original content of file
52
- return async ( ) => {
53
- fs . writeFile ( nextConfigPath , currentContent , 'utf-8' )
54
- }
25
+ process . env . NEXT_SERVERLESS_DEPLOYING_PHASE = 'true'
55
26
}
56
27
57
28
const appendRevalidateApi = async ( projectPath : string , isAppDir : boolean ) : Promise < string > => {
58
29
const routeFolderPath = path . join ( projectPath , isAppDir ? 'src/app' : 'src' , 'api' , 'revalidate' )
59
30
const routePath = path . join ( routeFolderPath , 'route.ts' )
60
- if ( ( await fs . stat ( routeFolderPath ) ) . isDirectory ( ) ) {
61
- await fs . mkdir ( routeFolderPath , { recursive : true } )
62
- }
63
31
64
- fs . writeFile ( routePath , appRouterRevalidate , 'utf-8' )
32
+ await fs . mkdir ( routeFolderPath , { recursive : true } )
33
+ await fs . writeFile ( routePath , appRouterRevalidateTemplate , 'utf-8' )
65
34
66
35
return routePath
67
36
}
68
37
69
38
export const buildNext = async ( options : BuildOptions ) : Promise < ( ) => Promise < void > > => {
70
- const { packager, nextConfigPath , s3BucketName, projectPath , isAppDir } = options
39
+ const { packager, projectPath , s3BucketName, isAppDir } = options
71
40
41
+ setNextEnvs ( s3BucketName )
72
42
const revalidateRoutePath = await appendRevalidateApi ( projectPath , isAppDir )
73
- const clearNextConfig = await setNextOptions ( nextConfigPath , s3BucketName )
74
43
childProcess . execSync ( packager . buildCommand , { stdio : 'inherit' } )
75
44
76
45
// Reverts changes to the next project
77
46
return async ( ) => {
78
- await Promise . all ( [ clearNextConfig ( ) , fs . rm ( revalidateRoutePath ) ] )
47
+ await fs . rm ( revalidateRoutePath )
79
48
}
80
49
}
81
50
82
- const copyAssets = async ( outputPath : string , appPath : string ) => {
51
+ const copyAssets = async ( outputPath : string , appPath : string , appRelativePath : string ) => {
83
52
// Copying static assets (like js, css, images, .etc)
84
- await Promise . all ( [
85
- fs . cp ( path . join ( appPath , '.next' , 'static' ) , path . join ( outputPath , '_next' , 'static' ) , { recursive : true } ) ,
86
- fs . cp ( path . join ( appPath , '.next' , 'standalone' ) , path . join ( outputPath , 'server' ) , {
53
+ await fs . cp ( path . join ( appPath , '.next' ) , path . join ( outputPath , '.next' ) , {
54
+ recursive : true
55
+ } )
56
+ await fs . cp (
57
+ path . join ( appPath , '.next' , 'static' ) ,
58
+ path . join ( outputPath , '.next' , 'standalone' , appRelativePath , '.next' , 'static' ) ,
59
+ {
87
60
recursive : true
88
- } )
89
- ] )
61
+ }
62
+ )
90
63
}
91
64
92
65
export const buildApp = async ( options : BuildAppOptions ) => {
93
66
const { projectSettings, outputPath, s3BucketName } = options
94
67
95
- const { packager, nextConfigPath, projectPath, isAppDir } = projectSettings
68
+ const { packager, nextConfigPath, projectPath, isAppDir, root , isMonorepo } = projectSettings
96
69
97
70
const cleanNextApp = await buildNext ( {
98
71
packager,
@@ -102,7 +75,9 @@ export const buildApp = async (options: BuildAppOptions) => {
102
75
projectPath
103
76
} )
104
77
105
- await copyAssets ( outputPath , projectPath )
78
+ const appRelativePath = isMonorepo ? path . relative ( root , projectPath ) : ''
79
+
80
+ await copyAssets ( outputPath , projectPath , appRelativePath )
106
81
107
82
return cleanNextApp
108
83
}
0 commit comments