Eu, eu mesmo e… um Projeto Base

Lucas Katayama
Lucas Katayama
Published in
4 min readSep 27, 2016

--

KoaJS e Aurelia

Esse post vou explicar como criar um esqueleto para um projeto web usando Javascript ES6 como linguagem no NodeJS, ExpressJS como framework para API e Aurelia como framework frontend.

ExpressJS

A criação do esqueleto tem como base o gerado com o comando “express”, mas como quero utilizar os recursos das versões mais novas do Javascript, temos que dar uma alterada.

A estrutura de diretórios fica da seguinte maneira:

.
├── lib
│ ├── app.js
│ └── routes
├── package.json
├── public
└── src
├── app.js
└── routes
  • src/ contém arquivos não transpilados
  • lib/ contém os arquivos transpilados
  • src/app.js contém o servidor em questão com as configurações do ExpressJS
  • api/index.js contém as configurações para as rotas abaixo do /api
  • api/resources/*.js as rotas para os recursos
  • public contém os arquivos estáticos, no caso o Aurelia

O app.js ficará da seguinte forma

import fs from 'fs';
import path from 'path';
import http from 'http';
import favicon from 'serve-favicon';
import logger from 'morgan';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import express, {Router} from 'express';
import api from './api';const PORT = process.env.PORT || '3000';
const app = express();
app.set('port', PORT);app.use(favicon(path.join(__dirname, '..', 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '..', 'public')));
app.use('/api', api);app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
next();
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
next();
});
var server = http.createServer(app);server.listen(PORT);

O api/index.js:

import {Router} from 'express';
import Users from './resources/users';
const router = new Router();const config = {
'/users' : Users
}
for(var path in config){
router.use(path, config[path]);
}
export default router;

Ali você pode ver um mapeamento para o reecurso Users para a path /users.

O recurso Users no arquivo api/resources/users.js pode ser configurado da seguinte maneira:

import {Router} from 'express';
const router = new Router();
router.post('/', (req, res, next) => {
res.json({cod : 200, msg : 'OK'});
next();
});
router.get('/', (req, res, next) => {
res.json([]);
next();
});
router.put('/:id', (req, res, next) => {
res.json({cod : 200, msg : 'OK'});
next();
});
router.delete('/:id', (req, res, next) => {
res.json({cod : 200, msg : 'OK'});
next();
});
export default router;

Assim, para “compilar” os arquivos de src/ para lib/ configuramos o package.json com as seguintes dependências:

{
...
"scripts": {
"autobuild": "./node_modules/.bin/babel -w -d lib src/",
"autorun": "./node_modules/.bin/nodemon lib/app.js"
},
"dependencies": {
"body-parser": "1.15.2",
"cookie-parser": "1.4.3",
"express": "4.14.0",
"morgan": "1.7.0",
"serve-favicon": "2.3.0"
},
"devDependencies": {
"babel-cli": "6.14.0",
"babel-preset-es2015": "6.14.0",
"babel-preset-es2016": "6.11.3",
"nodemon": "1.10.2"
},
"babel": {
"presets": [
"es2015"
]
},
...
}

Note a configuração do BabelJS para usar o ES2015.
Note também os scripts do NPM. POdemos então rodar o seguinte comando para buildar e rodar:

$ npm run autobuild
$ npm run autorun

Pronto, teremos um servidor ExpressJS rodando em http://localhost:3000

Aurelia

Para o Aurelia, fazemos download do própio site http://aurelia.io/downloads/basic-aurelia-project.zip

E descompactamos para a pasta public.

Como não quero usar Typescript, mudamos a linha contendo:

<script src=”scripts/config-typescript.js”></script>

Para:

<script src="scripts/config-esnext.js"></script>

Como quero usar o Routing do Aurelia, devemos adicionar o script:

<script src="scripts/aurelia-routing.min.js"></script>

E a configuração para o JSPM

<script src="config.js"></script>

O public/index.html ficará assim:

<!DOCTYPE html>
<html>
<head>
<title>Aurelia</title>
</head>
<body aurelia-app="src/main">
<script src="scripts/system.js"></script>
<script src="config.js"></script>
<script src="scripts/config-esnext.js"></script>
<script src="scripts/aurelia-core.min.js"></script>
<script src="scripts/aurelia-routing.min.js"></script>
<script>
System.import('aurelia-bootstrapper');
</script>
</body>
</html>

Como quero usar Bootstrap e o FontAwesome, vamos então instalar essas dependências e outras dentro da pasta public:

$ jspm install aurelia-fetch-client bootstrap font-awesome css

Próximo passo é criar os arquivos main.js, app.js e app.html dentro da pasta public/src.

main.js

import 'aurelia-fetch-client';export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start().then(() => aurelia.setRoot());
}

app.js

import 'bootstrap/css/bootstrap.min.css!';
import 'font-awesome';
export class App {
configureRouter(config, router) {
this.router = router;
config.title = '7dbs7ws';
config.map([
{ route: '', title: 'Home', name: 'home', moduleId: './home/index' , nav: true}
]);
}
}

app.html

<template>
<div class="col-lg-3">
<ul class="nav nav-sidebar">
<li repeat.for = "row of router.navigation">
<a href.bind = "row.href">${row.title}</a>
</li>
</ul>
</div>
<div class="col-lg-9">
<router-view></router-view>
</div>
</tempalte>

Agora criamos um módulo simples:

Dentro da pasta public/src/home:

index.html

<template>
<div class="jumbotron">
<h1>${heading}</h1>
</div>
</template>

index.js

export class Home {
constructor(){
this.heading = 'Teste';
}
}

Finalmente

Pronto, acho que agora ao acessar http://localhost:3000 você um app base para os projetos.

GitHub

Você pode fazer clone de um aqui também:

EDIT 2016–09–27

Adicionei o AdminLTE, uma variação do Bootstrap com Dashboards.

Assim, foram modificados as dependências:

jspm install -y github:almasaeed2010/AdminLTE

O main.js precisa carregá-lo:

import 'aurelia-fetch-client';
import 'jquery-ui';
import AdminLTE from 'almasaeed2010/AdminLTE';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start()
.then(() => aurelia.setRoot())
.then(() => $.AdminLTE.layout.activate()); // Este é necessário para o layout ficar correto.
}

E o app.html precisa carregar as dependências:

<require from="../jspm_packages/github/almasaeed2010/AdminLTE@2.3.6/bootstrap/css/bootstrap.min.css"></require><require from="../jspm_packages/github/almasaeed2010/AdminLTE@2.3.6/dist/css/AdminLTE.min.css"></require><require from="../jspm_packages/github/almasaeed2010/AdminLTE@2.3.6/dist/css/skins/skin-blue.min.css"></require>

E o index.html tem as classes necessárias para carregar a skin:

<body aurelia-app="src/main" class="hold-transition skin-blue sidebar-mini">

Fora isso, o app.html ainda tem as tags e classes necessárias para deixá-lo na estrutura de dashboard.

Modificações

Deixei de usar o mais famoso ExpressJS e inclui o KoaJS. Do mesmo criador, Koa usa novos recursos do Javascript, como async/await.

Referências

--

--