Módulos Próprios com NodeJS

Módulos Próprios com NodeJS

Anteriormente, você aprendeu um pouco mais sobre o funcionamento dos módulos do NodeJS, conhecendo os módulos internos, módulos externos e os módulos próprios.

Nesta lição, nós iremos focar nos módulos próprios, onde aprenderemos o funcionamento de uma estrutura inicial de um módulo, em conjunto com as instruções module.exports e require.

Onde posteriormente, aprenderemos também sobre as novas intruções import e export, advindas do ES6.

Arquivos da lição

Os arquivos que veremos durante o decorrer desta lição, podem ser encontrados nos links abaixo:

O que são Módulos Próprios?

Como dito anteriormente na lição passada, módulos próprios nada mais são do que novas funcionalidades que nós desenvolvemos durante a criação de um projeto.

Serão por meio desses módulos, que iremos organizar o código e adicionar recursos específicos ao nosso aplicativo, modularizando-o em partes menores, lógicas e reutilizáveis.

Esses módulos encapsulam funcionalidades específicas que compõem a lógica do nosso sistema, como por exemplo:

Módulo de autenticação de usuários: supondo que a nossa aplicação lide com um sistema de login/cadastro, podemos criar um módulo separado responsável por lidar especificamente com a autenticação de usuários.

Nesse caso, teriamos um módulo capaz de autenticar um usuário, gerar um token de acesso, apagar a sessão, além de outras funções que podemos adicionar ao decorrer do projeto.

Módulo de manipulação de banco de dados: supondo que a nossa aplicação lide com um banco de dados (Mysql, MongoDB, PostgreSQL...), nós podemos criar um módulo separado que vai lidar com todas as requisições relacionadas ao banco de dados da aplicação.

Nesse caso, teriamos um módulo que poderá conter todas as funções de CRUD (Create, Read, Update e Delete) usadas naquele sistema, por exemplo:

  • createUserDatabase (função que armazena a lógica de criação de uma base de dados de usuário)
  • selectUserByID (função que armazena a lógica responsável por selecionar o usuário pelo ID)
  • updateProductStyle (função que armazena a lógica responsável por atualizar o estilo de um produto específico)
  • deleteToken (função responsável por remover um token)

Módulo de processamento de arquivos: supondo que a nossa aplicação faça a abertura e salvamento de arquivos do tipo .json, podemos criar um módulo que lide com a leitura e escrita desses arquivos. Por exemplo:

  • openJsonFileByPath (função que armazena a lógica de abertura de um arquivo JSON pelo caminho absoluto do arquivo)
  • saveJsonInPath (função que armazena a lógica de salvamento de um arquivo JSON informando um caminho absoluto para o arquivo)
  • checkIfJsonIsEmpty (função que armazena a lógica que verifica se o arquivo JSON está vazio)

Módulo de envio de e-mails: supondo que a nossa aplicação lide com o envio de e-mails para os nossos usuários, também podemos criar um módulo específico para isso. Por exemplo:

  • sendEmailWithSettings (função que armazena a lógica de envio de emails informando as configurações do mesmo)
  • addEmailToQueueWithSettings (função que armazena a lógica que adiciona novos e-mails a uma fila de espera)

Enfim, acredito que já deu para entendeu que podemos modularizar toda a nossa aplicação com NodeJS 😆

Mas, talvez você esteja se perguntando: Como entra o conceito de classes (Orientação a Objetos) do Javascript no mundo do NodeJS?

Classes X Módulos em NodeJS

No mundo do Javascript, podemos aplicar o conceito de classes durante a construção de nossas aplicações.

Já no mundo do NodeJS, nós também podemos utilizar classes, ainda mais que é possível adiciona-las também dentro dos módulos 😉

Mais tarde ainda nesta lição, você verá como é fácil criar classes dentro de módulos do NodeJS.

Trabalhando com Módulos Próprios

O NodeJS trabalha com dois conceitos chamados de import e export, conceitos esses que são utilizados para importar e exportar módulos entre arquivos Javascript.

Veremos o funcionamento de cada um deles a seguir.

Conhecendo o module.exports

O primeiro comando que iremos conhecer agora, é chamado de module.exports, que representa uma maneira de exportar funções, variáveis e objetos disponíveis para outros módulos (ou arquivos da aplicação) que desejam importar essas funcionalidades.

