Yarn Plug'n'Play, TypeScript e webpack

Eliminando node_modules de maneira eficaz e com tipagem!

Image for post
Image for post
Sem `node_modules`, com tipagem e empacotando tudo! 🎉

Plug'n'Play é uma nova iniciativa da equipe do Yarn que remove a necessidade de ter uma pasta node_modules por projeto e, ao invés disso, utiliza a pasta de cache criada pelo yarn na sua máquina.

Por exemplo, no macOS você pode encontrar essa pasta em:

$ ls ~/Library/Caches/Yarn/<version>// pacotes já cacheados/"warm" na minha máquinanpm-react-16.6.0-b34761cfaf3e30f5508bc732fb4736730b7da246
npm-react-dom-16.6.0-6375b8391e019a632a89a0988bce85f0cc87a92f
npm-readable-stream-2.3.6-b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf
...

Algumas das vantagens desse tipo de instalação é:

Se você quiser saber mais detalhes da implementação, existem 3 documentos que posso recomendar:

A última versão estável do yarn@1.12.1 , já inclui essa funcionalidade por padrão, a questão agora é, como utilizá-la?

Iniciando com Plug'n'Play

Para ilustrar a funcionalidade, vamos criar um projeto de exemplo:

$ mkdir yarn-pnp-ts
$ cd yarn-pnp-ts
$ touch package.json

E atualizar o package.json para:

{
"installConfig": {
"pnp": true
}
}

E… é isso aí! 😅🤯🎉

A partir de agora, todos os pacotes que você adicionar nesse projeto, Yarn irá usar seu próprio algorítimo de resolução de depêndencias e irá utilizar os pacotes já instalados na pasta cache da sua máquina. Deixando suas instalações mais rápidas e ainda podendo reutilizar o que já foi instalado por outros projetos.

Porém, parando para pensar um pouco, temos um problema aqui. Se estamos mudando o local de resolução das nossas depêndencias (não é mais node_modules), como fica a integração com ferramentas do nosso ecossistema?

Resolvendo Plug'n'Play em webpack e TypeScript

Apesar da mudança, a equipe do Yarn já se preparou para introduzir o mínimo de problemas possível. O idealizador da funcionalidade Plug'n'Play, Maël Nison, já disponibilizou ferramentas de integração para o Rollup, Jest e webpack.

Sabendo disso, podemos começar a aplicar nossa configuração do webpack e também do TypeScript:

$ yarn add webpack webpack-cli typescript
$ yarn add pnp-webpack-plugin ts-loader

Listando os arquivos nessa paste, teremos:

/ yarn-pnp-ts
| .pnp
| .pnp.js
| package.json
| yarn.lock

O arquivo .pnp.js é o algorítimo de resolução (module resolver) criado pelo Yarn (ou seja, a implementação do Plug'n'Play) junto com a tabela de resolução estática (static resolution tables) que lista 3 coisas:

A pasta .pnp/ é gerada para pacotes que usam link simbólico (symlink) ou debug. Para saber mais detalhes sobre essa paste, recomendo dar uma olhada no PDF da tese.

Vamos criar nosso webpack.config.js :

$ touch webpack.config.js

E adicionar:

const PnpWebpackPlugin = require(`pnp-webpack-plugin`);module.exports = {
mode: process.env.NODE_ENV || "development",
entry: ['./src/entry.tsx'],
output: {
path: `${__dirname}/public/dist`
},
module: {
rules: [{
test: /\.tsx?$/,
loader: require.resolve('ts-loader'),
options: PnpWebpackPlugin.tsLoaderOptions(), // [A]
}],
},
resolve: {
plugins: [
PnpWebpackPlugin, // [B]
],
},
resolveLoader: {
plugins: [
PnpWebpackPlugin.moduleLoader(module), // [C]
],
},
};

Aqui temos uma configuração bem familiar do webpack onde:

Agora, como listado em nossa chave entry, vamos criar nosso arquivo src/entry.tsx :

$ mkdir src/
$ touch src/entry.tsx

E adicionar:

import * as React from "react";
import * as ReactDOM from "react-dom";
function App() {
return <h1>Hello World!</h1>;
}
function main(
component: React.ReactElement<{}>,
container: HTMLElement | null
) {
if (container) {
ReactDOM.render(component, container);
}
}
main(<App />, document.getElementById("root"));

Vamos adicionar nossas depêndencias e tipos:

$ yarn add react react-dom
$ yarn add @types/react @types/react-dom

Como estamos utilizando TypeScript, precisamos do nosso tsconfig.json :

$ yarn tsc --init

E atualizá-lo para:

{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"jsx": "react",
"strict": true
}
}

E ao executar o webpack:

$ yarn webpack

Teremos:

Image for post
Image for post

Hip Hip… Hooray!!1 🎉🎉

Finalizando

Acabamos de integrar 3 ferramentas essenciais no nosso dia a dia:

A integração do Plug'n'Play com o restante das ferramentas de desenvolvimento ainda está avançando (principalmente editores de código como VSCode, Atom, etc), porém, já é possível utilizá-lo hoje em dia e aumentar a precisão e velocidade de instalação do seu fluxo de trabalho.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store