DEK
O que é o DEK
O DEK é uma ferramenta de código aberto para a criação de novos projetos onde é preciso ter controle sobre o fluxo de inicialização e controle das execuções sejam elas síncronas ou assíncronas.
Instalação
Se você deseja iniciar um novo projeto utilizando o Dek, na maioria dos casos, a melhor maneira é usar nossa ferramenta CLI.
$ npm install dek -g
Criação de um novo projeto dek
Para criar um novo projeto Dek use o comando dek init
.
$ dek init nomeDoProjetoDek
Estrutura de pastas do DEK
Ao executar o dek init
, a estrutura do diretório do seu projeto deve ser como o exemplo abaixo:
nomeDoProjetoDek
│-- README.md
│-- index.js
│-- main.js
|-- package.json
|-- .env.example
└───loaders
│-- AfterLoad.js
│-- BeforeLoad.js
Iniciando o seu projeto
Após criar o esqueleto do seu projeto, acesse o diretório
$ cd nomeDoProjetoDek
Ao acessar o diretório do projeto,
$ npm install
Fluxo de carregamento
O carregamento de uma aplicação DEK é dividido em 3 partes:
1. Before Load (loaders/BeforeLoad.js)
Nesse arquivo você define tudo o que precisa ser carregado antes da sua aplicação.
Um bom exemplo da sua utilidade é iniciar o mongodb, redis e outras conexões e dependências antes da sua lógica principal
Exemplo:
import { dek, add } from 'dek'
import express from 'express'
export default async () => {
console.log('(BeforeLoad.js) Aqui começa o fluxo de carregamento.')
try{
add('app', express())
} catch (err) {
console.log(err.message)
}
}
2. Main (main.js)
Este é o script onde a lógica da sua aplicação deve começar. Todas as dependências adicionadas no BeforeLoad.js estão disponíveis agora no escopo do projeto. Você pode acessar, por exemplo, através de dek.variavelAdicionadaAoEscopo
(Ex: dek.express
) ou let { variavelAdicionadaAoEscopo } = dek
.
Exemplo:
import { dek } from 'dek'
export default async () => {
console.log('(main.js) Aqui inicia a sua aplicação')
let { app } = dek
app.get('/', (req, res) => {
res.json({
_id: "5c4a06735fa556025d0c460e",
name: "Teste"
})
})
}
3. After Load (loaders/AfterLoad.js)
Após toda a sua aplicação ser carregada, o script de AfterLoad é chamado.
Exemplo:
import { dek } from 'dek'
export default async () => {
let { app } = dek
try{
await app.listen(3000)
console.log('(express) Servidor conectado com sucesso na porta 3000!')
} catch (err) {
console.log(err)
}
console.log('(AfterLoad.js) O fluxo de carregamento da aplicação dek termina aqui.')
}
Executando sua aplicação DEK
Ao terminar de escrever o seu código nos scripts BeforeLoad.js, main.js e AfterLoad.js, execute o comando :
node index.js
ou
npm start
Seu terminal mostrará a ordem de carregamento dos arquivos do DEK. Mostrando a sequência de ações feitas dentro do código que você escreveu anteriormente.
(BeforeLoad.js) Aqui começa o fluxo de carregamento.
(main.js) Aqui inicia a sua aplicação
(express) Servidor conectado com sucesso na porta 3000!
(AfterLoad.js) O fluxo de carregamento da aplicação dek termina aqui.
Para testar se a sua aplicação está funcionando, acesse http://localhost:3000.
Se você seguir todas as instruções citadas acima, a api deverá retornar o resultado abaixo.
{
"_id": "5c4a06735fa556025d0c460e",
"name": "Teste"
}
Plugins
A ideia por trás do DEK é que ele sozinho apenas organize a ordem e carregamento da sua aplicação e nada mais. Quem dá poder a ele são seus plugins.
Imagine montar uma aplicação inteira apenas instalando plugins.
Como funcionam os plugins?
Os plugins são carregados antes do BeforeLoad.js
e seguem um pattern para que o DEK entenda o que deve ser feito em seu CORE.
Como criar um plugin?
Para criar um novo plugin, execute o comando baixo:
$ dek new plugin HelloWorld
Ao executar este comando, a pasta plugins
será criada junto de uma sub-pasta com o nome escolhido para o seu plugin.
└───plugins
└───HelloWorld
|-- main.js
|-- npm.js
Estrutura do plugin
main.js
O arquivo main.js contem a estrutura principal de um plugin. É o primeiro arquivo que o DEK vai ler ao carregar o seu plugin.
O plugin conta com os seguintes atributos
- name: Nome do seu plugin
- version: Versão do seu plugin seguindo o padrão Semantic Version
- dependencies: Lista de dependências que devem ser carregadas antes do plugin.
- default: Função principal de um plugin. Ela é executada na hora em que o sistema carrega o plugin.
- add:
- Função que adiciona uma variável ou função ao escopo do projeto.
- No código gerado, a função
add
adiciona uma função vazia com o nome HelloWorld
ao escopo do projeto.
- cli: Adiciona uma função ao CLI do dek. Seu funcionamento será explicado em mais detalhes posteriormente.
- generator: Adiciona uma função geradora ao CLI do dek. Seu funcionamento será explicado em mais detalhes posteriormente.
Veja abaixo um exemplo do código gerado:
import { add } from 'dek'
export let name = 'HelloWorld'
export let version = 'v0.1.0'
export let dependencies = []
export default async (arg) => {
add('HelloWorld', async () => {
})
}
export let cli = {
name: 'HelloWorld',
action: async () => {
}
}
export let generator = {
name: 'HelloWorld',
action: async () => {
}
}
Adicione console.log('HelloWorld')
dentro do callback da função add, como no exemplo abaixo.
export default async (arg) => {
add('HelloWorld', async () => {
})
console.log('HelloWorld')
}
Agora inicie sua aplicação novamente node index.js
$ node index.js
HelloWold
(BeforeLoad.js) Aqui começa o fluxo de carregamento.
(main.js) Aqui inicia a sua aplicação
(express) Servidor conectado com sucesso na porta 3000!
(AfterLoad.js) O fluxo de carregamento da aplicação dek termina aqui.
Veja que HelloWorld foi exibido antes do fluxo de toda a aplicação. Esse é o momento exato onde os plugins são carregados. Mas não é só isso que os plugins são capazes de fazer.
A função add
A função add funciona de uma maneira muito simples. Você define uma variável que vai existir dentro do escopo DEK e em seguida define um valor ou função para ele.
Veja no exemplo abaixo como adicionar uma função chamada OlaMundo ao escopo DEK.
export default async (arg) => {
add('OlaMundo', async () => {
console.log('\n\nOLÁ MUNDOOOOO!!!!! ESSE É O MEU PRIMEIRO PLUGIN PARA O DEK\n\n')
})
console.log('HelloWorld')
}
Pronto. Agora o escopo da nossa aplicação DEK conta com a função OlaMundo.
Para testar, abra o arquivo main.js da sua aplicação (não o main.js do plugin) e adicione as linhas abaixo:
import { dek } from 'dek'
export default async () => {
console.log('(main.js) Aqui inicia a sua aplicação')
let { app, OlaMundo } = dek
OlaMundo()
app.get('/', (req, res) => {
res.json({
_id: "5c4a06735fa556025d0c460e",
name: "Teste"
})
})
}
Inicie sua aplcação novamente. O resultado será exatamente como o do exemplo abaixo:
$ node index.js
HelloWold
(BeforeLoad.js) Aqui começa o fluxo de carregamento.
(main.js) Aqui inicia a sua aplicação
OLÁ MUNDOOOOO!!!!! ESSE É O MEU PRIMEIRO PLUGIN PARA O DEK
(express) Servidor conectado com sucesso na porta 3000!
(AfterLoad.js) O fluxo de carregamento da aplicação dek termina aqui.
O arquivo npm.js
Neste arquivo você define quais dependências do npm são necessárias para o plugin funcionar corretamente.
module.exports = {
npm: []
}
Para exemplificar, vamos adicionar o pacote do npm chamado chalk
module.exports = {
npm: ['chalk@2.4.2']
}
Adicione o chalk ao seu plugin
import { add } from 'dek'
import chalk from 'chalk'
export let name = 'HelloWorld'
export let version = 'v0.1.0'
export let dependencies = []
export default async (arg) => {
add('OlaMundo', async () => {
console.log('\n\nOLÁ MUNDOOOOO!!!!! ESSE É O MEU PRIMEIRO PLUGIN PARA O DEK\n\n')
})
console.log(chalk.blue('HelloWorld'))
}
Agora execute novamente sua aplicação
$ node index.js
(node:12321) UnhandledPromiseRejectionWarning: file:///home/dekDeveloper/exemplos/plugins/HelloWorld/main.js:1
Error: Cannot find module 'chalk'
(node:12321) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12321) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Perceba que o npm chalk não foi encontrado.
dek install
Para contornar este problema execute o comando dek install
ou dek i
$ dek install
Instalando dependências
Repositório Express instalado com sucesso!
Repositório Controllers instalado com sucesso!
+ express@4.16.4
+ express@4.16.4
+ chalk@2.4.2
added 7 packages from 3 contributors, updated 1 package and audited 161 packages in 5.494s
found 0 vulnerabilities
npm WARN dek-skeleton@0.7.5 No description
Perceba que chalk foi instalado, mas espere...
Apareceram algumas linhas que nada tem a ver com o que estamos fazendo. Fique tranquilo que nos próximos exemplos você entenderá do que se trata.
Vamos voltar ao nosso exemplo.
Execute novamente a aplicação.
$ node index.js
HelloWorld
(BeforeLoad.js) Aqui começa o fluxo de carregamento.
(main.js) Aqui inicia a sua aplicação
OLÁ MUNDOOOOO!!!!! ESSE É O MEU PRIMEIRO PLUGIN PARA O DEK
(express) Servidor conectado com sucesso na porta 3000!
(AfterLoad.js) O fluxo de carregamento da aplicação dek termina aqui.
Perceba que HelloWorld agora aparece com uma linha azul e nosso plugin está terminado.
Trabalhando com plugins em repositórios do GitHub e outros
Ao executarmos o comando dek install
, além de instalar a dependência chalk@2.4.2 também instalamos dois plugins.
O plugin Express, responsável por adicioinar o express ai escopo DEK e o Controllers, responsável por gerar controllers para a nossa aplicação.
Abra o arquivo package.json e dê uma olhada no atributo dek dependencie
(preste bem atenção, é dekDependencies e não devDependencies).
"dekDependencies": {
"vigiadepreco/Express": "v1.0.0",
"vigiadepreco/Controllers": "v1.0.1"
}
Repare bem no padrão.
"vigiadepreco/Express": "v1.0.0"
- vigiadepreco <- é a conta no gitgub
- Express <- é o nome do repositório
- v1.0.0 <- é a tag criada no repositório para marcar a versão
Você também pode adicionar essa dependência ao dekDependencies
com os padrões:
Caso seu repositório seja privado, poderão ocorrer as seguintes situações:
- Caso seja https, seu nome de usuário e senha serão solicitados
- Caso seja ssh, o sistema utilizará a chave privada presente na sua máquina
Acesse a pasta plugins e veja que mais duas pastas foram criadas:
A partir desse momento, a instância do express criada no BeforeLoad.js não será mais necessária pois ela já é gerada dentro do plugin.
Remova as linhas de BeforeLoad.js abaixo:
import express from 'express'
try{
add('app', express())
} catch (err) {
console.log(err.message)
}
Seu arquivo BeforeLoad.js deverá ficar como no exemplo abaixo:
import { dek, add } from 'dek'
export default async () => {
console.log('(BeforeLoad.js) Aqui começa o fluxo de carregamento.')
}
Execute a sua aplicação novamente e verá que a api ainda está funcionando perfeitamente.