Frontity CLI - Create command

Collection of ideas on what we need to do with the frontity create command and how we are going to implement it.

Contraints

  • Support for Node v8.10.
  • Support for Linux, macOS and Windows.
  • When using npx it shouldn’t download anything but frontity. (e.g. @frontity/core)

Create app

Command

frontity create [options] [name]

User stories

  • :white_check_mark: - As a developer, I want to generate a new app inside a new directory named by me.
  • :white_check_mark: - As a developer, I want to generate a new app in my current directory if the directory is empty or is a new GitHub repo.
  • :white_check_mark: - As a developer, I want to generate a new app with TypeScript support.
  • :white_check_mark: - As a developer, I want to use frontity create and get prompts about the initial setup of my app.
  • :white_check_mark: - As a developer, I also want to use frontity create programmatically (e.g. import { create } from "frontity").
  • :white_check_mark: - As a developer, if the command throws, I want it to undo any work done to that point.

Parameters

  • name (optional)
    A name for the app.

Options

  • -t, --typescript
    The app will be configured to use TypeScript.
  • -c, --use-cwd
    The app will be generated in the current working directory

Result

A directory with the following structure:

my-project/
|__ node_modules/
|__ packages/
|   |__ mars-theme/
|__ package.json
|__ frontity.settings.(js|ts)
|__ tsconfig.json ?

Steps

  1. Validate and parse options.
  2. Ensure that the directory exists and is empty.
  3. Generate a package.json file.
  4. Generate a frontity.settings.js file. (frontity.settinigs.ts if --typescript options is passed)
  5. Create a packages/ directory and clone @frontity/mars-theme inside it.
  6. Install dependencies.
  7. On error: Revert progress.

Create package

Command

frontity create-package [options] [name]

User stories

  • :x: - As a developer, I want to generate an environment ready to start developing my package.
  • :x: - As a developer, I want to generate an environment ready to use with TypeScript.
  • :x: - As a developer, I want to generate a new package in an existent Frontity app.

Result

I’m guessing that the directory structure for packages would be the same as with apps, but I’m not sure. In this case, the important code is inside the package folder, and it should be a git repo. Maybe we should avoid to create a git repo on the root directory.

A scenario that crosses my mind is when we are developing a package, we save the code of that package on Github, but we had some custom config in the root directory to help with development, and that config won’t be saved in Github. To restore that setup with just a command would be desirable but not possible. How can we approach this?

What do you prefer for create app and create package?

  • Two different commands
  • One command with --package option

0 voters

If you have any other suggestion please write them below.

@luisherranz @david let me know what you think, if I’m missing something (probably) and if you have any other ideas on how frontity create should work :smile:

Great work. I think it’s a great plan.

Just a design note: we need to make sure our APIS can be used in three levels:

  1. Programmatic, passing options (i.e, using node require)
  2. CLI, using user input.
  3. CLI, passing args.

So, instead of coding frontity create only for the cli it should work first like:

import { create } from 'frontity';

const options = { typescript: true };

create(options);

Use it with cli and args:

> frontity create --typescript 

And finally with no args, using a library of questions like inquirer.

> frontity create

- What is the name of the folder?
/my-app
- Do you want to use typescript? [Y/n]

The cli obviously uses the programmatic code underneath.

1 Like

I hadn’t think of the programmatic way. I’ll add it to the post.

I think it’s a good pattern and provides the tool to do the Frontity Admin in the future and makes it “hackable” to others. The “cli with args” option is also good for things like travis and whatnot.

Yeah, great work, @orballo!

Regarding on how to create apps or packages, I think it’s best to use two different commands, even if you haven’t created an app first you won’t be able to use frontity create-package.

I mean, it makes sense to create an app and be able to add one or more packages to that app, develop them in the same project and then, with another command, publish them separately in npm.

Something like:

> frontity create my-app
> frontity create-package my-pkg
> frontity publish my-pkg

What do you think?