É importante ressaltar que cada arquivo Javascript presente dentro do NodeJS, é considerado um módulo para ele, e possui seu próprio escopo.

Para testarmos, vamos começar criando um novo arquivo em Javascript dentro pasta do seu projeto, chamado de operacoesMatematicas.js:

//Módulo que contem funções matemáticas:

function soma(a, b){
 return a + b;
}

function subtracao(a, b){
 return a - b;
}

function multiplicacao(a, b){
 return a * b;
}

function divisao(a, b){
 return a / b;
}

Como podemos ver nos comandos acima, esse contém 4 operações matemáticas diferentes: soma, subtração, multiplicação e divisão, todos representados por 4 funções que recebem dois parâmetros e retornam o resultado da operação.

Para que esse arquivo seja interpretado pelo NodeJS como um MÓDULO, precisamos fazer o uso do comando module.exports no final do arquivo (operacoesMatematicas.js) da seguinte forma:

module.exports = {
 soma,
 subtracao,
 multiplicacao,
 divisao
};

Tudo o que esse comando faz, é tornar disponível para uso as funções que declaramos logo acima (somasubtraçãomultiplicação e divisão).

Para posteriormente, quando um outro arquivo requisitar esse módulo, tais funções estejam disponíveis para o uso dele.

Veja como ficou o resultado do arquivo final (operacoesMatematicas.js):

//Módulo que contem funções matemáticas:

function soma(a, b){
 return a + b;
}

function subtracao(a, b){
 return a - b;
}

function multiplicacao(a, b){
 return a * b;
}

function divisao(a, b){
 return a / b;
}

module.exports = {
 soma,
 subtracao,
 multiplicacao,
 divisao
};

Perceba que dentro do module.exports, estamos exportando todas as 4 funções separadas por vírgula.

Observe que também é possível exportar uma uníca função por ele:

module.exports = soma;//Nesse caso, só a função soma estará disponível para uso

Caso desejar, você pode exportar mais de uma simultaneamente seguido por vírgula:

module.exports = {
 soma,
 subtracao
};//Somnente as funções soma e subtracao estão disponíveis para uso

Também é possível exportar nossas funções, declarando-as diretamente dentro do module.exports da seguinte forma:

module.exports = {
 soma(a, b){
 return a + b;
 },
 subtracao(a, b){
 return a - b;
 },
 multiplicacao(a, b){
 return a * b;
 },
 divisao(a, b){
 return a / b;
 } 
};

Perceba que no comando acima, não é necessário informar a instrução function antes do nome da função. 

Veja que também é possível exportar uma única função diretamente pelo module.exports da seguinte forma:

module.exports = function soma(a, b) {
 return a + b;
};

Quantos module.exports podem existir dentro de um único módulo?

Dentro de um único módulo do NodeJS, você pode ter apenas um module.exports, a não ser que você crie novas funcionalidades para ele usando a notação de ponto (.):

module.exports.soma = soma;
module.exports.subtracao = subtracao;

No caso do exemplo acima, teriamos acesso ás funções soma e subtração.

Ou você também pode atribuir um objeto com várias propriedades diretamente no module.exports:

module.exports = {
 soma: function(a, b){
 return a + b;
 },
 subtracao: function(a, b){
 return a - b;
 }
};

Beleza, até o momento você viu diversas formas diferentes de se exportar funcionalidades com o module.exports 🙂

Mas como iremos acessar e usar as funcionalidades desse módulo? É o que veremos a seguir!

Selecionando um módulo com require

No mundo do NodeJS, para selecionarmos (e usarmos) um determinado módulo, nós fazemos o uso da função require.

Ela é uma função fundamental do sistema de módulos do NodeJS, pois é usada para incluir (importar) módulos em um outro arquivo Javascript, de modo a permitir que você use funcionalidades disponibilizadas pelo módulo dentro do seu arquivo.

Para testa-la, vamos criar um novo arquivo chamado de app.js dentro da pasta do seu projeto, que por sua vez, fará o uso do módulo operacoesMatematicas.js que criamos anteriormente:

/* Aplicação de Testes (app.js) */

const moduloOperacoesMatematicas = require('./operacoesMatematicas');//Importando o módulo para dentro da constante 'moduloOperacoesMatematicas'

