{"id":1851,"date":"2017-06-21T15:11:52","date_gmt":"2017-06-21T18:11:52","guid":{"rendered":"http:\/\/www.milfont.org\/tech\/2017\/06\/21\/transformando-seu-codigo-de-negocio-em-biblioteca-versionada\/"},"modified":"2017-06-21T15:11:52","modified_gmt":"2017-06-21T18:11:52","slug":"transformando-seu-codigo-de-negocio-em-biblioteca-versionada","status":"publish","type":"post","link":"https:\/\/www.milfont.org\/tech\/2017\/06\/21\/transformando-seu-codigo-de-negocio-em-biblioteca-versionada\/","title":{"rendered":"Transformando seu c\u00f3digo de neg\u00f3cio em biblioteca versionada"},"content":{"rendered":"<p>Um problema comum no Frontend \u00e9 o gerenciamento e organiza\u00e7\u00e3o do c\u00f3digo e as <a href=\"https:\/\/medium.com\/@milfont\/os-m%C3%BAsculos-do-javascript-be2b721851b7\" target=\"_blank\" rel=\"noopener noreferrer\">\u00faltimas tecnologias nos \u00faltimos anos<\/a> nos ajudam a resolver.<\/p>\n<h3>Caso<\/h3>\n<p><a href=\"https:\/\/beerswarm.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Tenho um c\u00f3digo que depende de mapas<\/a> em v\u00e1rias telas do sistema e organizei um componente que pode ser importado em v\u00e1rios arquivos.<\/p>\n<p>Como esse componente tem um ciclo de desenvolvimento diferente, organizei como subm\u00f3dulo no git.<\/p>\n<figure>\n<p><img decoding=\"async\" data-width=\"1035\" data-height=\"839\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*bKlyPigAFLZ_6JN1JRcdmw.png\"><br \/>\n<\/figure>\n<p>Para facilitar, os devs importam o projeto principal com par\u00e2metro pra j\u00e1 carregar os subm\u00f3dulos, mas no final de contas fica tudo num mesmo lugar.<\/p>\n<pre><code>git clone --recursive -j8 git@github.com:cmilfont\/beerswarm.git<\/code><\/pre>\n<h3>Problema<\/h3>\n<p>O c\u00f3digo est\u00e1 blindado para importar as depend\u00eancias sem se preocupar com estrutura e organiza\u00e7\u00e3o, j\u00e1 que nos foi dada com a nova abstra\u00e7\u00e3o na linguagem\u200a\u2014\u200a<strong>transpilada<\/strong> pelo <a href=\"https:\/\/medium.com\/@milfont\/usaremos-babel-pra-sempre-f827604762fb\" target=\"_blank\" rel=\"noopener noreferrer\">Babeljs<\/a>\u200a\u2014\u200apara funcionar em todos os navegadores, algo como:<\/p>\n<pre>import { BMap, Toolbar, GoogleMutant, GoogleApiLoader } from '\/components\/maps';<\/pre>\n<p>O problema mesmo \u00e9 no ciclo de vers\u00e3o desses componentes. Se um desenvolvedor move um m\u00e9todo de lugar e o projeto n\u00e3o tem 100% de cobertura em testes (se tratando de legado \u00e9 o normal e esperado) corre o risco prov\u00e1vel de detectar apenas em produ\u00e7\u00e3o.<\/p>\n<p>Problema dobrado, uso o <a href=\"http:\/\/leafletjs.com\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Leaflet<\/a> como gerenciador de mapas, cada fornecedor representa uma camada (layer) a ser exibido, o default \u00e9 o <a href=\"http:\/\/www.openstreetmap.org\/#map=5\/51.500\/-0.100\" target=\"_blank\" rel=\"noopener noreferrer\">Open Street Maps<\/a>.<\/p>\n<p>Para usar o mapa do Google teria que implementar uma layer e carregar a API, causou o problema com outra tela que precisava al\u00e9m do Mapa tamb\u00e9m carregar a biblioteca de <strong>places<\/strong> que faz parte dos opcionais. Da\u00ed nasce o subm\u00f3dulo do subm\u00f3dulo pra gerenciar.<\/p>\n<p>Problemas secund\u00e1rios que tamb\u00e9m tomam tempo da equipe: merges desmotivantes.<\/p>\n<h3>Solu\u00e7\u00e3o<\/h3>\n<p><a href=\"https:\/\/hackernoon.com\/building-a-react-component-library-part-1-d8a1e248fe6c\" target=\"_blank\" rel=\"noopener noreferrer\">Transformar esses c\u00f3digos gen\u00e9ricos em bibliotecas<\/a> com seu pr\u00f3prio ciclo de versionamento usando o pr\u00f3prio gerenciador de pacotes do Nodejs, <a href=\"https:\/\/www.npmjs.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">o npm<\/a>, como fazem as bibliotecas OpenSource da linguagem.<\/p>\n<h4>Hospedando o projeto da\u00a0lib<\/h4>\n<p>Come\u00e7amos por isolar a Layer do Google a ser usada no Leaflet como uma lib.<\/p>\n<p>Usando o <strong>create-react-app<\/strong> (troque pelo seu boilerplate preferido) eu criei um projeto novo <a href=\"https:\/\/github.com\/produtoreativo\/react-leaflet-googlemutant\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/produtoreativo\/react-leaflet-googlemutant<\/a>, adicionei repositorio no github.<\/p>\n<p><strong>Formato 1: Open Source<\/strong><\/p>\n<p>Se n\u00e3o tem diferencial pro meu neg\u00f3cio (como uma Layer para o mapa do Google) o melhor \u00e9 deixar o mundo ajudar a manter, <a href=\"https:\/\/docs.npmjs.com\/getting-started\/publishing-npm-packages\" target=\"_blank\" rel=\"noopener noreferrer\">reservando um reposit\u00f3rio no npmjs.com<\/a>.<\/p>\n<p><strong>Formato 2: Privado no npmjs.com<\/strong><\/p>\n<p>O registro global de libs no nodejs tem planos pagos para <a href=\"https:\/\/www.npmjs.com\/pricing\" target=\"_blank\" rel=\"noopener noreferrer\">libs privadas<\/a>, tem tamb\u00e9m que colocar <strong>private: true<\/strong> no <strong>package.json<\/strong> do projeto. Conveniente por ser a mesma coisa do OpenSource, mas talvez um pre\u00e7o salgado dependendo do tamanho da sua companhia.<\/p>\n<p><strong>Formato 3: Privado e hospedado in-house.<\/strong><\/p>\n<p>Caso queira hospedar seu pr\u00f3prio reposit\u00f3rio de bibliotecas, pode usar uma op\u00e7\u00e3o como o <a href=\"http:\/\/www.sonatype.org\/nexus\/\" target=\"_blank\" rel=\"noopener noreferrer\">Nexus<\/a> e apontar no package.json o caminho como a <a href=\"https:\/\/books.sonatype.com\/nexus-book\/reference\/npm-deploying-packages.html\" target=\"_blank\" rel=\"noopener noreferrer\">pr\u00f3pria documenta\u00e7\u00e3o da ferramenta ensina<\/a>.<\/p>\n<p><strong>Formato 4: Privado sem gerenciador de reposit\u00f3rios de libs<\/strong><\/p>\n<p>Caso ainda n\u00e3o queira configurar um servidor privado ou pagar o registro p\u00fablico global, pode tamb\u00e9m indicar no package.json o caminho ao github diretamente, algo como:<\/p>\n<pre>{<br \/>  \"name\": \"beerswarm\",<br \/>  \"version\": \"0.1.0\",<br \/><strong>\"private\": true,<\/strong><br \/>  \"dependencies\": {<br \/>    \/* libs ... *\/<br \/>    \"react-leaflet-googlemutant\": \"<strong>github:produtoreativo\/react-leaflet-googlemutant<\/strong>\",<br \/>  },<br \/>  \"devDependencies\": {<br \/>    \"react-scripts\": \"0.9.5\",<br \/>  },<br \/>  \"scripts\": {<br \/>    \"start\": \"NODE_PATH=src react-scripts start\",<br \/>    \"build\": \"NODE_PATH=src react-scripts build &amp;&amp; sw-precache --config=sw-precache-config.js\",<br \/>    \"test\": \"NODE_PATH=src react-scripts test --env=jsdom --coverage\",<br \/>    \"eject\": \"react-scripts eject\"<br \/>  }<br \/>}<\/pre>\n<p>Os devs que tiveram em uma m\u00e1quina com permiss\u00e3o para puxar desse reposit\u00f3rio no seu fornecedor git bastar\u00e3o executar o <strong>npm install (<\/strong>ou <strong>yarn install)<\/strong> para ter as libs no projeto principal como depend\u00eancia.<\/p>\n<p>Lembrando que esse \u00faltimo caso de apontar diretamente para o github (ou gitlab) s\u00f3 funciona\u200a\u2014\u200a<a href=\"https:\/\/docs.npmjs.com\/files\/package.json#git-urls-as-dependencies\" target=\"_blank\" rel=\"noopener noreferrer\">como demonstra a pr\u00f3pria documenta\u00e7\u00e3o<\/a>\u200a\u2014\u200ainformando qual commit ou branch no final da url com o pattern <strong>#commit-ish.<\/strong><\/p>\n<p>A vers\u00e3o informada no package.json fica s\u00f3 simb\u00f3lica nesse caso e n\u00e3o define que vers\u00e3o real foi puxada.<\/p>\n<h4>Estrutura da\u00a0Lib<\/h4>\n<figure>\n<p><img decoding=\"async\" data-width=\"474\" data-height=\"593\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*c5sBD4bKqNtKedGrub-Anw.png\"><br \/>\n<\/figure>\n<p>Com o seu boilerplate preferido\u200a\u2014\u200ano meu caso o create-react-app\u200a\u2014\u200acrie a estrutura do seu projeto e reserve uma pasta (sugest\u00e3o, chamei de lib) para o resultado final que ser\u00e1 empacotado.<\/p>\n<p>Basicamente precisamos configurar adequadamente o package.json e usar um Module Bundler (construtor que vai transformar seu c\u00f3digo em um projeto execut\u00e1vel no navegador) como <a href=\"http:\/\/webpack.github.io\/\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Webpack<\/strong><\/a>.<\/p>\n<p>Quero transformar o import em algo como:<\/p>\n<pre>import { GoogleMutant, GoogleApiLoader } from 'react-leaflet-googlemutant';<\/pre>\n<h4>Configurando o package.json<\/h4>\n<p>Duas coisas importantes a configurar logo de in\u00edcio, o n\u00famero de vers\u00e3o da lib e de forma recomend\u00e1vel o script que vai ser carregado quando essa lib for importada.<\/p>\n<pre>{<br \/>  \"name\": \"react-leaflet-googlemutant\",<br \/>  \"description\": \"React leaflet wrapper to GoogleMutant plugin\",<br \/>  \"version\": \"0.1.6\",<br \/>  \"main\": \".\/lib\/react-leaflet-googlemutant.js\",<br \/>  \"private\": false<br \/>}<\/pre>\n<p>Ou seja, quando o usu\u00e1rio faz um <strong>import from &#8216;lib&#8217;. <\/strong>Essa Lib vai ser carregada no que voc\u00ea informar em main.<\/p>\n<p>Utilizei a lib <a href=\"https:\/\/github.com\/conventional-changelog\/standard-version\" target=\"_blank\" rel=\"noopener noreferrer\">standard-version<\/a> para <a href=\"https:\/\/github.com\/conventional-changelog\/standard-version\" target=\"_blank\" rel=\"noopener noreferrer\">g<\/a>erenciar as mudan\u00e7as do n\u00famero de vers\u00e3o de forma autom\u00e1tica.<\/p>\n<p>Outro fator importante de configura\u00e7\u00e3o \u00e9 definir o que vai ficar em <a href=\"https:\/\/stackoverflow.com\/questions\/18875674\/whats-the-difference-between-dependencies-devdependencies-and-peerdependencies\" target=\"_blank\" rel=\"noopener noreferrer\">dependencies, devDependencies ou peerDependencies<\/a>. Lembrando que para o arquivo final que ser\u00e1 importando num projeto Frontend voc\u00ea pode fazer o ajuste tranquilamente no Webpack.<\/p>\n<p><strong>Configurando o Webpack<\/strong><\/p>\n<p>Al\u00e9m de instalar com <strong>yarn add -D webpack<\/strong>, criei um arquivo <strong>webpack.conf.js<\/strong> na raiz da pasta para iniciar a configura\u00e7\u00e3o.<\/p>\n<p>Para importar as classes que est\u00e3o no caminho <strong>src\/components\/<\/strong> eu criei um index.js que exporta todas as interfaces p\u00fablicas dessa lib.<\/p>\n<pre>export { default as GoogleApiLoader} from 'components\/googleapiloader.js';<br \/>export { default as GoogleMutant } from 'components\/googlemutant.js';<\/pre>\n<p>Ou seja, voc\u00ea pode importar a Lib inteira como<\/p>\n<pre>import ReactLeafletGoogleMutant from 'react-leaflet-googlemutant';<\/pre>\n<p>ou as duas classes exportadas como no c\u00f3digo mostrado anteriormente:<\/p>\n<pre>import { GoogleMutant, GoogleApiLoader } from 'react-leaflet-googlemutant';<\/pre>\n<p>Esse arquivo de export vai ser nosso Entry Point. A ponte de entrada para todos os componentes da lib.<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/><strong>entry: \".\/src\/react-leaflet-googlemutant\/index.js\"<\/strong><br \/>};<\/pre>\n<p>Definimos as refer\u00eancias din\u00e2micas para os locais que o c\u00f3digo deve encontrar as fontes j\u00e1 que estamos usando caminhos absolutos a partir de um source (src).<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/>  entry: \".\/src\/react-leaflet-googlemutant\/index.js\",<br \/><strong>  resolve: {<br \/>    modules: [path.resolve(__dirname, \"src\"), \"node_modules\"]<br \/>  }<\/strong><br \/>};<\/pre>\n<p>Em seguida definimos qual vai ser aquela sa\u00edda que os projetos importar\u00e3o:<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/>  entry: \".\/src\/react-leaflet-googlemutant\/index.js\",<br \/>  resolve: {<br \/>    modules: [path.resolve(__dirname, \"src\"), \"node_modules\"]<br \/>  },<br \/><strong>  output: {<br \/>    path: path.join(__dirname, 'lib'),<br \/>    filename: \"react-leaflet-googlemutant.js\",<br \/>    library: \"ReactLeafletGoogleMutant\",<br \/>    libraryTarget: \"amd\"<br \/>  }<\/strong><br \/>};<\/pre>\n<p>Escolhi o formato <strong>amd<\/strong> como <a href=\"https:\/\/webpack.js.org\/configuration\/output\/#output-librarytarget\" target=\"_blank\" rel=\"noopener noreferrer\">padr\u00e3o da biblioteca gerada<\/a> por ser um dos mais comuns que funciona para todos os ambientes, seja web ou node, o que facilita testes e integra\u00e7\u00f5es.<\/p>\n<p>Um fator importante \u00e9 definir as depend\u00eancias e n\u00e3o levar junto no build gerado, exemplo, esse projeto de lib assume que o React e o Leaflet vai existir para ele funcionar, n\u00e3o faz sentido empacotar j\u00e1 que os projetos j\u00e1 o far\u00e3o, voc\u00ea pode definir o que \u00e9 externo:<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/>  entry: \".\/src\/react-leaflet-googlemutant\/index.js\",<br \/>  resolve: {<br \/>    modules: [path.resolve(__dirname, \"src\"), \"node_modules\"]<br \/>  },<br \/>  output: {<br \/>    path: path.join(__dirname, 'lib'),<br \/>    filename: \"react-leaflet-googlemutant.js\",<br \/>    library: \"ReactLeafletGoogleMutant\",<br \/>    libraryTarget: \"amd\"<br \/>  },<br \/><strong>  externals: {<br \/>    react: {<br \/>        root: 'React',<br \/>        amd: 'react'<br \/>    },<br \/>    'react-dom': {<br \/>        root: 'ReactDOM',<br \/>        amd: 'react-dom'<br \/>    },<br \/>    'prop-types': {<br \/>      root: 'PropTypes',<br \/>      amd: 'prop-types'<br \/>    },<br \/>    'react-leaflet': {<br \/>      amd: 'react-leaflet'<br \/>    },<br \/>    'leaflet': {<br \/>      amd: 'leaflet'<br \/>    }<br \/>  }<\/strong><br \/>};<\/pre>\n<p><a href=\"https:\/\/webpack.github.io\/docs\/configuration.html#devtool\" target=\"_blank\" rel=\"noopener noreferrer\">Existem v\u00e1rias prefer\u00eancias sobre qual formato de <strong>source map<\/strong><\/a> (aqui definido pela propriedade <strong>devtool<\/strong>), adotei qualquer uma porque essa lib \u00e9 intermedi\u00e1ria e n\u00e3o componente final a ser aplicado em projeto:<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/>  entry: \".\/src\/react-leaflet-googlemutant\/index.js\",<br \/>  resolve: {<br \/>    modules: [path.resolve(__dirname, \"src\"), \"node_modules\"]<br \/>  },<br \/>  output: {<br \/>    path: path.join(__dirname, 'lib'),<br \/>    filename: \"react-leaflet-googlemutant.js\",<br \/>    library: \"ReactLeafletGoogleMutant\",<br \/>    libraryTarget: \"amd\"<br \/>  },<br \/>  externals: {<br \/>    react: {<br \/>        root: 'React',<br \/>        amd: 'react'<br \/>    },<br \/>    'react-dom': {<br \/>        root: 'ReactDOM',<br \/>        amd: 'react-dom'<br \/>    },<br \/>    'prop-types': {<br \/>      root: 'PropTypes',<br \/>      amd: 'prop-types'<br \/>    },<br \/>    'react-leaflet': {<br \/>      amd: 'react-leaflet'<br \/>    },<br \/>    'leaflet': {<br \/>      amd: 'leaflet'<br \/>    }<br \/>  },<br \/><strong>devtool: 'sourcemap'<\/strong><br \/>};<\/pre>\n<p>Por fim configurei um plugin para aplicar vari\u00e1veis de ambiente (vou colocar o Version Number da lib dentro do c\u00f3digo) e o babel configurado para stage 2 e praticamente traduzindo apenas ES7, j\u00e1 que espero n\u00e3o usar diretamente no navegador e sim j\u00e1 inclu\u00eddo na tradu\u00e7\u00e3o de outra lib\/projeto. <a href=\"https:\/\/medium.com\/@milfont\/transpilando-com-babel-44d2517dd909\" target=\"_blank\" rel=\"noopener noreferrer\">Ler mais sobre configura\u00e7\u00e3o do <strong>Babel<\/strong> nesse artigo<\/a>.<\/p>\n<pre>var path = require('path');<br \/>var webpack = require('webpack');<br \/><br \/>module.exports = {<br \/>  entry: \".\/src\/react-leaflet-googlemutant\/index.js\",<br \/>  resolve: {<br \/>    modules: [path.resolve(__dirname, \"src\"), \"node_modules\"]<br \/>  },<br \/>  output: {<br \/>    path: path.join(__dirname, 'lib'),<br \/>    filename: \"react-leaflet-googlemutant.js\",<br \/>    library: \"ReactLeafletGoogleMutant\",<br \/>    libraryTarget: \"amd\"<br \/>  },<br \/>  externals: {<br \/>    react: {<br \/>        root: 'React',<br \/>        amd: 'react'<br \/>    },<br \/>    'react-dom': {<br \/>        root: 'ReactDOM',<br \/>        amd: 'react-dom'<br \/>    },<br \/>    'prop-types': {<br \/>      root: 'PropTypes',<br \/>      amd: 'prop-types'<br \/>    },<br \/>    'react-leaflet': {<br \/>      amd: 'react-leaflet'<br \/>    },<br \/>    'leaflet': {<br \/>      amd: 'leaflet'<br \/>    }<br \/>  },<br \/>  devtool: 'sourcemap',<br \/><strong>  plugins: [<br \/>    new webpack.EnvironmentPlugin(['__VERSION__'])<br \/>  ],<br \/>  module: {<br \/>    rules: [<br \/>      {<br \/>        test: \/.js$\/,<br \/>        exclude: \/(node_modules|bower_components)\/,<br \/>        use: {<br \/>          loader: 'babel-loader',<br \/>          options: {<br \/>            presets: [\"react\", \"stage-2\"],<br \/>            plugins: [<br \/>              ['transform-runtime', {<br \/>                \"helpers\": false,<br \/>                \"polyfill\": false,<br \/>                \"regenerator\": false,<br \/>                \"moduleName\": \"babel-runtime\"<br \/>              }]<br \/>            ]<br \/>          }<br \/>        }<br \/>      }<br \/>    ]<br \/>  }<\/strong><br \/>};<\/pre>\n<p>Criei uma task script no package.json chamada transpile com o comando webpack e o resultado final fica extremamente enxuto (j\u00e1 que n\u00e3o transpila classes e outras features do es6 tamb\u00e9m).<\/p>\n<figure>\n<p><img decoding=\"async\" data-width=\"635\" data-height=\"307\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*lv2lVvEJwlV-MTWbiUUBmQ.png\"><br \/>\n<\/figure>\n<p>Criei um bash script pra rodar todas as tasks necess\u00e1rias pra gerar uma vers\u00e3o, chamado <a href=\"https:\/\/github.com\/produtoreativo\/react-leaflet-googlemutant\/blob\/master\/publish.sh\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>publish.sh<\/strong><\/a><\/p>\n<pre>#!\/bin\/sh -x<br \/><br \/>yarn release #incrementa a vers\u00e3o, consultar a lib standard-version<br \/>VERSION=`node -e \"console.log(require('.\/package.json').version);\"`<br \/>NODE_ENV=production __VERSION__=$VERSION yarn transpile<br \/>git commit -a -m $VERSION<br \/>git push --follow-tags origin master<br \/>npm publish<\/pre>\n<h3>Debugger e atualiza\u00e7\u00f5es<\/h3>\n<p>Uma realidade \u00e9 que precisamos muitas vezes debugar o c\u00f3digo dessa sublib enquanto detectamos alguma evid\u00eancia de problema (atire o primeiro <strong>unit test<\/strong> que nunca fez isso), al\u00e9m de atualizar a vers\u00e3o conforme novas necessidades no projeto principal.<\/p>\n<p>Estamos trabalhando no BeerSwarm 1.0 que precisar\u00e1 da vers\u00e3o v0.1.9 do <a href=\"https:\/\/www.npmjs.com\/package\/react-leaflet-googlemutant\" target=\"_blank\" rel=\"noopener noreferrer\">react-leaflet-googlemutant<\/a> que ainda se encontra na v0.1.8.<\/p>\n<p>Para tornar isso poss\u00edvel o <strong>npm<\/strong> fornece um mecanismo simples para linkar um package local e fazer refer\u00eancia direta.<\/p>\n<p>Na raiz do projeto, execute o comando <strong><em>npm link.<\/em><\/strong><\/p>\n<pre>[cmilfont@MacBook-Pro-de-Christiano:\/Users\/cmilfont\/projetos\/react-leaflet-googlemutant:master:a635622:]<br \/>$ <strong>npm link<\/strong><br \/><strong>\/Users\/cmilfont\/.nvm\/versions\/node\/v8.0.0\/lib\/node_modules\/react-leaflet-googlemutant -&gt; \/Users\/cmilfont\/projetos\/react-leaflet-googlemutant<\/strong><\/pre>\n<p>Agora no projeto da lib voc\u00ea vai executar a task <strong>transpile<\/strong> com o par\u00e2metro -w (de watch) pra ficar observando todas as altera\u00e7\u00f5es:<\/p>\n<figure>\n<p><img decoding=\"async\" data-width=\"681\" data-height=\"337\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*zifjpc5GpftOQ5w0jN-qkQ.png\"><br \/>\n<\/figure>\n<p>Toda altera\u00e7\u00e3o no source muda automaticamente no Webpack que produz aquela sa\u00edda que planejamos.<\/p>\n<p>No projeto que importa essa lib rode o mesmo comando, mas indicando qual lib foi linkada <strong><em>npm link react-leaflet-googlemutant<\/em><\/strong>.<\/p>\n<p>E rode o seu toolset de desenvolvimento hot-loader, no meu caso o yarn start para o create-react-app, todas as modifica\u00e7\u00f5es na lib original causar\u00e3o um &#8220;touch&#8221; no projeto que linkou causando a imediata recompila\u00e7\u00e3o.<\/p>\n<p>Ao final de desenvolvimento execute o script bash de gera\u00e7\u00e3o da nova vers\u00e3o, coloque o n\u00famero correto no package.json que vai receber (um <strong>yarn upgrade nome-da-lib<\/strong> resolve) e evite quebrar o c\u00f3digo de outros projetos que continuar\u00e3o com a vers\u00e3o anterior.<\/p>\n<p>Espero que esse pequeno tutorial tenha sido \u00fatil como foi pra mim, quaisquer d\u00favidas comenta ou manda issues no github\u00a0<img decoding=\"async\" src=\"https:\/\/s0.wp.com\/wp-content\/mu-plugins\/wpcom-smileys\/twemoji\/2\/72x72\/1f642.png\" alt=\"&#x1f642;\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Um problema comum no Frontend \u00e9 o gerenciamento e organiza\u00e7\u00e3o do c\u00f3digo e as \u00faltimas tecnologias nos \u00faltimos anos nos ajudam a resolver. Caso Tenho um c\u00f3digo que depende de mapas em v\u00e1rias telas do sistema e organizei um componente que pode ser importado em v\u00e1rios arquivos. Como esse componente tem um ciclo de desenvolvimento [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts\/1851"}],"collection":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/comments?post=1851"}],"version-history":[{"count":0,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts\/1851\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/media?parent=1851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/categories?post=1851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/tags?post=1851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}