I didn’t see it that way. Maybe we could support both ways. What worries me here, is how the repos are going to be used.

If I have an app, I’d like to have a repo with everything, not just my custom package. But maybe I’d like to also have a repo for my custom package (e.g. my theme).

If what I’m doing is to develop a package for the community, I don’t care about the app repo, I’d only want to save the package and that’s gonna be my repo. But, there are some configs in the app that I use for development that would be worth saving, and I’d be loosing them. I don’t know how to make all of this to work together.

I thought about a file called frontity.development.js inside my package, or something like that, to store the settings I need in the app to develop my package, and them another user could just frontity clone-package [email protected]:my/package and generate the whole environment ready to run frontity dev and start coding.

I actually don’t know if all this trouble is really necessary or I’m just overthinking it :sweat_smile:

PS: Two commands wins!

Would it make sense to add an option called --now that would generate also a now.json file?

now is going to be only one of the possible ways to deploy Frontity so I wouldn’t add anything specific to the cli.

My take on this is: the dev creates the theme/extension inside a “Frontity project”, not in a separate project.

my-custom-theme-project/
|__ .git/
|__ node_modules/
|__ packages/
    |__ my-custom-theme/ # <- the dev wants to publish only this
          |__ package.json
          |__ src/
|__ package.json
|__ frontity.settings.js

When the theme/extension is ready to be published, the dev simply uses frontity publish my-custom-theme and the cli does the magic. The themes/extensions already need a package.json file: they are ready to be published in npm.

The frontity publish command only checks things like if the keywords are right (as suggested by @David a while ago).

Regarding git, the devs can choose if they want to keep a “Frontity project git” (which I think it should be our recommendation), create a git submodule or only use git inside my-custom-theme:

my-custom-theme-project/
|__ node_modules/
|__ packages/
    |__ my-custom-theme/
          |__ .git/
          |__ package.json
          |__ src/
|__ package.json
|__ frontity.settings.js

For that reason, we need to “clone” packages from npm and not from github:

So, it looks like we need naming for:

> frontity create my-app
> frontity create-package my-pkg
> frontity publish-package my-pkg
> frontity clone-package other-pkg

Maybe we can name create so we don’t have to name with -package the rest:

> frontity create-app my-app
> frontity create my-pkg
> frontity publish my-pkg
> frontity clone other-pkg

frontity create could fail gracefully if the dev is not in a Frontity project folder and suggest to use create-app instead.

I don’t quite like clone much because it may be confusing (we won’t add the .git folder).

Ok, I’ll be updating the first post with any changes I come up with during development and the ideas you are posting here.

@luisherranz once we have dev, build and serve in frontity, do we still need those commands to run in @frontity/core? I mean as scripts in its package.json.

No, we can use frontity dev and so on everywhere.

It’d be interesting to think about the settings of wp-source:

  • Give the user the default settings populated, like { api: "https://test.frontity.io/wp-json/" }.
  • Ask the user about those settings in the create.

And any other setting that needs to be set so the app works.

https://vadimdemedes.com/posts/creating-clis-with-ink-react-and-a-bit-of-magic

I like the idea of doing the CLI with React.

What do you think @orballo?

1 Like

I think I’d love to try it out :smile:

1 Like

Maybe next week after the beta is out?

I really like the final frontity create! I think it’s really good, maybe we don’t need to invest more time now on it right now and we should focus on other important stuff.

Yup. After the beta we can try pastel and ink, and also implement the create-package function.

If we transpile the typescript code to javascript, it cannot access the frontity.settings.ts file.

So either we:

  1. Don’t transpile the frontity code and run it using ts-node.
  2. Transpile frontity.settings.ts with tsc before Frontity starts.

@orballo can you take a look at it?

I think I’ll try the first one first. ts-node has a programmatic option: https://github.com/TypeStrong/ts-node#programmatic.

  • It can work with require('ts-node').register() inside the code
  • It can work with node -r ts-node/register in the command line.

EDIT: Uh, and it has a transpile-only option :slight_smile: