[CLI] partial fixes to cwd
option, propose that commands import deps lazily
#5623
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR 1) partially fixes the CLI's
cwd
option and 2) gives an idea of some of the tweaks I think we should make to the CLI to increase maintainability (for contributors) and start up time (for users). Note that the diff is mostly the result of of fixing the CLI'scwd
option.In sum, the tweaks I'm suggesting are:
getPaths
,getConfig
andstructure
to global context of CLI #2793To make things more concrete, I've reworked three of the commands to show what they'd look like:
check
,info
, andlint
. The changes are pretty minimal. I'd like for all the commands in the CLI to look more or less like this.I'll talk about
lint
a bit more. The changes I want to bring attention to are in thehandler
function:redwood/packages/cli/src/commands/lint.js
Lines 27 to 29 in d4b65fc
All the dependencies used by the
lint
command are now imported inside thehandler
function. There's also a "new" property onargv
,redwoodProject
—naming and association with@redwoodjs/internal
/structure
TBD—that has "everything you need to know". I.e., no more callinggetPaths
.Ok, so all the dependencies used by the
lint
command are now imported inside thehandler
function... this may not seem like a big deal. Currently,execa
is imported outside thehandler
function:redwood/packages/cli/src/commands/lint.js
Line 3 in 9bea0a3
It's not that bad for one command but it doesn't scale nicely. The way it is now, if a user runs
yarn rw info
, a command that only uses one dependency,env-info
,execa
gets imported even though it's never actually used for anything. And it's way more thanexeca
—it's every dependency every command imports.The reason they're all imported is
commandDir
recursively requires every file in the directory it's given (yargs
has to build the whole CLI before it can figure out what to execute). The consequence is that start-up time is slow. Moving the imports into thehandler
only imports the dependencies if the command is actually invoked.Again, this isn't a full-on rework of the CLI. If I were to really rework the CLI, I'd probably use clipanion.
Note that the missing improvement here is bundling the CLI. Yargs has a short doc on bundling: https://github.com/yargs/yargs/blob/main/docs/bundling.md. And I've tried to follow it, using ESBuild, but am facing some issues. While I'm hoping to resolve those, note that it may only be beneficial to bundle what's included in the entry-point
index.js
file since bundling lazily-imported dependencies could give us the same slow start-up time we're seeing now. Think of it like the code-splitting the Router does automatically.Partially fixing the
cwd
optionNow about the less-interesting change in this PR. The CLI has a
cwd
option that should let you change the working directory so that you can invoke the CLI in another project.One of the reasons it's broken is
getPaths
is called in many places beforegetCwdMiddleware
has the chance to set thecwd
. For example, inyargsDefaults
,getPaths
is called as soon as this file is imported, which is beforegetCwdMiddleware
runs:redwood/packages/cli/src/commands/generate.js
Lines 25 to 38 in f3e034c
The solution is making constants that use
getPaths
functions so that they wait till it's actually set. So now, after building, you should be able to test out some of the commands like so...Not all commands work yet for reasons TBD.