//Fazendo o uso das funcionalidades do módulo:
console.log('Soma: ' + moduloOperacoesMatematicas.soma(14, 55));//Mostra na tela o resultado da soma
console.log('Subtração: ' + moduloOperacoesMatematicas.subtracao(8, 5));//Mostra na tela o resultado da subtração
console.log('Multiplicacao: ' + moduloOperacoesMatematicas.multiplicacao(33, 13));//Mostra na tela o resultado da multiplicação
console.log('Divisao: ' + moduloOperacoesMatematicas.divisao(10, 2));//Mostra na tela o resultado da divisão

Como estamos vendo no comando acima, para fazer o uso do require, você deve fornecer o caminho do arquivo do módulo que deseja importar:

require('./operacoesMatematicas');

Observação: não é necessário informar a extensão (.js) do módulo, pois o NodeJS é capaz de reconhecer o tipo de arquivo de maneira automática. Mas caso preferir, você também pode informar a extensão tranquilamente.

require('./operacoesMatematicas.js');

Em seguida, basta atribuir essa função para dentro de uma variável, no meu caso usei uma constante chamada de moduloOperacoesMatematicas:

const moduloOperacoesMatematicas = require('./operacoesMatematicas');//Importando o módulo para dentro da constante 'moduloOperacoesMatematicas'

Dessa forma, todas as funções que foram exportadas dentro do module.exports, estarão disponíveis para uso por meio da variável moduloOperacoesMatematicas.

Tanto é, que podemos ter acesso a essas funções por meio dela da seguinte forma:

console.log('Soma: ' + moduloOperacoesMatematicas.soma(14, 55));//Mostra na tela o resultado da soma
console.log('Subtração: ' + moduloOperacoesMatematicas.subtracao(8, 5));//Mostra na tela o resultado da subtração
console.log('Multiplicacao: ' + moduloOperacoesMatematicas.multiplicacao(33, 13));//Mostra na tela o resultado da multiplicação
console.log('Divisao: ' + moduloOperacoesMatematicas.divisao(10, 2));//Mostra na tela o resultado da divisão

Para rodar a sua aplicação, basta entrar na pasta do projeto e executar o comando:

node app.js

Observe que o módulo foi adicionado com sucesso dentro do arquivo app.js, e que também fomos capazes de executar nossas operações matemáticas 🤩

Explorando o module.exports

No início desta lição, eu cheguei a comentar que nós podemos exportar variáveis e classes além de meras função com o module.exports, se lembra?

Veremos como tudo isso fuciona abaixo 🤓

Exportando variáveis

Para exportar uma variável usando o module.exports, basta que você a declare no escopo do módulo, e depois faça a exportação:

//seu-modulo.js

const minhaVariavel = 'Olá, isso é uma variável exportada!';
module.exports = minhaVariavel;

Para exportar mais de uma variável simultaneamente, basta refazer aquela mesma declaração que vimos anteriormente:

//seu-modulo.js

const variavel1 = 'Variável 1';
var variavel2 = 'Variável 2';
let variavel3 = 'Variável 3';

module.exports = {
 variavel1,
 variavel2,
 variavel3
};

Para usarmos essas variáveis dentro do app.js, basta fazer o uso da função require da seguinte forma:

/* Aplicação de Testes (app.js) */

const meuModulo = require('./seu-modulo');

console.log(meuModulo.variavel1);
console.log(meuModulo.variavel2);
console.log(meuModulo.variavel3);

Viu como é fácil?

Uma outra forma de se fazer isso é por meio de uma desestruturação ({ variavel1, variavel2, variavel3 }) que pode ser feita ainda no processo de require, observe:

/* Aplicação de Testes (app.js) */

const { variavel1, variavel2, variavel3 } = require('./seu-modulo');

console.log(variavel1);
console.log(variavel2);
console.log(variavel3);

Exportando variáveis e funções simultaneamente

Caso seu módulo possui variáveis e funções declaradas em seu escopo, basta seguir o mesmo procedimento que vimos anteriormente:

//seu-modulo.js

const variavel1 = 'Essa é uma variável';

function olaMundo(){
 console.log('Olá Mundoooo!');
}

module.exports = {
 variavel1,
 olaMundo
};

E dentro do app.js, basta fazer:

/* Aplicação de Testes (app.js) */

const meuModulo = require('./seu-modulo');

console.log(meuModulo.variavel1);
meuModulo.olaMundo();

Exportando classes

Para exportar classes usando o module.exports, o processo também se dá de uma maneira bem simples:

//seu-modulo.js

class MinhaClasse{
 constructor(nome) {
 this.nome = nome;
 }

 saudacao() {
 console.log(`Muito prazer, ${this.nome}!`);
 }
}

module.exports = MinhaClasse;

Já dentro do app.js, basta fazer:

/* Aplicação de Testes (app.js) */

const minhaClasse = require('./seu-modulo');

// Criando uma instância da classe
const instanciaDaClasse = new MinhaClasse('Micilini');

// Chamando um método da classe
instanciaDaClasse.saudacao(); // Saída: Muito Prazer, Micilini!

Caso você tiver mais de uma classe declarada dentro de um mesmo módulo, basta seguir a lógica abaixo:

//seu-modulo.js

class MinhaClasse{
 //...
}

class MinhaClasseDois{
 //...
}

module.exports = {
 MinhaClasse,
 MinhaClasseDois
};

No app.js, acredito que você já saiba o que fazer 😉

Exportando variáveis, funções e classes

Existem módulos que são como uma salada mista, onde você tem acesso a variáveis, funções e classes de forma simultânea, vamos ver como isso funciona:

//seu-modulo.js

const variavel1 = 'Minha Variável...';

function soma(a, b){
 return a + b;
}

class MinhaClasse{
 saudacao(nome){
 console.log('Olá: ' + nome);
 }
}


module.exports = {
 MinhaClasse,
 variavel1,
 soma
};

Já no app.js:

/* Aplicação de Testes (app.js) */

const seuModulo = require('./seu-modulo');

// Usando a variável exportada
console.log(seuModulo.variavel1); // Saída: Minha Variável...

// Usando a função exportada
const resultadoSoma = seuModulo.soma(3, 5);
console.log(resultadoSoma); // Saída: 8

// Usando a classe exportada
const instanciaDaClasse = new seuModulo.MinhaClasse();
instanciaDaClasse.saudacao('Micilini'); // Saída: Olá: Micilini

É possível importar um módulo dentro de outro?

Sim, e veremos muito isso acontecer durante a nossa jornada de desenvolvedor NodeJS, pois dessa forma podemos modularizar ainda mais o nosso código, ajudando na reutilização do mesmo.

Vamos ver como isso funciona na prática 😉

Vamos supor que temos dois módulos dentro da pasta do nosso projeto: moduloA.js e moduloB.js:

// moduloA.js

const variavelA = 'Variável do Módulo A';

function funcaoA() {
 console.log('Estou executando uma função do Módulo A');
}

module.exports = {
 variavelA,
 funcaoA
};
// moduloB.js

const moduloA = require('./moduloA');

function funcaoB() {
 console.log('Estou dentro da função do módulo B!');
 console.log('Estou acessando a variável do módulo A:', moduloA.variavelA);
 moduloA.funcaoA();
}

module.exports = {
 funcaoB
};

Dentro do app.js, você pode chamar o moduloB, que por sua vez estará fazendo o uso do moduloA:

/* Aplicação de Testes (app.js) */

const moduloB = require('./moduloB');

// Usando a função do Módulo B
moduloB.funcaoB();

Como resultado, as funções do moduloB chamaram as funções do móduloA.

Usando módulos exportados como objetos

Anteriormente, eu ensinei a você como exportar módulos por meio de objetos por meio do uso da notação de ponto:

// seu-modulo.js
const soma = (a, b) => a + b;
const subtracao = (a, b) => a - b;

module.exports.soma = soma;
module.exports.subtracao = subtracao;

Em casos como esses, basta acessar o nome do objeto para acessar as funções:

/* Aplicação de Testes (app.js) */

const seuModulo = require('./seu-modulo');

const resultadoSoma = seuModulo.soma(10, 5);//Estamos usando a notação de ponto aqui...
const resultadoSubtracao = seuModulo.subtracao(10, 5);//E aqui também...

console.log(resultadoSoma); 
console.log(resultadoSubtracao);

Viu como é fácil?

Trabalhando com export e import do ES6

Anteriormente nós vimos como criar módulos usando o module.exports, e como importar esses mesmos módulos usando a função require.

Até antes da versão 13.2.0 do NodeJS, essa era a única forma de se criar e importar modulos dentro do ambiente de desenvolvimento.

