Skip to content
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

consider a deno new command to encourage best practices #2584

Closed
jorroll opened this issue Jun 26, 2019 · 15 comments
Closed

consider a deno new command to encourage best practices #2584

jorroll opened this issue Jun 26, 2019 · 15 comments

Comments

@jorroll
Copy link
Contributor

jorroll commented Jun 26, 2019

edit: I think my comment below does a better job of explaining what I'm proposing.

Bear with me on this first paragraph, I do have a point...

While I appreciate deno eliminating package.json, there are several aspects of package.json that I find myself missing. For instance, package.json established a convention of adding / aliasing project tasks in the "scripts" section, and in general I've found a good way to learn about a new repo is to start by peaking inside package.json. It can also be helpful to know where to look to find a project's version, etc. All of this really just boils down to the fact that package.json helped push/establish a set of project conventions within the javascript / node community.

I definitely don't want deno to require a set of project conventions, but it would be nice if deno suggested some project conventions / best practices.

The best way that comes to mind to accomplish this would be to add a deno new (or deno init, deno generate, etc) command which scaffolds out a new project directory. This project directory could adhere to whatever the deno "best practices" are.

Would you accept PRs for a feature like this? Do other people think this is a good idea?

For example (obviously up for discussion):

  • have a top level mod.ts file
    • include a comment in the file explaining it's use
  • have a top level deps.ts file
    • include a comment in the file explaining it's use
  • have a top level README.md
    • the generated readme could contain some helpful placeholder text for getting started with deno, as well as other useful "best practice" information
  • etc

The "version 1" implementation of a deno new might just do this. But a "version 2" of a deno new implementation could also allow scaffolding a new project from some sort of config / scaffolding template file. A "version 3" implementation might allow users to add custom named generators to a project, so someone could do deno new service my-service. Etc.

In this way, a deno new command could help to establish general best practices within the deno community, and it could also help establish project specific best practices (through user specified scaffolding templates).

In some hypothetical future, I could imaging many deno "getting started" tutorials beginning with "first install deno by........Then, run deno new hello_world".

Prior art

  • The Angular CLI
    • supports custom, project specific generators (and you can install generators from npm)
    • encourages solid best practices
    • one nice feature of the Angular CLI, is that if you invoke a command without all the required arguments, terminal prompts walk you through adding what's missing. i.e. if you try and generate a new service but forget to specify the service's name, rather than failing the cli asks "What is the name of the service?".
    • con of the angular-cli: it requires an angular.json file in a project's root.

Edit

I suppose, for maximum flexibility, a "scaffolding template" could simply be a script. So deno new service my_service would call some script that's somehow been labeled service and pass it the my_service argument. At that point, the feature is really just looking like a way of defining tasks for a project, which brings up new ideas. But I'll stop ideating here and see what other people are thinking.

@maxuuell
Copy link

I think a deno_init script might work for this, where the script would set up a deno project, based on the flag a user passed to the script. See here for a PR I submitted about the idea.

@jorroll
Copy link
Contributor Author

jorroll commented Jun 26, 2019

@maxuuell just to make sure we're on the same page, you're suggesting that this feature could already be accomplished by using the deno install command to install a new script which does this? Isn't that the same as saying "this isn't needed, just use another tool / cli for this"? I could install a node CLI to accomplish this goal as well.

One of the goals of this issue would be for deno to establish some best practices. It sounds like your suggestion would specifically not address that goal?

Or maybe I'm not understanding your suggestion--is there some way in which the deno_init script would be "official"?

Separately, generating code (and, if you saw my edit, running tasks) is a universal aspect of programming. One of ry's stated goals for deno is as a scripting companion alongside other languages. It seems like code generation (and tasks) fits into that goal. Admittedly, this feature would be strictly in the "quality of life improvement" category.

edit

One of the advantages to baking something like this into the CLI, is the fact that the CLI could automatically pick up project related scaffolding/tasks in some way. Though I realize I'm kinda advocating for two different things here: a deno new best practice repo, as well as the ability to run deno new service to generate a service I define (though in reality, I think deno new service would simply call a script that I had identified as the service script)

@kitsonk
Copy link
Contributor

kitsonk commented Jun 26, 2019

