-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
refactor(create-app): moves to prompts #3044
Conversation
Hey @Olyno! Thanks for the PR! Could you break the PR in smaller changes using different PRs for each? I think that changing from enquirer to prompts should be the first PR, to solve the bug that you found (good to make the callback to async changes also). Looks like prompts is more active, and it is 14.5kb vs 21kb (not much for node, but always good to reduce size). I think the best is to avoid a big refactoring though, so it is easier to merge the bug fix, and you can send another refactor PR later. We could discuss in other PRs or issues about further changes. For example, I don't think that moving the templates in a separate folder is needed at this point. I also have doubts about replacing 'framework' with 'template', I don't think that framework is confusing in this context. Thanks again! |
Hi @patak-js, thanks you for your feedback! I personally don't see how I can reduce this pull request into several for the simple reason that prompts to a certain logic that enquirer does not have and vice versa. So I don't think it is possible even though I would have liked to. Enquirer allows you to create dialogues on the fly, while prompts is more adapted to make all the dialogues in a chain. Also, should I go back to the term "framework" and put it back? |
Yes, better to revert to "framework" IMO. And it is ok to refactor what is needed to use What I think you shouldn't include is renaming templates from template-xxx to templates/template-xxx, and renaming index.js to src/index.js, just leave the file structure as is so the discussion can focus on one change at a time ( in this case enquirer -> prompts) |
I did the revert for the "framework" and the file structure. It seems to have something wrong with the |
Sorry @Olyno, it is still quite hard to review this PR because there are a lot of changes that are unrelated to the migration from enquirer to prompts. For example, moving the utility functions to the top instead of leaving them at the bottom of the file. Looks like there was an issue with the linter that let pass different linting rules (use of |
13733bd
to
099366b
Compare
Hey @patak-js sorry for the delay. I reworked the code as you requested, making as few changes as possible. I'll do some more pull requests later to improve the other parts 😃 |
Can you explain a bit when would the duplicate selection issue appears? It works fine on my side. And if so, it's more likely a bug of |
Yeah... I am with @antfu in this point Also why According to following statistics, we could directly move to |
It works fine for me too on Windows, but does not work as expected on my Linux (see screen above)
Well I'm totally agree with you, and I would like to know how to fix it, but it doesn't seem possible to fix it directly here, it's probably an internal issue of
If everything should be related to stats, then I guess WindiCSS should not be used since TailwindCSS is much more used, same for Svelte in front of React and much more...
As well as its popularity which only grows with time. Inquirer remains an interesting choice, but:
I'm talking here from my personal point of view, and one way or another it's up to you to decide what you prefer for Vite. I can of course redo all the code with Inquirer if you prefer. |
I'm a bit splitted here 😕 First IMO WindiCSS is an improvement on top of TailwindCSS, like SCSS is for CSS Create React App uses Vue-CLI uses I would like to let @patak-js or @antfu decide it 😅 |
Yeah I know ahah, I was trying to show you an absurd comparison to explain you that numbers don't mean everything, WindiCSS was maybe not the best example 😅 |
I think it would be a good idea to check if inquirer is a better option here. @sodatea was there a rationale to choose it for vue-cli? |
I've considered switching to The only thing that blocks me from doing so is that we've made the |
Thanks @sodatea, I think switching to prompts is a good idea. @antfu what do you think? @Olyno the PR is still changing more things than just the move to prompts though. The getValidPackageName shouldn't be removed. This function is used to have an extra question when the project name is not valid. |
Don't get me wrong, I am not against switching tools. As least we should explain a bit about why, otherwise this is like "changing the tool because of a bug" (as there are also like to have other bugs in the tool you are replacing with, there will be no end to this). And I guess that's also why @patak-js is suggesting to make into two PRs. As you have provided the detailed explanations, and they sounds reasonable to me now. 👍 |
@Olyno it is not the same. You should be able to create a project name "Hello World" (that is the name of the directory). In the version in this PR you can no longer do that, please check this comment from Evan #2385 (comment)
|
Well, I gave more than this argument:
Changed |
Updated and handled some edge cases so the tests are now passing |
The UX is a lot better with prompts, there a lot of little details that make this a good move ❤️ The only thing is that we lost the ability to use a project name that is not a valid package name. See this comment by Evan: #2385 (comment)
In the current version, after the user enters a project name (we always accepts it), then:
|
Pushed a commit to support non-valid project names. It also allows for users to set project name to Added also a throw if the user doesn't confirm that it is ok to delete the target dir files. I don't know if this is the correct pattern for prompts. Edit: Fixing the tests now 😅 |
Done @patak-js 👍🏻 |
LGTM now, except for the failing tests. @jamesgeorge007 maybe you could help us here? |
Migrating to prompts doesn't call for a major refactor as it offers a similar API surface. diff --git a/packages/create-app/index.js b/packages/create-app/index.js
index 1cbfb075..5f369d0e 100755
--- a/packages/create-app/index.js
+++ b/packages/create-app/index.js
@@ -5,7 +5,7 @@ const fs = require('fs')
const path = require('path')
const argv = require('minimist')(process.argv.slice(2))
// eslint-disable-next-line node/no-restricted-require
-const { prompt } = require('enquirer')
+const prompts = require('prompts')
const {
yellow,
green,
@@ -131,11 +131,18 @@ async function init() {
/**
* @type {{ projectName: string }}
*/
- const { projectName } = await prompt({
- type: 'input',
+ const { projectName } = await prompts({
+ type: 'text',
name: 'projectName',
message: `Project name:`,
- initial: 'vite-project'
+ initial: 'vite-project',
+ onState: ({ aborted }) => {
+ if (aborted) {
+ process.nextTick(() => {
+ process.exit(1)
+ })
+ }
+ }
})
targetDir = projectName
}
@@ -150,7 +157,7 @@ async function init() {
/**
* @type {{ yes: boolean }}
*/
- const { yes } = await prompt({
+ const { yes } = await prompts({
type: 'confirm',
name: 'yes',
initial: 'Y',
@@ -159,7 +166,14 @@ async function init() {
? 'Current directory'
: `Target directory ${targetDir}`) +
' is not empty.\n' +
- 'Remove existing files and continue?'
+ 'Remove existing files and continue?',
+ onState: ({ aborted }) => {
+ if (aborted) {
+ process.nextTick(() => {
+ process.exit(1)
+ })
+ }
+ }
})
if (yes) {
emptyDir(root)
@@ -184,41 +198,44 @@ async function init() {
/**
* @type {{ framework: string }}
*/
- const { framework } = await prompt({
+ const { framework } = await prompts({
type: 'select',
name: 'framework',
message,
- format(name) {
- const framework = FRAMEWORKS.find((v) => v.name === name)
- return framework
- ? framework.color(framework.display || framework.name)
- : name
- },
choices: FRAMEWORKS.map((f) => ({
- name: f.name,
- value: f.name,
- message: f.color(f.display || f.name)
- }))
+ title: f.color(f.display || f.name),
+ value: f.name
+ })),
+ onState: ({ aborted }) => {
+ if (aborted) {
+ process.nextTick(() => {
+ process.exit(1)
+ })
+ }
+ }
})
+
const frameworkInfo = FRAMEWORKS.find((f) => f.name === framework)
if (frameworkInfo.variants) {
/**
* @type {{ name: string }}
*/
- const { name } = await prompt({
+ const { name } = await prompts({
type: 'select',
name: 'name',
- format(name) {
- const variant = frameworkInfo.variants.find((v) => v.name === name)
- return variant ? variant.color(variant.display || variant.name) : name
- },
message: 'Select a variant:',
choices: frameworkInfo.variants.map((v) => ({
- name: v.name,
- value: v.name,
- message: v.color(v.display || v.name)
- }))
+ title: v.color(v.display || v.name),
+ value: v.name
+ })),
+ onState: ({ aborted }) => {
+ if (aborted) {
+ process.nextTick(() => {
+ process.exit(1)
+ })
+ }
+ }
})
template = name
} else {
@@ -288,13 +305,20 @@ async function getValidPackageName(projectName) {
/**
* @type {{ inputPackageName: string }}
*/
- const { inputPackageName } = await prompt({
- type: 'input',
+ const { inputPackageName } = await prompts({
+ type: 'text',
name: 'inputPackageName',
message: `Package name:`,
initial: suggestedPackageName,
validate: (input) =>
- packageNameRegExp.test(input) ? true : 'Invalid package.json name'
+ packageNameRegExp.test(input) ? true : 'Invalid package.json name',
+ onState: ({ aborted }) => {
+ if (aborted) {
+ process.nextTick(() => {
+ process.exit(1)
+ })
+ }
+ }
})
return inputPackageName
} |
Co-authored-by: Anthony Fu <[email protected]> Co-authored-by: patak-js <[email protected]>
Description
This pull request fixes the duplicate selection issue, and replaces
enquirer
withprompts
as CLI tool.Additional context
The first thing I tried was to fix the selection issue:
But after a long look in the code of the
create-app
without being capable to fix the bug, I decided to refactor with a (in my opinion) better CLI tool which isprompts
.What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).