Frameworks
JavaScript estão sempre mudando, e geralmente são mudanças complexas que nos
obrigam a reaprender como fazemos as coisas. Não foi diferente com a questão da
criação de bibliotecas do Angular, que até a versão 5 era apenas um projeto
comum, o qual empacotávamos no formato NPM e publicávamos. Agora, a partir da
versão 7 em diante o Angular cria uma espécie de workspace, onde é possível
criar vários projetos e bibliotecas, e são essas bibliotecas internas que podemos
exportar e podemos usar em outros projetos, e até publicar no NPM.
Com
isso, muita coisa mudou, porque essa biblioteca interna, (pelo menos por
enquanto, até a versão 7.1.2 do Angular), não contém os arquivos environments.prod.ts e environments.ts para tratarmos a
diferença entre algumas configurações de produção e o ambiente de
desenvolvimento, também não existe a estrutura da pasta assets para colocarmos nossas imagens e o Angular conseguir encontrá-las
de forma fácil.
Essas
dificuldades eu contornei da seguinte forma: as imagens eu coloco em texto
base64 direto na tag <img> e quando preciso pegar uma URL em uma
biblioteca uso JavaScript para obter a URL de forma dinâmica: (window.location.protocol
+ window.location.hostname;).
Outra
mudança que houve foi o arquivo angular-cli.json
que teve seu nome alterado para angular.json
e sua estrutura mudou um pouco, passando a conter múltiplos projetos (como o de
testes e as bibliotecas) pois como
disse, o que criamos com “ng new” a partir da versão 7 do Angular se comporta
como um workspace.
Agora
que já falamos das mudanças e alguns contratempos que tive com elas, vamos a
criação do projeto. Abrindo no terminal a pasta do seu workspace, digite:
$ ng
new teste --create-application=false
Quando indagado sobre a criação do Router
e do CSS escolha as opções padrão.
A opção
--create-aplication usada acima
também é nova, e faz com que o Angular não crie o projeto inicial, bem com a
pasta src, criando apenas o Workspace
Angular por assim dizer. Basicamente isso é útil para criarmos bibliotecas,
pois gera um workspace de mesmo nome da biblioteca. Note que o Angular aceita tanto comandos com camelCase
quanto separados por ífem (-), então poderia ser --createApplication=false.
Aproveite e dê uma olhada nos arquivos
package.json que continua com as
dependências do projeto e angular.json, que está praticamente
vazio aguardando a criação de um projeto ou biblioteca.
Vamos criar a biblioteca, posicione o
terminal na nova pasta criada (teste):
$ cd
..
E crie
a biblioteca com o seguinte comando:
$ ng
g library teste --prefix=lib
Na linha acima, foi criada a
biblioteca “teste” e ao invés de
usarmos o prefixo “app” como de
costume, dissemos para o Angular usar o prefixo “lib”. Fique à vontade para escolher o prefixo que desejar, isso é
importante para evitar conflitos entre a biblioteca e os apps que a usam.
Note que o conteúdo do arquivo angular.json mudou, temos nele a
propriedade que indica a versão do projeto: “version”, a propriedade que indica o pacote raiz que contém os
projetos: “newProjectRoot”, e então
temos a propriedade que indica os nossos projetos: “projects”. Dentro da propriedade “projects” há uma propriedade para cada projeto que criarmos, nesse
caso haverá apenas o projeto “teste”,
e dentro da propriedade “teste” teremos
as propriedades de configuração deste projeto específico, como o tipo do projeto, o prefixo usado, a raiz do
projeto, o source do projeto e
outras configurações pertinentes.
A
estrutura do projeto também foi alterada, agora existe uma pasta “projects” com a pasta “teste” que é o nosso projeto dentro
dela; e dentro da pasta “teste”
temos o diretório “src” que conterá tudo que pertencer a lib propriamente
dita, o arquivo “package.json” da lib que especificará suas
dependências que serão compiladas e posteriormente instaladas junto com ela
quando um cliente usar npm install e
também o arquivo ng-package.json. Os
demais arquivos são de menor importância. É também no arquivo “package.json” da lib que especificamos
o autor, a licença, o repositório, etc.
A lib já foi criada contendo um
componente e um service dentro de src/lib
. Também vemos outro arquivo importante dentro da pasta src: public_api.ts. Nesse arquivo devemos exportar
todos os módulos, componentes e services que criarmos, para que possam ser
usados por quem instalar nossa biblioteca.
export * from './lib/teste.service';
export * from './lib/teste.component';
export * from './lib/teste.module';
No
diretório principal, o arquivo “tsconfig.json”
tem as configurações de transpilação e build do projeto. Ele recebe o path
da biblioteca que criamos para podermos usar nesse projeto, enquanto que em
projetos externos ela será instalada com npm
install e o conteúdo ficará em node_modules.
"paths": {
"teste": [
"dist/teste"
],
"teste/*": [
"dist/teste/*"
]
}
Vamos buildar o projeto:
$ ng
build teste
Veja que o projeto é buildado
normalmente. Mas a frente vamos ver como usá-lo em outro projeto e também como
publicar no npm. Agora vamos ver como criar novos componentes para a
biblioteca. Digite o comando abaixo:
$ ng
g c meu-componente --project=teste
Veja
que a única coisa que
mudou foi que especificamos em qual projeto o componente seria gerado pelo
AngularCli. O novo componente deve ser declarado no módulo da nossa
biblioteca e também no arquivo de entrada, o public_api.ts.
Com
isso podemos re-buildar nossa aplicação. Uma novidade desde a versão 6.2 é o
re-build pode ser automático a medida que arquivos forem alterados, para isso
basta acrescentar a opção --watch no momento do build, a partir de então os
demais serão disparados sozinhos.
$ ng
build teste --watch
Agora
vamos ver como usar a biblioteca em um
projeto externo e como publicar no npm.
Para isso
temos que empacotar nossa biblioteca em uma arquivo .tgz, por tanto, vamos criar um script no “package.json” raiz para facilitar este trabalho. Na seção “scripts” adicione o seguinte trecho de
código:
"scripts": {
...
"npm_pack_teste": "cd dist/teste && npm
pack"
}
Agora
podemos usar o seguinte comando para empacotar a biblioteca “teste”:
$ npm
run npm_pack_teste
Isto
criou o arquivo “teste-0.0.1.tgz” dentro
de “dist/teste” com a versão
especificada no arquivo “package.json” da
lib como já dito anteriormente. Podemos inclusive criar um script que faz o build
e o empacotamento de uma só vez:
"scripts": {
...
"npm_pack_teste": "cd dist/teste && npm
pack",
"package_teste":
"ng build teste && npm run npm_pack_teste "
}
E agora
basta executar:
$ npm
run package_teste
Pronto,
temos nossa biblioteca buildada e empacotada para usarmos onde quisermos! Para usarmos em projetos próprios não
precisamos publicar no npm. Isso é bom para empresas que não querem expor suas bibliotecas, pode-se
criar um repositório interno para elas e quando for usar o npm install basta passar
o caminho completo de onde a biblioteca está.
Uma vez
instalada a biblioteca, o uso é normal como qualquer pacote npm instalado na aplicação.
Agora vamos a publicação no npm. Antes
de criar uma biblioteca, se é sua intenção publicá-la no npm é bom checar se o
nome que pretende dar a sua biblioteca já não existe lá, para evitar ter que
mudar depois de criado todo o projeto.
O
arquivo “package.json” deve estar com
as informações de nome, versão, autor, licença, repositório, palavras chaves e
outras além das dependências, scripts, etc... como abaixo:
...
"name": "teste",
"version": "1.0.0",
"license": "MIT",
"author": {
"name": "seu_nome",
"email":
"seu_email",
"url": "seu_site_ou_blog"
},
"bugs": {
"url":"url_issues_git"
},
"homepage":"url_git",
"keywords": [
"angular",
"angular2",
"angular4",
"p-calendar",
"p-calendar-ptbr",
"primeNG",
"datepicker",
"calendar",
"pt-BR"
],
"repository": {
"type":
"git",
"url":
"git+https://endereço_rep_git"
},
...
O npm
usará sua página de README.md com a página inicial da sua biblioteca no
servidor. Como agora estamos tratando de mais de uma biblioteca por
workspace, o README.md deve ser copiado para o destino onde a biblioteca é
buildada. Caso haja um arquivo LICENSE também deve ser colocado lá.
É preciso
criar uma conta caso você não tenha, ou fazer login para poder compartilhar
seus pacotes. A criação da conta é bem simples e eles pedem um username,
password e e-mail. É necessário a confirmação do e-mail antes de publicar algo
caso a conta seja nova. O comando para criar uma conta é:
$
npm adduser
Ao
criar a conta ele já loga no NPM. Para efetuar logins posteriores, os mesmos
dados são pedidos, e o comando é:
$
npm login
Agora
podemos publicar nossa biblioteca, digitando o comando npm publish e passando o
caminho do arquivo .tgz gerado:
$ npm
publish .\dist\teste\teste-0.0.1.tgz
Bom, o
artigo ficou um pouco grande porque expliquei algumas coisas com detalhes, mas
espero ter ajudado! Abraços!
Links
de referência: