diff --git a/docs/cli/Ignite-CLI.md b/docs/cli/Ignite-CLI.md index 3abb65d89..c381d9e67 100644 --- a/docs/cli/Ignite-CLI.md +++ b/docs/cli/Ignite-CLI.md @@ -98,11 +98,11 @@ Starts the interactive prompt for generating a new Ignite project. Any options n - `--overwrite` overwrite the target directory if it exists - `--targetPath` string, specify a target directory where the project should be created - `--removeDemo` will remove the boilerplate demo code after project creation -- `--mst` flag to specify whether to include MobX-State-Tree in project (can only be set to `false` if `--removeDemo=true`) +- `--state` string, one of `mst` or `none` to include MobX-State-Tree in project (can only be set to `none` if `--removeDemo=true`) - `--useCache` flag specifying to use dependency cache for quicker installs - `--no-timeout` flag to disable the timeout protection (useful for slow internet connections) - `--yes` accept all prompt defaults -- `--workflow` string, one of `expo`, `cng` or `manual` for project initialization +- `--workflow` string, one of `cng` or `manual` for project initialization - `--experimental` comma separated string, indicates experimental features (which may or may not be stable) to turn on during installation. **A CNG workflow is require for these flags** `--workflow=cng` - `expo-router` converts the project to [Expo Router](https://docs.expo.dev/router/introduction/) from React Navigation - `new-arch` enables [The New Architecture](https://reactnative.dev/docs/new-architecture-intro) diff --git a/docs/concept/MobX-State-Tree.md b/docs/concept/MobX-State-Tree.md index f38a0294c..739594b01 100644 --- a/docs/concept/MobX-State-Tree.md +++ b/docs/concept/MobX-State-Tree.md @@ -41,10 +41,10 @@ We also recognize no state management solution is perfect. MST has some known do ### Remove MST Option -We understand that state management is a highly opinionated topic with various options available. To accommodate this, we've added an option in Ignite CLI to remove MobX-State-Tree if you choose so! When Igniting a new project, provide `--mst=false` to remove MobX-State-Tree code from the boilerplate. This option only works when also removing demo code. +We understand that state management is a highly opinionated topic with various options available. To accommodate this, we've added an option in Ignite CLI to remove MobX-State-Tree if you choose so! When Igniting a new project, provide `--state=none` to remove MobX-State-Tree code from the boilerplate. This option only works when also removing demo code. ``` -npx ignite-cli@latest new PizzaApp --removeDemo=true --mst=false +npx ignite-cli@latest new PizzaApp --removeDemo=true --state=none ``` ## Learning MobX-State-Tree diff --git a/src/commands/new.ts b/src/commands/new.ts index 6a6ff995d..94aad0000 100644 --- a/src/commands/new.ts +++ b/src/commands/new.ts @@ -35,6 +35,7 @@ import { findAndRemoveDependencies } from "../tools/dependencies" import { demoDependenciesToRemove } from "../tools/demo" type Workflow = "cng" | "manual" +type StateMgmt = "mst" | "none" export interface Options { /** @@ -137,6 +138,7 @@ export interface Options { * and include them in .gitignore or not * * Input Source: `prompt.ask`| `parameter.option` + * @default cng */ workflow?: Workflow /** @@ -149,9 +151,9 @@ export interface Options { * Whether or not to include MobX-State-Tree boilerplate code * * Input Source: `prompt.ask` | `parameter.option` - * @default true + * @default mst */ - mst?: boolean + state?: StateMgmt } module.exports = { @@ -287,7 +289,7 @@ module.exports = { const defaultWorkflow = "cng" let workflow = useDefault(options.workflow) ? defaultWorkflow : options.workflow if (workflow === undefined) { - const useExpoResponse = await prompt.ask<{ workflow: "cng" | "manual" }>(() => ({ + const useExpoResponse = await prompt.ask<{ workflow: Workflow }>(() => ({ type: "select", name: "workflow", message: "How do you want to manage Native code?", @@ -348,15 +350,15 @@ module.exports = { // #endregion // #region Prompt to Remove MobX-State-Tree code - const defaultMST = true - let includeMST = useDefault(options.mst) ? defaultMST : boolFlag(options.mst) + const defaultMST = "mst" + let stateMgmt = useDefault(options.state) ? defaultMST : options.state - if (includeMST === undefined) { + if (stateMgmt === undefined) { if (!removeDemo) { - includeMST = true + stateMgmt = "mst" } else { // only ask if we're removing the demo code - const includeMSTResponse = await prompt.ask<{ includeMST: boolean }>(() => ({ + const includeMSTResponse = await prompt.ask<{ includeMST: StateMgmt }>(() => ({ type: "confirm", name: "includeMST", message: "Include MobX-State-Tree code? (recommended)", @@ -364,15 +366,15 @@ module.exports = { format: prettyPrompt.format.boolean, prefix, })) - includeMST = includeMSTResponse.includeMST + stateMgmt = includeMSTResponse.includeMST } } - if (!removeDemo && includeMST === false) { + if (!removeDemo && stateMgmt === "none") { p() p(yellow(`Warning: You can't remove MobX-State-Tree code without removing demo code.`)) - p(yellow(`Setting --mst=true`)) - includeMST = true + p(yellow(`Setting --state=mst`)) + stateMgmt = "mst" } // #endregion @@ -658,7 +660,7 @@ module.exports = { packageJsonRaw = findAndRemoveDependencies(packageJsonRaw, demoDependenciesToRemove) } - if (!includeMST) { + if (stateMgmt === "none") { log(`Removing MST dependencies... ${mstDependenciesToRemove.join(", ")}`) packageJsonRaw = findAndRemoveDependencies(packageJsonRaw, mstDependenciesToRemove) } @@ -817,9 +819,7 @@ module.exports = { const CMD = removeDemo === true ? "remove-demo" : "remove-demo-markup" log(`Ignite bin path: ${IGNITE}`) - await system.run(`${IGNITE} ${CMD} "${targetPath}"`, { - onProgress: log, - }) + await system.run(`${IGNITE} ${CMD} "${targetPath}"`, { onProgress: log }) } catch (e) { log(e) p(yellow(`Unable to remove demo ${removeDemoPart}.`)) @@ -854,46 +854,27 @@ module.exports = { // #endregion // #region Remove MST code - if (includeMST) { - // remove MST markup only - startSpinner(`Removing MobX-State-Tree markup`) - try { - const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite") - log(`Ignite bin path: ${IGNITE}`) - await system.run( - `${IGNITE} remove-mst-markup "${targetPath}" "${ - experimentalExpoRouter ? "src" : "app" - }"`, - { - onProgress: log, - }, - ) - } catch (e) { - log(e) - p(yellow(`Unable to remove MobX-State-Tree markup`)) - } - stopSpinner(`Removing MobX-State-Tree markup`, "🌳") - } else { - startSpinner(`Removing MobX-State-Tree code`) - try { - const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite") - log(`Ignite bin path: ${IGNITE}`) - await system.run( - `${IGNITE} remove-mst "${targetPath}" "${experimentalExpoRouter ? "src" : "app"}"`, - { - onProgress: log, - }, - ) - } catch (e) { - log(e) - p( - yellow( - `Unable to remove MobX-State-Tree code. To perform updates manually, check out the recipe with full instructions: https://ignitecookbook.com/docs/recipes/RemoveMobxStateTree`, - ), - ) - } - stopSpinner(`Removing MobX-State-Tree code`, "🌳") + const removeMstPart = stateMgmt === "none" ? "code" : "markup" + startSpinner(`Removing MobX-State-Tree ${removeMstPart}`) + try { + const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite") + const CMD = stateMgmt === "none" ? "remove-mst" : "remove-mst-markup" + + log(`Ignite bin path: ${IGNITE}`) + await system.run( + `${IGNITE} ${CMD} "${targetPath}" "${experimentalExpoRouter ? "src" : "app"}"`, + { onProgress: log }, + ) + } catch (e) { + log(e) + const additionalInfo = + stateMgmt === "none" + ? ` To perform updates manually, check out the recipe with full instructions: https://ignitecookbook.com/docs/recipes/RemoveMobxStateTree` + : "" + p(yellow(`Unable to remove MobX-State-Tree ${removeMstPart}.${additionalInfo}`)) } + stopSpinner(`Removing MobX-State-Tree ${removeMstPart}`, "🌳") + // #endregion // #region Format generator templates EOL for Windows let warnAboutEOL = false @@ -985,7 +966,7 @@ module.exports = { y: yname, yes: yname, noTimeout, - mst: includeMST, + state: stateMgmt, }, projectName, toolbox, diff --git a/test/vanilla/ignite-new-expo-router.test.ts b/test/vanilla/ignite-new-expo-router.test.ts index dc8c85e53..e00056edc 100644 --- a/test/vanilla/ignite-new-expo-router.test.ts +++ b/test/vanilla/ignite-new-expo-router.test.ts @@ -6,7 +6,7 @@ const APP_NAME = "Foo" const originalDir = process.cwd() describe(`ignite new with expo-router`, () => { - describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst --yes`, () => { + describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=mst --yes`, () => { let tempDir: string let result: string let appPath: string @@ -14,7 +14,7 @@ describe(`ignite new with expo-router`, () => { beforeAll(async () => { tempDir = tempy.directory({ prefix: "ignite-" }) result = await runIgnite( - `new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst --yes`, + `new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=mst --yes`, { pre: `cd ${tempDir}`, post: `cd ${originalDir}`, @@ -29,7 +29,7 @@ describe(`ignite new with expo-router`, () => { }) it("should convert to Expo Router with MST", async () => { - expect(result).toContain("--mst") + expect(result).toContain("--state=mst") // make sure src/navigators, src/screens, app/, app.tsx is gone const dirs = filesystem.list(appPath) @@ -99,7 +99,7 @@ describe(`ignite new with expo-router`, () => { }) }) - describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst-false --yes`, () => { + describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state-none --yes`, () => { let tempDir: string let result: string let appPath: string @@ -107,7 +107,7 @@ describe(`ignite new with expo-router`, () => { beforeAll(async () => { tempDir = tempy.directory({ prefix: "ignite-" }) result = await runIgnite( - `new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst=false --remove-demo --yes`, + `new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=none --remove-demo --yes`, { pre: `cd ${tempDir}`, post: `cd ${originalDir}`, @@ -122,8 +122,8 @@ describe(`ignite new with expo-router`, () => { }) it("should convert to Expo Router without MST", async () => { - expect(result).toContain("--mst=false") - expect(result).not.toContain("Setting --mst=true") + expect(result).toContain("--state=none") + expect(result).not.toContain("Setting --state=mst") // check the contents of ignite/templates const templates = filesystem.list(`${appPath}/ignite/templates`)