Com a chegada desta nova versão, o suporte ao ES6 (ECMAScript 6 ou ES2015) foi adicionado ao NodeJS, e com ele uma nova sintaxe de importação e exportação de módulos foi adicionada.

Isso possibilitou uma gama de novos recursos disponíveis, que até então não existiam no module.exports.

É importante ressaltar que até o framework ReactJS faz o uso das instruções import e export, portanto, é bom você já se familiarizar com elas 😊

A única diferença, é que agora você precisa criar os arquivos que representam seus módulos usando a extensão .mjs em vez de .js, o que indica que o módulo segue o padrão do ES6.

Veremos como tudo isso funciona abaixo!

Criando e exportando um módulo (ES6)

Para criar um módulo aos moldes do ES6, você vai precisar criar um arquivo com a extensão .mjs.

Como exemplo, vamos criar um arquivo chamado de operacoesMatematicas.mjs:

//operacoesMatematicas.mjs

export function soma(a, b) {
 return a + b;
}

export function subtracao(a, b) {
 return a - b;
}

export function multiplicacao(a, b) {
 return a * b;
}

export function divisao(a, b) {
 return a / b;
}

Ele é praticamente igual a versão anterior que criamos com o module.exports, a diferença é que estamos fazendo o uso da instrução export em cada função que queremos exportar.

Importando e utilizando um módulo (ES6)

Para importar seu novo módulo em um arquivo Javascript do tipo .mjs, basta usar a função import da seguinte forma:

/* Aplicação de Testes (app.mjs) */

import { soma, subtracao, multiplicacao, divisao } from './operacoesMatematicas.mjs';//Aqui estamos importanto todas as funções que iremos fazer uso (soma, subtracao, multiplicacao, divisao)

console.log(soma(5, 3));// Saída: 8
console.log(subtracao(10, 4));// Saída: 6
console.log(multiplicacao(2, 6));// Saída: 12
console.log(divisao(8, 2));// Saída: 4

Observe que dentro das chaves ({}) do import, estamos importando todas as funções disponíveis para serem importadas.

Caso você queira usar somente a função de soma, você não precisaria declarar as outras:

import { soma } from './operacoesMatematicas.mjs';

Caso você queria usar somente as funções de subtracao e divisão, você poderia informa-las separando-as por vírgulas:

import { subtracao, divisao } from './operacoesMatematicas.mjs';
IMPORTANTE!

Se você executar o app.js por meio do comando [node app.js], a sua aplicação vai gerar o seguinte erro: SyntaxError: Cannot use import statement outside a module. Isso aconteceu pois o ES6 precisa estar habilitado no NodeJS.

Habilitando o suporte ao ES6 no NodeJS

Talvez você tenha se deparado com erro SyntaxError: Cannot use import statement outside a module, quando tentou executar o app.js usando a nova sintaxe do ES6.

Isso aconteceu porque no NodeJS, de forma padrão está configurado para usar o CommonJS (sistema de módulos anterior que faz o uso do module.exports).

Para que o NodeJS reconheça essa nova sintaxe, você vai precisar criar um arquivo chamado de package.json, dentro da pasta do projeto com a seguinte informação:

{
 "type": "module"
}

Após isso, se você executar o seguinte comando no console:

node app.mjs

Você já será capaz de ver o ES6 em ação 🥳

Observação: Sobre o arquivo package.json, fique tranquilo que em lições futuras com toda certeza iremos falar sobre ele.

Explorando o export (ES6)

Com o ES6, você também consegue exportar variáveis e classes além das funções, veremos como isso é feito.

Exportando variáveis (ES6)

Para exportar variáveis usando o export do ES6, basta adicionar essa instrução logo no início da declaração da mesma:

//seu-modulo.mjs

export const nome = "Micilini";
export const rank = 1;

export let tipo = "Portal de Ensino";

Já no app.mjs, basta selecionar as variaveis que você deseja usar:

/* Aplicação de Testes (app.mjs) */

import { nome, rank, tipo } from './seu-modulo.mjs';

console.log(nome);
console.log(rank);
console.log(tipo);

Exportando classes (ES6)

Para exportar classes usando o export do ES6, basta adicionar a instrução logo no início da declaração da classe:

//seu-modulo.mjs

export class MinhaClasse {
 constructor(nome) {
 this.nome = nome;
 }

 saudacao() {
 console.log(`Muito Prazer, ${this.nome}!`);
 }
}

Já no app.mjs, basta fazer a seguinte declaração:

/* Aplicação de Testes (app.mjs) */

import { MinhaClasse } from './MinhaClasse.mjs';

const instancia = new MinhaClasse('Micilini');
instancia.saudacao();

Para exportar mais de uma classe, basta seguir a lógica do export.

Exportando variáveis, funções e classes (ES6)

Sim, existem módulos que atuam como uma salada mista, onde você tem acesso a variáveis, funções e classes simultaneamente.

Veja abaixo como isso pode ser feito:

// seu-modulo.mjs
export const variavel1 = 'Micilini';

export function olaMundo() {
 console.log('Olá Mundooo!');
}

export class MinhaClasse {
 saudacao() {
 console.log('Olá :D');
 }
}

Já dentro do app.mjs, podemos fazer:

/* Aplicação de Testes (app.mjs) */

import { variavel1, olaMundo, MinhaClasse } from './seu-modulo.mjs';

console.log(`Variável 1: ${variavel1}`);

olaMundo();

const instancia = new MinhaClasse();
instancia.saudacao();

Conhecendo o export default (ES6)

No ES6, existe uma sintaxe usada para exportar uma única entidade principal de um módulo, como uma classe, função ou objeto, que será o valor padrão quando o módulo for importado.

Ou seja, é uma forma de exportar uma única função, classe ou variável declarada dentro de um módulo.

Observe como é feita a exportação usando o export default:

//seu-modulo.mjs

const nome = 'Micilini';

// Exportação padrão de uma variável
export default nome;

Já no app.mjs, você pode importar a variável nome sem o uso das chaves ({}):

/* Aplicação de Testes (app.mjs) */

import nome from './seu-modulo.mjs';

console.log('Meu nome é: ' + nome);

Uma das características do export default, é que você pode definir um variável customizada para a entidade que você vai importar:

import nomeCustomizado from './seu-modulo.mjs';

console.log('Meu nome é: ' + nomeCustomizado);//O resultado ainda será Micilini

Observe que no comando acima, eu ainda estou usando a variável nome que existe dentro do módulo, a diferença é que estou atribuindo uma nova nomenclatura para ela no momento do import.

Exportando um objeto com export default

Caso você queria exportar mais de uma única entidade (variável, função ou classe) usando o exports default, você pode fazer isso da seguinte forma:

//meu-modulo.mjs

const variavel1 = 'Micilini';

function olaMundo() {
 console.log('Olá Mundooo!');
}

class MinhaClasse {
 saudacao() {
 console.log('Olá :D');
 }
}

export default {
 variavel1,
 olaMundo,
 MinhaClasse
};

Já no app.mjs, use-o desta maneira:

/* Aplicação de Testes (app.mjs) */

import MeuModulo from './meu-modulo.mjs';

console.log(MeuModulo.variavel1);

MeuModulo.olaMundo();

const instancia = new MeuModulo.MinhaClasse();
instancia.saudacao();

Podemos usar o export default junto com varios outros exports?

Sim, o NodeJS junto com o ES6 permite esse tipo de flexibilidade, observe:

//meu-modulo.mjs

const valorPadrao = 'Algum valor padrão';
export default valorPadrao;

// Outras exportações nomeadas
export const numero = 42;
export function minhaFuncao() {
 console.log('Olá, mundo!');
}

// Exportação de uma classe
export class MinhaClasse {
 constructor() {
 console.log('Instância da MinhaClasse criada.');
 }
}

Já no app.mjs, você pode fazer o seguinte:

/* Aplicação de Testes (app.mjs) */

import ValorPadrao from './meu-modulo.mjs';
console.log(ValorPadrao);

// Importando exportações nomeadas
import { numero, minhaFuncao, MinhaClasse } from './meu-modulos.mjs';

console.log(numero);
minhaFuncao();
const instancia = new MinhaClasse();

Incrível, não acha? 😆

Conclusão

Agora que você já sabe criar, exportar e importar um módulo, creio que você já esta mais do que preparado para aprender sobre os Core Modules e Módulos Externos.

Te aguardo na próxima lição 🥳

Criadores de Conteúdo

Foto do William Lima
William Lima
Fundador da Micilini

Inventor nato, escreve conteudos de programação para o portal da micilini.

Torne-se um MIC 🤖

Mais de 100 mic's já estão conectados na plataforma.