This in general feels like a higher order concern of people doing derivative things. At the Deno level, I don't think we can hold that much of an opinion because the type of workloads that people would author are so diverse. It might be a single file script, it might be a web server and to "enforce" or even advocate would mean we would get it wrong 90% of the time for the 10% of time we got it right.

Angular and things like React Create App are higher order frameworks that can have opinions about how you structure a web application.

Because as you point out there is no package.json there really isn't anything to scaffold, and even if there is, I would think it is really premature to force that opinion on people when there isn't even a consensus of what a good Deno project looks like at this stage. It is something that needs to bake for a while longer, if it is tackled even at all.

@maxuuell
Copy link

@thefliik

... you're suggesting that this feature could already be accomplished by using the deno install command to install a new script which does this? Isn't that the same as saying "this isn't needed, just use another tool / cli for this"? I could install a node CLI to accomplish this goal as well.

You absolutely could create a node script that does the same thing. Totally agree. My intention was only to take advantage of the new deno tools to help create deno projects.

One of the goals of this issue would be for deno to establish some best practices. It sounds like your suggestion would specifically not address that goal?

I thought that, by use a script to generate a scoffold of a deno project, you could enforce some best practices. So far, all I found in the manual and other projects was using mod.ts and deps.ts files. There are probably other best practices that already exist that I don't know about, or more will come as things progress 😅

Or maybe I'm not understanding your suggestion--is there some way in which the deno_init script would be "official"?

No no. Never was intended to be "official". Would be cool if it were 😉 but I don't think the deno team is at that point yet, as @kitsonk mentioned. I just thought, if I built out a script that others could install and use to bootstrap/scaffold projects more quickly, it would help adoption, etc... And it would totally be a quality of life thing.

Hope that helps clarify things 👍

@jorroll
Copy link
Contributor Author

jorroll commented Jun 26, 2019

there isn't even a consensus of what a good Deno project looks like at this stage. It is something that needs to bake for a while longer, if it is tackled even at all.

@kitsonk You bring up good points.

But just to make sure you understand what I'm proposing, let me take one last stab at clarifying (because what I was envisioning is pretty un-opinionated):

User story:

User opens a repo and invokes deno task --list. They see a list of named scripts that the repo has somehow registered with deno. From there, they can do deno task build and the script associated with the build name would run. This could be whatever script a user wanted it to be. deno task build one would invoke the build script with the argument one.

At this point you might be thinking, "what's the different between deno task and deno run?" Really, the only differences are that:

  1. deno task could only invoke scripts that had been somehow registered as "tasks" in that context.
  2. Tasks would be invoked via name rather than file path.
  3. Tasks for a context (e.g. a repo) could be discovered via deno task --list.
  4. Tasks could have description messages attached (shown via deno task --list)

These might seem like minor changes but I really feel like they'd have a big impact on quality of life and usability.

Separately I'd propose that a deno new command be added. deno new would, technically, be almost exactly the same as deno task. The main difference would be that, by convention, scripts executed via deno new would generate code. The only other difference would be that deno new --list would show scripts that had been registered as deno new scripts, while deno task --list would show scripts that had been registered as deno task scripts. So deno new --list and deno task --list would (by convention) show different scripts.

Again these are 100% customizable and the commands are largely just copies of deno run. However they would promote discoverability and establish a convention.

deno new "filepath.ts" could, by default, invoke a script that created a new repo at that filepath. But we could let users replace that default script with another script of their choosing. But, even being able to replace that default, I feel like that default could have a positive impact establishing as-yet-to-be-determined conventions.

These obviously fall under "quality of life changes" and are debatable, but I feel like they are in a similar spirit to deno fmt (which I love). Obviously deno fmt could be achieved via either a deno install script or via deno run a script. But having fmt built into the CLI, and just a single, named command away, makes a huge difference in terms of usability and establishing conventions. 

Anyway, I can definitely appreciate if you still disagree.

@jorroll
Copy link
Contributor Author

jorroll commented Jun 26, 2019

Never was intended to be "official". Would be cool if it were 😉 but I don't think the deno team is at that point yet, as @kitsonk mentioned. I just thought, if I built out a script that others could install and use to bootstrap/scaffold projects more quickly, it would help adoption, etc... And it would totally be a quality of life thing.

