11#!/usr/bin/env node
2- /* eslint-env node */
32
43import { performance } from 'node:perf_hooks'
54import { fileURLToPath } from 'node:url'
@@ -8,12 +7,90 @@ import { parseArgs as nodeUtilParseArgs } from 'node:util'
87import ora from 'ora'
98import { cd , chalk , fs , glob , path , within , $ } from 'zx'
109
11- const mockSpinner = {
12- text : '' ,
13- succeed : ( ) => { } ,
14- }
10+ const FRAMEWORK_PATH = fileURLToPath ( new URL ( '../../' , import . meta. url ) )
11+ const TARBALL_DEST_DIRNAME = 'tarballs'
1512
1613async function main ( ) {
14+ const { projectPath, verbose } = await getOptions ( )
15+ $ . verbose = verbose
16+
17+ cd ( FRAMEWORK_PATH )
18+ performance . mark ( 'startFramework' )
19+
20+ const spinner = getFrameworkSpinner ( { text : 'building and packing packages' } )
21+ await buildTarballs ( )
22+
23+ spinner . text = 'moving tarballs'
24+ await moveTarballs ( projectPath )
25+
26+ spinner . text = 'updating resolutions'
27+ await updateResolutions ( projectPath )
28+
29+ performance . mark ( 'endFramework' )
30+ performance . measure ( 'framework' , 'startFramework' , 'endFramework' )
31+ const [ entry ] = performance . getEntriesByName ( 'framework' )
32+ spinner . succeed ( `finished in ${ ( entry . duration / 1000 ) . toFixed ( 2 ) } seconds` )
33+
34+ await yarnInstall ( projectPath )
35+
36+ const entries = performance . getEntriesByType ( 'measure' ) . map ( ( entry ) => {
37+ return `• ${ entry . name } => ${ ( entry . duration / 1000 ) . toFixed ( 2 ) } seconds`
38+ } )
39+
40+ for ( const entry of entries ) {
41+ verbose && console . log ( entry )
42+ }
43+ }
44+
45+ main ( )
46+
47+ // Helpers
48+ // -------
49+
50+ async function parseArgs ( ) {
51+ const { positionals, values } = nodeUtilParseArgs ( {
52+ allowPositionals : true ,
53+
54+ options : {
55+ verbose : {
56+ type : 'boolean' ,
57+ default : false ,
58+ short : 'v' ,
59+ } ,
60+ } ,
61+ } )
62+
63+ const [ projectPath ] = positionals
64+
65+ const options = {
66+ verbose : values . verbose ,
67+ }
68+
69+ options . projectPath = projectPath ? projectPath : process . env . RWJS_CWD
70+
71+ if ( ! options . projectPath ) {
72+ throw new Error (
73+ [
74+ 'Error: You have to provide the path to a Redwood project as' ,
75+ '' ,
76+ ' 1. the first positional argument' ,
77+ '' ,
78+ chalk . gray ( ' yarn project:tarsync /path/to/redwood/project' ) ,
79+ '' ,
80+ ' 2. the `RWJS_CWD` env var' ,
81+ '' ,
82+ chalk . gray ( ' RWJS_CWD=/path/to/redwood/project yarn project:tarsync' ) ,
83+ ] . join ( '\n' )
84+ )
85+ }
86+
87+ // This makes `projectPath` an absolute path and throws if it doesn't exist.
88+ options . projectPath = await fs . realpath ( options . projectPath )
89+
90+ return options
91+ }
92+
93+ async function getOptions ( ) {
1794 let options
1895
1996 try {
@@ -26,33 +103,35 @@ async function main() {
26103
27104 const { projectPath, verbose } = options
28105
29- $ . verbose = verbose
30-
31- // Closing over `verbose` here.
32- function getProjectSpinner ( { text } ) {
33- return verbose
34- ? mockSpinner
35- : ora ( { prefixText : `${ chalk . green ( '[ project ]' ) } ` , text } ) . start ( )
106+ return {
107+ projectPath,
108+ verbose,
36109 }
110+ }
37111
38- function getFrameworkSpinner ( { text } ) {
39- return verbose
40- ? mockSpinner
41- : ora ( { prefixText : `${ chalk . cyan ( '[framework]' ) } ` , text } ) . start ( )
42- }
112+ const mockSpinner = {
113+ text : '' ,
114+ succeed : ( ) => { } ,
115+ }
43116
44- const frameworkPath = fileURLToPath ( new URL ( '../../' , import . meta. url ) )
45- cd ( frameworkPath )
46- performance . mark ( 'startFramework' )
117+ function getProjectSpinner ( { text } ) {
118+ return $ . verbose
119+ ? mockSpinner
120+ : ora ( { prefixText : `${ chalk . green ( '[ project ]' ) } ` , text } ) . start ( )
121+ }
47122
48- const spinner = getFrameworkSpinner ( { text : 'building and packing packages' } )
123+ function getFrameworkSpinner ( { text } ) {
124+ return $ . verbose
125+ ? mockSpinner
126+ : ora ( { prefixText : `${ chalk . cyan ( '[framework]' ) } ` , text } ) . start ( )
127+ }
49128
129+ async function buildTarballs ( ) {
50130 await $ `yarn nx run-many -t build:pack --exclude create-redwood-app`
131+ }
51132
52- spinner . text = 'moving tarballs'
53-
54- const tarballDestDirname = 'tarballs'
55- const tarballDest = path . join ( projectPath , tarballDestDirname )
133+ async function moveTarballs ( projectPath ) {
134+ const tarballDest = path . join ( projectPath , TARBALL_DEST_DIRNAME )
56135 await fs . ensureDir ( tarballDest )
57136
58137 const tarballs = await glob ( [ './packages/**/*.tgz' ] )
@@ -64,9 +143,25 @@ async function main() {
64143 } )
65144 )
66145 )
146+ }
67147
68- spinner . text = 'updating resolutions'
148+ async function getReactResolutions ( ) {
149+ const packageConfig = await fs . readJson ( path . join ( FRAMEWORK_PATH , 'packages/web/package.json' ) )
150+
151+ const react = packageConfig . peerDependencies . react
152+ const reactDom = packageConfig . peerDependencies [ 'react-dom' ]
153+
154+ if ( ! react || ! reactDom ) {
155+ throw new Error ( "Couldn't find react or react-dom in @redwoodjs/web's peerDependencies" )
156+ }
69157
158+ return {
159+ react,
160+ 'react-dom' : reactDom ,
161+ }
162+ }
163+
164+ async function updateResolutions ( projectPath ) {
70165 const resolutions = ( await $ `yarn workspaces list --json` ) . stdout
71166 . trim ( )
72167 . split ( '\n' )
@@ -77,9 +172,8 @@ async function main() {
77172 return {
78173 ...resolutions ,
79174 // Turn a Redwood package name like `@redwoodjs/project-config` into `redwoodjs-project-config.tgz`.
80- [ name ] : `./${ tarballDestDirname } /${
81- name . replace ( '@' , '' ) . replaceAll ( '/' , '-' ) + '.tgz'
82- } `,
175+ [ name ] : `./${ TARBALL_DEST_DIRNAME } /${ name . replace ( '@' , '' ) . replaceAll ( '/' , '-' ) + '.tgz'
176+ } `,
83177 }
84178 } , { } )
85179
@@ -93,20 +187,16 @@ async function main() {
93187 resolutions : {
94188 ...projectPackageJson . resolutions ,
95189 ...resolutions ,
190+ ...( await getReactResolutions ( ) )
96191 } ,
97192 } ,
98193 {
99194 spaces : 2 ,
100195 }
101196 )
197+ }
102198
103- performance . mark ( 'endFramework' )
104- performance . measure ( 'framework' , 'startFramework' , 'endFramework' )
105-
106- const [ entry ] = performance . getEntriesByName ( 'framework' )
107-
108- spinner . succeed ( `finished in ${ ( entry . duration / 1000 ) . toFixed ( 2 ) } seconds` )
109-
199+ async function yarnInstall ( projectPath ) {
110200 await within ( async ( ) => {
111201 cd ( projectPath )
112202 performance . mark ( 'startProject' )
@@ -123,56 +213,4 @@ async function main() {
123213 spinner . succeed ( `finished in ${ ( entry . duration / 1000 ) . toFixed ( 2 ) } seconds` )
124214 } )
125215
126- const entries = performance . getEntriesByType ( 'measure' ) . map ( ( entry ) => {
127- return `• ${ entry . name } => ${ ( entry . duration / 1000 ) . toFixed ( 2 ) } seconds`
128- } )
129-
130- for ( const entry of entries ) {
131- verbose && console . log ( entry )
132- }
133- }
134-
135- main ( )
136-
137- async function parseArgs ( ) {
138- const { positionals, values } = nodeUtilParseArgs ( {
139- allowPositionals : true ,
140-
141- options : {
142- verbose : {
143- type : 'boolean' ,
144- default : false ,
145- short : 'v' ,
146- } ,
147- } ,
148- } )
149-
150- const [ projectPath ] = positionals
151-
152- const options = {
153- verbose : values . verbose ,
154- }
155-
156- options . projectPath = projectPath ? projectPath : process . env . RWJS_CWD
157-
158- if ( ! options . projectPath ) {
159- throw new Error (
160- [
161- 'Error: You have to provide the path to a Redwood project as' ,
162- '' ,
163- ' 1. the first positional argument' ,
164- '' ,
165- chalk . gray ( ' yarn project:tarsync /path/to/redwood/project' ) ,
166- '' ,
167- ' 2. the `RWJS_CWD` env var' ,
168- '' ,
169- chalk . gray ( ' RWJS_CWD=/path/to/redwood/project yarn project:tarsync' ) ,
170- ] . join ( '\n' )
171- )
172- }
173-
174- // This makes `projectPath` an absolute path and throws if it doesn't exist.
175- options . projectPath = await fs . realpath ( options . projectPath )
176-
177- return options
178216}
0 commit comments