11import fs from 'node:fs' ;
22import path from 'node:path' ;
3+ import { fileURLToPath } from 'node:url' ;
4+ import { getPackages } from '@manypkg/get-packages' ;
35import logSymbols from 'log-symbols' ;
46import { installDependencies , type PackageManagerName , runScript } from 'nypm' ;
57import ora from 'ora' ;
@@ -15,15 +17,24 @@ interface Args {
1517 packageManager : PackageManagerName ;
1618}
1719
20+ const dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
21+ const isInReactEmailMonorepo = ! dirname . includes ( 'node_modules' ) ;
22+
1823const setNextEnvironmentVariablesForBuild = async (
1924 emailsDirRelativePath : string ,
2025 builtPreviewAppPath : string ,
26+ usersProjectLocation : string ,
2127) => {
28+ let rootDir = 'previewServerLocation' ;
29+ if ( isInReactEmailMonorepo ) {
30+ rootDir = `'${ await getPackages ( usersProjectLocation ) . then ( ( p ) => p . rootDir . replaceAll ( '\\' , '/' ) ) } '` ;
31+ }
2232 const nextConfigContents = `
2333import path from 'path';
2434const emailsDirRelativePath = path.normalize('${ emailsDirRelativePath } ');
25- const userProjectLocation = '${ process . cwd ( ) . replace ( / \\ / g, '/' ) } ';
26- const previewServerLocation = '${ builtPreviewAppPath . replace ( / \\ / g, '/' ) } ';
35+ const userProjectLocation = '${ process . cwd ( ) . replaceAll ( '\\' , '/' ) } ';
36+ const previewServerLocation = '${ builtPreviewAppPath . replaceAll ( '\\' , '/' ) } ';
37+ const rootDir = ${ rootDir } ;
2738/** @type {import('next').NextConfig} */
2839const nextConfig = {
2940 env: {
@@ -33,7 +44,10 @@ const nextConfig = {
3344 REACT_EMAIL_INTERNAL_PREVIEW_SERVER_LOCATION: previewServerLocation,
3445 REACT_EMAIL_INTERNAL_USER_PROJECT_LOCATION: userProjectLocation
3546 },
36- outputFileTracingRoot: previewServerLocation,
47+ turbopack: {
48+ root: rootDir,
49+ },
50+ outputFileTracingRoot: rootDir,
3751 serverExternalPackages: ['esbuild'],
3852 typescript: {
3953 ignoreBuildErrors: true
@@ -164,6 +178,7 @@ export const build = async ({
164178 packageManager,
165179} : Args ) => {
166180 try {
181+ const usersProjectLocation = process . cwd ( ) ;
167182 const previewServerLocation = await getPreviewServerLocation ( ) ;
168183
169184 const spinner = ora ( {
@@ -177,10 +192,13 @@ export const build = async ({
177192 process . exit ( 1 ) ;
178193 }
179194
180- const emailsDirPath = path . join ( process . cwd ( ) , emailsDirRelativePath ) ;
195+ const emailsDirPath = path . join (
196+ usersProjectLocation ,
197+ emailsDirRelativePath ,
198+ ) ;
181199 const staticPath = path . join ( emailsDirPath , 'static' ) ;
182200
183- const builtPreviewAppPath = path . join ( process . cwd ( ) , '.react-email' ) ;
201+ const builtPreviewAppPath = path . join ( usersProjectLocation , '.react-email' ) ;
184202
185203 if ( fs . existsSync ( builtPreviewAppPath ) ) {
186204 spinner . text = 'Deleting pre-existing `.react-email` folder' ;
@@ -191,12 +209,11 @@ export const build = async ({
191209 await fs . promises . cp ( previewServerLocation , builtPreviewAppPath , {
192210 recursive : true ,
193211 filter : ( source : string ) => {
194- // do not copy the CLI files
212+ const relativeSource = path . relative ( previewServerLocation , source ) ;
195213 return (
196- ! / ( \/ | \\ ) c l i ( \/ | \\ ) ? / . test ( source ) &&
197- ! / ( \/ | \\ ) \. n e x t ( \/ | \\ ) ? / . test ( source ) &&
198- ! / ( \/ | \\ ) \. t u r b o ( \/ | \\ ) ? / . test ( source ) &&
199- ! / ( \/ | \\ ) n o d e _ m o d u l e s ( \/ | \\ ) ? $ / . test ( source )
214+ ! / \. n e x t / . test ( relativeSource ) &&
215+ ! / \. t u r b o / . test ( relativeSource ) &&
216+ ( isInReactEmailMonorepo || ! / n o d e _ m o d u l e s / . test ( relativeSource ) )
200217 ) ;
201218 } ,
202219 } ) ;
@@ -218,6 +235,7 @@ export const build = async ({
218235 await setNextEnvironmentVariablesForBuild (
219236 emailsDirRelativePath ,
220237 builtPreviewAppPath ,
238+ usersProjectLocation ,
221239 ) ;
222240
223241 spinner . text = 'Setting server side generation for the email preview pages' ;
@@ -226,12 +244,14 @@ export const build = async ({
226244 spinner . text = "Updating package.json's build and start scripts" ;
227245 await updatePackageJson ( builtPreviewAppPath ) ;
228246
229- spinner . text = 'Installing dependencies on `.react-email`' ;
230- await installDependencies ( {
231- cwd : builtPreviewAppPath ,
232- silent : true ,
233- packageManager,
234- } ) ;
247+ if ( ! isInReactEmailMonorepo ) {
248+ spinner . text = 'Installing dependencies on `.react-email`' ;
249+ await installDependencies ( {
250+ cwd : builtPreviewAppPath ,
251+ silent : true ,
252+ packageManager,
253+ } ) ;
254+ }
235255
236256 spinner . stopAndPersist ( {
237257 text : 'Successfully prepared `.react-email` for `next build`' ,
0 commit comments