@maxuuell 👍 ah gotcha. And it is cool! I definitely appreciate that you made it to work via deno install.

@jorroll
Copy link
Contributor Author

jorroll commented Nov 6, 2019

Closing due to lack of interest

@jorroll jorroll closed this as completed Nov 6, 2019
@ry
Copy link
Member

ry commented Nov 6, 2019

One of the main goals of Deno is to reduce unnecessary boilerplate. Generating a project directory with boilerplate would only be a todo list of boilerplate to remove.

@jorroll
Copy link
Contributor Author

jorroll commented Nov 6, 2019

Well a comment like that makes me worried that you didn’t read the proposal, because it was optional and fully customizable by the end user. I can understand if it’s just not something you want, but it sucks to close a suggestion while feeling like it hasn’t been heard.

But you obviously have a lot of people talking at you, so it happens.

@hayd
Copy link
Contributor

hayd commented Nov 6, 2019

Does creating a template repo suffice for many usecases?
https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository

This can also be created as an external module, e.g. https://github.com/maxuuell/deno_init
(Though it looks like that example needs a lot of fleshing out.)

@ry
Copy link
Member

ry commented Nov 6, 2019

@thefliik Sorry if I was dismissive. TBH I hadn't read your complete proposal but I have now. My comments regarding generated code and "deno new" stand - I really want to avoid boilerplate or mechanisms that can justify adding boilerplate - I prefer this to be as minimal as possible. Regarding scripts or "deno task", I certainly appreciate the usefulness of "npm run" and the "scripts" section of package.json, but I want to avoid having a configuration file (i.e. a package.json like thing) and all the complexity that comes with it... What you're really after is a way for a deno project directory to provide a small set of actions. I wonder if this can be achieved in some other way? What if the convention is to have a file called tools.ts which provided these things. Maybe something like this?

import { register } from "https://deno.land/std/tools/mod.ts";
register({
  start: "deno run server.ts -A",
  lint: "eslint src/**/*.ts",
});

@hayd
Copy link
Contributor

hayd commented Nov 6, 2019

@ry What if you could "register"/install subcommands somehow (into DENO_DIR). In that way deno itself wouldn't need to pick a winner.

@jorroll
Copy link
Contributor Author

jorroll commented Nov 7, 2019

I wonder if this can be achieved in some other way? What if the convention is to have a file called tools.ts which provided these things. Maybe something like this?

@ry, I'm definitely not committed to a particular implementation. How would tools.ts be consumed? Something like deno tools.ts build? That might be the best solution, balancing a desire for flexibility with a desire for discoverability/ease of use. It seems like tasks.ts might be a more descriptive filename--though if you expect the use case for tools.ts to increase over time (in the same way that the different metadata shoved into package.json has increased over time), I could see tools.ts making sense as a filename.

Would it make sense for me to create a new issue for something like: ?

import { register } from "https://deno.land/std/tools/mod.ts";

register({
  start: "deno run server.ts -A",
  lint: "eslint src/**/*.ts",
});

I'm also attracted to @hayd's suggestion of a way (at some point) of installing 3rd-party subcommands for deno, but that seems like it's (ultimately) a separate feature request (it also doesn't address the goal of providing discoverable tasks for a repo).

This being said, with a convention like tools.ts, if (at some point) there is the ability to install optional subcommands for deno, then a user could choose to optionally improve the ergonomics of deno tools.ts by installing a subcommand that built off the "already existing" tools.ts convention.

@jorroll
Copy link
Contributor Author

jorroll commented Nov 7, 2019

@hayd, ry hit the nail on the head:

What you're really after is a way for a deno project directory to provide a small set of actions

I realize that I initially framed this feature request poorly, and it's sort of advocating for two similar, yet distinct, feature requests (a deno task/deno new). The more fundamental one is some form of deno task for the current repo, and a template repo isn't really addressing that goal. However, your suggestion of some way to register 3rd-party subcommands with deno seems like great, if tangential, suggestion.

@brandonkal
Copy link
Contributor

Regarding the syntax proposed by @ry in #2584 (comment)

That looks a lot like Jake. Would a Deno port of that make sense in std?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants