Veja nesse artigo como criar um projeto para upload de arquivo utilizando Node.js + TypeScript e Azure. A seguir você tem dois links demonstrando um passo a passo do upload para uma pasta até o envio para o Azure Storage e depois alguns vídeos demonstrando a construção de um middler.
JWT — JSON Web Token / Vídeos
Veja nesse artigo como trabalhar com JWT
Recentemente eu liberei mais um módulo do meu curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, nesse estou demonstrando como trabalhar com JWT. Caso tenha interesse em ver esse conteudo, segue alguns links abaixo:
- Node.js: criando um token JWT sem plugin
- Conhecendo o (JWT) na teoria e na prática
- Angular decode payload JWT
- programadriano/nodejs-jwt
Introdução ao JWT
JWT — JSON Web Token — 2 Parte
JWT — Criando a secret key
Criando a classe de Autenticação
Importando o middler de autenticação
JQT — Gerando o token
Testando a segurança nas rotas
Gostou deste artigo? Comente abaixo!
Referência: https://programadriano.medium.com/jwt-json-web-token-2039797ba126
(JWT) JSON Web Token
Conhecendo o (JWT) na teoria e na prática.
Introdução
Quando estamos trabalhando com API’s, nós precisamos pensar na segurança no momento no momento de trafegar os dados e principalmente no nível de permissão que cada usuário deverá ter. Existem muitas formas de se fazer isso, mas uma que vem se destacando a cada dia que se passa é o JWT (JSON Web Token), por ser muito seguro e fácil de se implementar. Nas próximas sessões, será abordado a sua teoria com alguns exemplos e no final iremos criar uma aplicação com Node.js para exemplificarmos melhor o seu funcionamento.
Bom, o JWT (JSON Web Token) é um sistema de transferência de dados que pode ser enviado via POST ou em um cabeçalho HTTP (header) de maneira “segura”, essa informação é assinada digitalmente por um algoritmo HMAC, ou um par de chaves pública/privada usando RSA. Podemos ver na imagem a baixo um cenário onde será requisitado um token através do Verbo HTTP POST, que irá devolver um token validado para que nas próximas requisições que utilizem os Verbos HTTP possam utilizar.
A estrutura dele é formada por 3 partes: Header, Payload e Signature. Vamos entender melhor elas:
Header
O Header consiste em duas partes encodados em Base64 sendo:
- O Tipo (JWT)
- E o algoritmo de Hash que pode ser (HMAC SHA256 ou RSA).
{ "alg": "HS256", "typ": "JWT" }
Payload (Claims)
Os payloads são objetos JSON que contem os claims, nessa parte que nós trabalhamos com os “pedidos”, carga de dados ou dados enviados. Existem 3 tipos de claims em Payloads: reserved, public, e private claims.
Reserved claims: Atributos não obrigatórios (mas recomendados) que podem ser um conjunto de informações uteis e interoperáveis normalmente utilizados por protocolos de segurança em API’s:
- “iss” (Issuer) Origem do token
- “iat” (issueAt) Timestamp de quando o token foi gerado
- “exp” (Expiration) Timestamp de quando o token expira
- “sub” (Subject) Entidade a quem o token pertence, normalmente o ID do usuário
- Public claims: São atributos que definem o uso do JWT e informações úteis para a aplicação.
- Private claims: São atributos definidos especialmente para compartilhar informações entre aplicações.
Exemplo:
{ "iss": "127.0.0.13", "exp": 1300819380, "user": "programadriano", "admin": true }
Signature
Essa é a terceira e última parte do JWT, para que possamos ter um token, nós precisamos de um Header, Payload, o algoritmo definido na header, um secret definido pela nossa aplicação. Vamos ver um exemplo com a utilização do HMAC SHA256:
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload); + "." + HMACSHA256(encodedString, 'secret');
O seu retorno seria o token a baixo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IlRoaWFnbyIsInN1YiI6IjEzIiwianRpIjoiZDBlMGFkZDItOTlkMC00NWY1LThlYzEtY2FiYzIwZjkxMGYyIiwiaWF0IjoxNTAwMDMzMjE0LCJKd3RWYWxpZGF0aW9uIjoiVXN1YXJpbyIsIm5iZiI6MTUwMDAzMzIxMywiZXhwIjoxNTAwMDMzMjczLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.SmjuyXgloA2RUhIlAEetrQwfC0EhBmhu-xOMzyY3Y_Q
Podemos perceber que o nosso token está dividido em três partes separadas por “.”, conforme nós utilizamos no momento da criação.
Primeira parte: Header .
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
Segunda parte: Payload.
eyJ1bmlxdWVfbmFtZSI6IlRoaWFnbyIsInN1YiI6IjEzIiwianRpIjoiZDBlMGFkZDItOTlkMC00NWY1LThlYzEtY2FiYzIwZjkxMGYyIiwiaWF0IjoxNTAwMDMzMjE0LCJKd3RWYWxpZGF0aW9uIjoiVXN1YXJpbyIsIm5iZiI6MTUwMDAzMzIxMywiZXhwIjoxNTAwMDMzMjczLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.
Terceira parte: Secret.
SmjuyXgloA2RUhIlAEetrQwfC0EhBmhu-xOMzyY3Y_Q
Quando um usuário faz uma requisição ao servidor passando os seus dados de login, o servidor analisa e retorna um token com uma validade, para que o usuário possa navegar pelo sistema.
Para que possamos validar se o nosso token está correto podemos utilizar o próprio site do JWT. Para isso, basta copiar o token acima que criamos para esse exemplo e colar na parte Encoded do site. Podemos ver o seu retorno dessa validação na imagem a baixo:
Agora lembra que acima comentamos sobre a palavra chave? Podemos adicionar ela na parte VERIFY SIGNATURE do site, para esse exemplo nós utilizamos a frase: batman batman batman, notem que após colocarmos ela irá mudar o status da nossa assinatura conforme a baixo de Invalid Signature para Signature Verified.
Nessa primeira parte nós conseguimos criar o nosso token e validar ele pelo próprio site do JWT, mas como funcionária em um projeto real? Vamos criar uma API em Node.js e utilizar o postman para que possamos validar as nossas requisições.
Exemplo prático
Nosso primeiro passo será a criação de um novo projeto Node.js, para que esse artigo não fique muito longo, vamos resumir essa etapa em:
1º Crie um diretório para o nosso projeto;
2º Execute o comando npm init -y;
3º Abrir uma IDE de nossa preferencia e criar uma estrutura básica como na imagem a baixo, para esse exemplo nós iremos utilizar o Visual Studio Code, ele é uma ferramente muito completa e grátis desenvolvida pela Microsoft. Caso queria instalar ele, basta baixar o seu executável no link Download.
Vamos agora adicionar os pacotes necessários para esse artigo, no seu arquivo package.json adicione as seguintes dependências:
},"dependencies": { "body-parser": "^1.15.0", "express": "^4.13.4", "jsonwebtoken": "^5.7.0", "mongoose": "^4.4.5", "morgan": "^1.7.0" }
Para que possamos baixar esse pacotes para o nosso projeto, execute o comando npm install, a execução dele irá criar uma pasta chamada node_modules e dentro dela os nossos pacotes.
Nosso próximo passo será a implementação da nossa classe user. Para isso, copie e cole o código a baixo dentro do seu arquivo user.js, que está dentro do diretório models.
class User { constructor(name, admin) { this.name = name; this.admin = admin; }}; module.exports = User;
Agora nós iremos implementar o nosso server.js, esse será o arquivo principal do nosso projeto.
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var morgan = require('morgan'); var jwt = require('jsonwebtoken'); var user = require('./models/user');
Nessa primeira parte estamos importando os nossos pacotes, até aqui nenhuma novidade, vamos agora adicionar o código que será responsável para realizar a conversão dos nossos dados para JSON:
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json());
Vamos agora referenciar o código que será responsável por gerenciar os logs das nossas requisições e apresentar eles na nossa console:
app.use(morgan(‘dev’));
Para que possamos testar o pacote Morgan e validar o nosso código, vamos criar a nossa primeira rota:
var apiRoutes = express.Router(); apiRoutes.get('/', function (req, res) { res.json({ message: 'Node.js com JWT' }); }); app.use('/', apiRoutes); var port = process.env.PORT || 8000; app.listen(port); console.log('Aplicação rodando na porta:' + port);
Vamos entender o código acima, na primeira linha nós estamos chamando o Router do pacote Express, em seguida nós criamos o nosso primeiro método Get retornando uma mensagem, por fim estamos passando a porta que o nosso projeto irá rodar e adicionando um listen nela. Para executar o código, dentro da console digite o comando node server.js, em seguida vamos abrir no nosso navegador o endereço: http://localhost:8000/ ele deve retornar a mensagem: “Node.js com JWT” e o senguinte log na nossa console:
Com isso nos conseguimos validar o pacote morgan e a nossa requisição HTTP com o express, vamos agora implementar o JWT. Para isso, vamos criar um novo método POST no nosso arquivo server.js.
apiRoutes.post('/', function (req, res) { if (req.body.UserName != "tadriano" || req.body.PassWord != "102030") { res.json({ success: false, message: 'Usuário ou senha incorreto(s)!' }); } else { let usuario = new user() { name : "tadriano"; admin: true }; var token = jwt.sign(usuario, 'batman batman batman', { expiresInMinutes: 1440 }); res.json({ success: true, message: 'Token criado!!!', toke: token }); } });
Para que esse artigo não fique muito longo, nós criamos uma validação conhecida como Hard Code, em seguida como não estamos buscando o nosso usuário no banco nós criamos um novo, para que possamos implementar os dados da nossa assinatura, em seguida nós retornamos uma mensagem de sucesso e o nosso token. Para validar essa etapa nós iremos utilizar o Postman, uma ferramenta do google chrome que auxilia nos testes a requisições HTTP. Com ele aberto adicione a URL do projeto com a porta e o usuário e senha na Body. A imagem a baixo demonstra esse implementação:
Feito isso podemos enviar a nossa requisição que irá retornar o nosso token. Podemos ver esse retorno na imagem a baixo:
Agora para finalizar esse artigo vamos criar um middler para verificar se a requisição está com o token ou se ele é um token é valido. Para isso, vamos colar o código a baixo depois do nosso método POST.
apiRoutes.use(function(req, res, next) { var token = req.body.token || req.query.token || req.headers['x-access-token']; if(token) { jwt.verify(token, 'batman batman batman', function(err, decoded) { if (err) { return res.json({ success: false, message: 'Falha ao tentar autenticar o token!' }); } else { //se tudo correr bem, salver a requisição para o uso em outras rotas req.decoded = decoded; next(); } }); } else { // se não tiver o token, retornar o erro 403 return res.status(403).send({ success: false, message: '403 - Forbidden' }); } });
Nessa etapa nós estamos verificando se a requisição está com o token, caso não esteja enviando ele ou caso ele seja um token invalido nós retornamos o status 403, que é utilizado para passar que o usuário não tem permissão para realizar aquela requisição. Caso o token seja valido, nós retornamos o status 200 e uma mensagem no navegador.
Por fim, para que possamos validar um requisição com o token, nós precisamos realizar o mesmo procedimento acima para gerar um token e em seguida preencher o Postman conforme a imagem a baixo, assim conseguiremos ter acesso aos nossos métodos.
Com isso nós conseguimos abordar a teoria do JWT e entender o seu funcionamento através de um exemplo criado em uma linguagem de programação que vem sendo adotada por muitos programadores a cada dia que se passa.
Gostou deste artigo? Comente abaixo!
Referência: https://programadriano.medium.com/json-web-token-jwt-c469834849a8
Publicando projeto Docker + Node.js + TypeScript + MongoDB No Azure
Veja nessa artigo alguns links sobre como publicar o seu projeto Node.js, TypeScript e MongoDB com Docker e Docker Compose no Azure
O próximo passo será acessar a sua conta do Azure. Caso ainda não tenha uma, você pode criar através do seguinte link: Crie sua conta Azure Grátis.
Benefícios Visual Studio Dev Essentials
A seguir você tem o exemplo do arquivo Docker Compose que eu irei utilizar para publicar o meu projeto no Azure:
version: "3" services: api: image: tadrianonet/api-ts ports: - "80:3050" links: - link-db link-db: image: tutum/mongodb ports: - "27017:27017" - "28017:28017" environment: - AUTH=no
Deploy no Azure Web Apps for Containers
Testando aplicação na Nuvem
Bom galera, com isso liberamos mais um módulo sobre Docker do Curso “Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB”.
Espero que gostem e até um próximo artigo pessoal 😉
Referências: https://programadriano.medium.com/publicando-projeto-docker-node-js-typescript-mongodb-no-azure-608d8fa54246
Trabalhando com Docker + Node.js + TypeScript + MongoDB
Veja nessa artigo alguns links sobre como trabalhar com Docker e o Docker Compose em um projeto desenvolvido com Node.js, TypeScript e MongoDB
Abaixo vocês tem os links do módulo como trabalhar com Docker do meu Curso Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB
Criando uma imagem Docker
Subindo a API com o Docker compose
Publicando imagem no Docker hub
Baixando e testando a imagem do Docker Hub
Espero que tenham gostado e até um próximo artigo pessoal 🙂
Referência: https://medium.com/typescript/trabalhando-com-docker-node-js-typescript-mongodb-a341d42e1fc0
[TypeScript] no TDC São Paulo Online 2020
Na data do dia 26/08/2020 eu tive a oportunidade de palestrar no TDC são Paulo Online 2020.
Gostaria de agradecer ao Jackson Feijó, Adriano Rodrigues e à Talitha Barcellos que coordenaram as apresentações na Sala Microsoft pela oportunidade em participarmos como palestrantes nesta edição TDC.
A seguir vocês tem alguns links do material utilizado na minha apresentação:
Slides da minha apresentação:
Prints de tela retirado por amigos 😉
Curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, Redis e Docker no Azure – Parte 2
2-Parte: Configurando o ambiente de banco de dados com Docker
Dando continuidade a liberação dos módulos do meu curso: Criando API’s RESTful utilizando TypeScript, Node e mongoDB, hoje eu irei demonstrar como subir um ambiente Docker com o MongoDB e como acessar essa base de dados.
Caso você seja iniciante em Docker, eu recomendo a leitura do seguinte artigo: Comando básicos docker.
Artigo contendo um passo a passo de como configurar um ambiente MongoDB com Docker: Docker: Criando servidor MongoDB
Configurando ambiente de banco de dados MongoDB com Docker
Acessando a base de dados mongoDB
Link para download do Robo 3T: Download
Espero que gostem e qualquer dúvida podem postar aqui ou no vídeo do Youtube.
Gostou deste artigo? Comente abaixo!
Estrutura de Dados com Classes JavaScript
Olá pessoal! Neste artigo, demonstrarei as principais Estruturas de Dados utilizando JavaScript. Será uma postagem bem longa, por isso, prepare seu café e uma boa leitura!
FILA:
Filas são estruturas de dados onde o primeiro a entrar é o primeiro a sair. É chamado de FIFO (First In First Out). As operações em Fila são análogas ao que ocorre em filas reais, como a fila de um banco, por exemplo, com a exceção de que os elementos na fila não se movem, conforme o primeiro elemento é retirado. Na estrutura de dados Fila, o algoritmo indica quem está na primeira posição.
Utilizaremos as classes que foram implementadas no ECMAScript 2015 para criação de nossa fila. A nossa estrutura terá os seguintes métodos:
- Enqueue (inserção na fila);
- Dequeue (remoção da fila);
- MostrarTudo;
- VisualizarEm.
Para começar, precisamos criar uma classe chamada Fila, onde teremos o início da fila (head), fim da fila (tail) e um contador (count). Como a fila está vazia, o nosso head e nosso tail recebem o valor null, e nosso contador começa em 0. Precisamos também de um método Get para nosso contador:
class Fila { constructor(head = null, tail = null, count = 0){ this.head = head; this.tail = tail; this.count = count; } GetContador(){ return this.count; } }
Enqueue:
Para adicionarmos um item no início da nossa fila, precisamos criar um nó, que conterá o dado e uma referência à próxima posição da fila, que deverá ser null. Quando inserirmos nosso primeiro elemento, o início e o final da fila serão o mesmo elemento, e precisaremos incrementar o contador:
Enqueue(data){ let no = { data: data, next: this.head }; if (this.head === null){ this.tail = no; } this.head = no; this.count++; }
Dequeue:
Removeremos o primeiro elemento da fila e retornaremos o último item inserido e armazenado no final da fila. Fazendo isso, teremos que, enquanto houver um próximo elemento, avançaremos na fila. A ideia é ter um atual no final da fila e um anterior e, então, teremos que decrementar o contador:
Dequeue(){ if (this.count === 0){ return; } else { let current = this.head; let previous = null; while (current.next){ previous = current; current = current.next; } if (this.count > 1){ previous.next = null; this.tail = previous; } else { this.head = null; this.tail = null; } this.count--; } }
MostrarTudo:
O próprio nome já diz: mostraremos todos os elementos da fila. Utilizaremos um vetor para isso e, com um laço de repetição, iremos inserir cada valor em sua respectiva posição neste vetor. Também precisamos verificar se há elementos na fila:
MostrarTudo(){ if (this.head === null){ return null; } else { let arr = []; let current = this.head; for (let i = 0; i < this.count; i++) { arr[i] = current.data; current = current.next; } return arr; } }
VisualizarEm:
No método VisualizarEm, iremos procurar o elemento na nossa fila, buscando-o e exibindo-o. Utilizaremos um laço de repetição para percorrer nossa fila e encontrar o elemento que buscamos:
VisualizarEm(index){ if (index > -1 && index < this.count){ let current = this.head; for (let i = 0; i < index; i++) { current = current.next; } return current.data; } else { return null; } }
Agora, vamos testar:
let fila = new Fila(); fila.Enqueue(1); fila.Enqueue(2); fila.Enqueue(3); fila.Enqueue(4); fila.Enqueue(5); fila.Enqueue(6); fila.Dequeue(); fila.Dequeue(); console.log(fila.VisualizarEm(1)); console.log(fila.MostrarTudo()); console.log(fila);
E a nossa saída será:
PILHA:
A pilha é uma estrutura de dados que implementa o conceito de último a entrar, primeiro a sair (LIFO (Last in First Out)), ou seja, o último elemento adicionado será o primeiro elemento a ser removido. Utilizaremos também, na nossa estrutura de dados, a palavra-chave class, que foi introduzida no ECMAScript 2015. Mas isso não significa que JavaScript é uma linguagem orientada e objetos. O JavaScript continua sendo orientado a protótipos, ou seja, o prototype continua agindo “por baixo dos panos”, e a palavra-chave class apenas “mascara” toda essa prototipagem, tornando o código mais simples de ser lido.
Abaixo temos uma imagem do funcionamento da pilha:
Então, para começarmos a implementar a pilha, precisamos construir a nossa classe Pilha e seu construtor. Vamos implementar também um contador, que será útil para nos mostrar a quantidade de itens na pilha. No nosso construtor, precisamos setar nossos valores do contador e do topo da pilha. Como ainda não há nada na pilha, o topo é null e o contador é 0:
class Pilha { constructor(top = null, count = 0){ this.top = top; this.count = count; } GetContador(){ return this.count; } }
Nossa pilha terá os seguintes métodos:
- Push;
- Visualizar;
- Remover;
- MostrarTodos.
Push:
Para criar nosso método push, precisamos criar um nó. Cada nó precisa ter o dado e a referência para o próximo nó, que precisa ser null, pois cada vez que inserirmos algo na pilha, esse elemento inserido deverá ser o primeiro a ser removido. Então, cada nó inserido deve virar o topo da pilha.
Push(data){ let no = { data: data, next: null }; no.next = this.top; this.top = no; this.count++; }
Visualizar:
Para visualizarmos o item que está no topo da pilha, precisamos nos certificar de que a pilha não está vazia. Caso a pilha não estiver vazia, retornaremos o dado que está no topo de nossa estrutura:
Visualizar(){ if (this.top === null){ return null; } else { return this.top.data; } }
Remover:
Para remover o elemento do topo da pilha, precisamos entender que a pilha não poderá estar vazia. Caso ela não esteja vazia, removeremos o elemento do topo e diminuiremos o nosso contador em 1.
Remover(){ if (this.top === null){ return null; } else { let remover = this.top; this.top = this.top.next; if (this.count > 0){ this.count--; } return remover.data; } }
MostrarTodos:
Iremos adicionar os dados em um vetor, para então exibi-los. Precisamos ter certeza que nossa pilha não está vazia e, então, criamos um vetor, Utilizaremos um laço de repetição que irá inserir cada elemento de nossa pilha em sua respectiva posição:
MostrarTodos(){ if (this.top === null){ return null; } else { let arr = []; let current = this.top; for (let i = 0; i < this.count; i++){ arr[i] = current.data; current = current.next; } return arr; } }
E podemos testar a nossa estrutura de dados, instanciando uma nova pilha:
let pilha = new Pilha(); pilha.Push(1); pilha.Push(2); pilha.Push(3); pilha.Push(4); pilha.Push(5); pilha.Push(6); pilha.Push(7); pilha.Remover(); console.log(pilha.Visualizar()); console.log(pilha.MostrarTodos()); console.log(pilha);
E a saída será:
Curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, Redis e Docker no Azure Parte 1
Para aqueles que colocaram como meta aprender algo novo na area de programação em 2020, eu estou disponibilizando alguns módulos do meu curso: Criando API’s RESTful utilizando TypeScript, Node e mongoDB.
Segue abaixo as primeiras video aulas liberadas 🙂
Introdução ao curso:
Ambiente de desenvolvimento:
Instalação do Node.js
Instalação do TypeScript
Aproveitando, segue link para download das ferramentas que nós iremos utilizar nesse curso abaixo:
- Instalação do Node.js
- Instalação do TypeScript
- Instalação do Docker
- Instalação do VS Code (Visual Studio Code)
Espero que gostem 🙂
Você sabe o que significa NPM?
O NPM, ou Node Package Manager, é um repositório online com a finalidade de publicação de projetos NodeJS de código aberto. Podemos utilizar o npm como um utilitário de linhas de comando, interagindo com os repositórios e instalando os seus pacotes. Isso auxilia diretamente na instalação, controle de gerenciamento de versão e dependências dos projetos. Existem muitos aplicativos e bibliotecas publicados no npm, com novidades sendo adicionadas todos os dias. Você pode pesquisar essas bibliotecas e dependências em: https://npmjs.org.
Para instalar uma biblioteca, você só precisará executar o comando:
npm install nome_do_pacote
Assim que estiver instalado, você pode verificar a existência da biblioteca ou dependência na pasta node_modules e você usa o comando require() para adicioná-lo à sua página.
Para adicionar algo globalmente, você pode adicionar o comando -g à sintaxe. Isso instalará o programa em um local, e adicionará um link a ele, permitindo a utilização do programa no console, como qualquer outra ferramenta CLI.
Como um gerenciador de dependências, você possuirá um arquivo package.json no seu projeto nodejs. Executando o comando:
npm install
Utilizando esse comando na pasta raiz do seu projeto, assim o npm instalará todas as dependências que são listadas no arquivo package.json. Depois de executar este comando, você pode verificar na pasta node_modules que todas as dependências que são especificadas no package.json estarão instaladas.
home
Com o comando home, você pode abrir o site da biblioteca que você está tentando instalar. O site será aberto no seu navegador padrão. Por exemplo, utilizaremos o React Native como exemplo:
npm home react-native
Após executar este comando, a página de documentação do React Native no GitHub será aberta!
init
O comando init nos permite iniciar um arquivo package.json. Na criação deste arquivo, são feitas diversas perguntas. Mas você também pode pular todo o questionário adicionando um -y ao comando!
npm init -y
Lista de pacotes
Podemos verificar a lista de pacotes instalados no nosso projeto utilizando o comando:
npm ls --depth 0
E também podemos verificar quais são as bibliotecas ou dependências instaladas globalmente na nossa máquina utilizando o comando:
npm ls -g --depth 0
Gostou deste artigo? Comente abaixo e compartilhe com os seus amigos!
Referências:
- https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/
- https://www.npmjs.com/?_ga=2.124867018.1555257413.1602678251-469908954.1602678251
- https://www.treinaweb.com.br/blog/10-truques-do-npm-voce-conhece-todos/
Referências: https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/