dexa
v0.3.1
Published
dexa is a CLI tool that allows you to capture your preferred tech stack as a project template with generators
Downloads
1
Maintainers
Readme
dexa
create awesome project templates turbocharged with generators/scaffolders!
dexa is a CLI tool that allows developers and teams to capture their preferred tech stacks as a project template and a set of code generators.
Each of these stacks can be distributed as a git repository. Create them in a publicly available service such as Github to encourage usage and sharing across the wider community. But you are also free to use dexa with private repositories.
Installation
Requires Node.js 14 or later!
You can install dexa as a global tool, making the dx
executable available in your shell:
# install
npm install -g dexa
# verify
dx --version
dx stack list
Alternatively, you can use npx
to run dexa commands without installing as a global tool:
npx dexa --version
npx dexa stack list
Getting started
What is a stack
Dexa allows users to create and use stacks, where each stack is a project template combined with code generators. To better understand what a stack is, let's use an existing stack in our test samples.
The hello-world-stack creates a hello world Node.js console application. To install it, use the dx stack add
command, pointing to the git repo where the stack is located
dx stack add hello-world https://github.com/kaizendorks/dexa/test/stack-fixtures/hello-world-stack
Let's now create a project using the stack. For this, you use the dx init
command and the name you gave to the stack when installed.
dx init hello-world my-first-project
You can see all the installed stacks with
dx init --help
Once finished, it will have created a new folder named my-first-project
, which contains the project created by the stack.
Let's run the project to verify it indeed created a working project:
cd ./my-first-project
node index.js
Hello World!
Awesome, looks like the stack successfully creates hello world console applications.
Let's now explore the code generators available with this stack. Any stack can define 2 flavours of generators:
- features, which are added to your project with the
dx add
command. These are meant to be optional features that are optionally added once to each project - scaffolders, which encapsulate the boilerplate for elementes of which you can add many to your project
Each stack is defined with a particular domain in mind, so the generators implemented by each stack will be based on that context. For example, a stack for creating web applications with Vue.js and Fastify migh provide features such as
unit-test
,i18n
orgraphQL
, and scaffolders such aspage
,component
orrest-api
.
Let's see them in action. Begin by adding the unit-test
feature:
dx add unit-test
This has added a very simple unit test to our project. For completeness, let's verify it works
node ./test/greeter.test.js
Great, now let's scaffold a new greeter
so the application says more than "Hello World"
dx generate greeter tutorial
And verify it generated working code
node index.js
Hello World!
Hello World from the greeter tutorial!
Note the parameter
tutorial
provided in the command has been used inside the template of thegreeter
scaffolder.
Yay, the stack can generate code! You can cleanup with:
cd ../
rm -rf ./my-first-project
dx stack delete hello-world
How to create a stack
The sample hello world stack we have seen above is great to get a sense on how dexa works. But chances are that you are not interested in creating more Node.js hello world applications.
The good news are that you can create your own stacks, and define whatever project templates and generators you want! Let's see how to create one.
A stack just needs to follow a certain structure organising the templates:
/init
the project template
/add
each feature has a subfolder with its template
/generate
each scaffolder has a subfolder with its template
This is the basic structure. See the reference guide for more advanced usages
To make things even simpler, dexa comes with a predefined stack named dexa-stack
that can be used to create your own stacks:
dx init dexa-stack my-stack
If you inspect the generated files, it looks like this:
my-stack
├── README.md
├── add
│ └── README.md
├── generate
│ └── README.md
└── init
├── sample-copy.md
└── sample-template.md.hbs
Those various README.md files contain valuable information on how a stack works and how you can update the project template as well as creating your own code generators.
Can we now test our stack? Yes you can test it directly from its local folder, without publishing it to git.
As per the development instructions in the generated README.md file, install the stack by running in its root folder:
dx stack add my-stack $(pwd)
Now on a separated terminal and folder, try generating a project using your stack:
dx init my-stack test-project
If you inspect the generated project, you will notice the stack used the template defined inside its ./init folder.
test-project
├── sample-copy.md
└── sample-template.md
Take a moment to inspect the files inside the ./init
template folder. Notice how the .hbs
extension makes the file a dynamic template with placeholders. If you want to regenerate the project after modifying the files, use the same init command with the override flag (--override
or -o
):
dx init my-stack test-project --override
How to add code generators to a stack
Let's now see how to define code generators. Each generator is just a folder containing a template similar to the ./init
template. The template folder for a feature generator lives inside the ./add
folder, while the template folder for a scaffolder lives inside the ./generate
folder.
You can manually create these folders, or use the commands provided by the dexa-stack
stack. For example, lets add a feature template using:
dx generate feature my-feature
Your stack should now like follows:
my-stack
├── README.md
├── add
│ ├── README.md
│ └── my-feature
│ └── README.md
├── generate
│ └── README.md
└── init
├── sample-copy.md
└── sample-template.md.hbs
Take a moment to create some files and subfolder inside the ./add/my-feature
folder.
Once you are ready, navigate to the folder where you created the test-project
. Let's try your feature generator:
dx add my-feature
Awesome! You have created your first feature generator.
Try the same with the scaffolder. Back at the root of the stack definition, run (please bear with me):
dx generate generator my-generator
Notice there is a new folder ./generate/my-generator
which contains the template for the new generator.
my-stack
├── README.md
├── add
│ ├── README.md
│ └── my-feature
│ └── README.md
├── generate
│ ├── README.md
│ └── my-generator
│ └── README.md
└── init
├── sample-copy.md
└── sample-template.md.hbs
As before, take another moment to update/create files inside the template folder ./generate/my-generator
.
When a user invokes a
dx generate
command, in addition to the name of the generator, there is a second parameter which is the name of that particular instance of the generator. For example, assume a generator that creates new REST APIs. You might rundx generate rest-api customer
anddx generate rest-api profile
to create the customer and profile APIs respectively The__name__
part of any of the template file/folder names will be replaced withcustomer
andprofile
respectively. Inside any.hbs
files of the template, you can similarly use the placeholder{{ userOptions.name }}
.
Once you are ready, navigate to the test-project
folder and give it a go:
dx generate my-generator foo
Great! And this finishes the basics on how to create your own stacks.
Check the reference section for more advanced scenarios like adding extra input parameters or defining functions to run when invoking the code generators.
The only remaining (optional) step is to publish your stack so others can use it. Simply publish the stack to a git repo, allowing anyone with access to that repo to install it using a command like dx stack add https://github.com/username/reponame
.
Reference
Installing stacks
TBC
Using stacks
TBC
Creating stacks
TBC
API
TBC
Examples
See test stacks
FAQ
How can dexa help you?
Imagine you work in a team that frequently creates web applications with Vue3 and fastify. You probably have an opinionated way of setting these up, so you can capture your project template in a repo. This way you can dx stack add
your repo as a stack in dexa, so you can later create projects with dx init my-vue-fastify-template
.
You might sometimes use docker, you can then expand your stack repo with another template that adds docker and compose files so you can dx add docker
. In some projects you might use postgre while in others you might use mongoDB, you can then capture 2 further templates that allow you to dx add postgre
or dx add mongo
to your project.
You will likely find yourself regularly creating elements like pages or apis to your web application. Dexa can also help you by expanding your stack with template generators so you can dx generate page new-page
or dx generate api new-api
!
This means you can create your dexa stack as a repo with the following structure:
/
|__ /init
| |__ fileA // can be any extension (and copied as is) or `.hbs` (with replacements and helpers)
| |__ /some/folder/fileB
| |__ ... more template files and folders
|__ /add
| |__ /docker
| | |__ ...
| |__ /postgre
| | |__ ...
| |__ /mongo
| |__ ...
|__ /generate
| |__ /api
| | |__ ...
| |__ /page
| |__ ...
|__ dexa.js // optional file, defines additional metadata/options/arguments for each template
Once the stack is defined in a repo:
- Install the stack by pointing to the repo, as in
dx stack add [email protected]:DaniJG/my-stack.git
- Create a new project using the name of the stack, as in
dx init my-stack
- Add stack features to a generated project by running
dx add
commands within the project root folder, as indx add docker
- Generate code by running
dx generate
commands within the project root folder, as indx generate page my-new-page
Is it limited to JavaScript or web projects?
Absolutely not! While dexa is written in JavaScript, you can define stack templates for any language. In a nutshell, dexa will render the templates you define, what those templates contain is entirely up to you.
For example, you could create a terraform stack so you can dx init terraform
. This stack could define features such as S3 or azure blob remote storage so you can dx add remote-aws-s3
or dx add remote-azure-blob
. In a similar fashion, you could then create generators for any common terraform modules you typically use, allowing you to dx generate s3-bucket
or dx generate aws-kubernetes
.
Can I use a project template without generators?
You can define a stack by pointing to a repo that contains just a project template like this vue-vite-tailwind starter
dx stack add vue-vite https://github.com/web2033/vite-vue3-tailwind-starter
You will be able to create new projects using that template as in dx init vue-vite
, but here will be no dx add
or dx generate
commands available for those generated projects.
This is similar to using degit, except you can keep track of these templates as dexa stacks.
Changelog and Roadmap
See CHANGELOG.md
License
MIT © by its authors
See LICENSE.md