DEV Community

Cover image for Criando um monorepo com Lerna e Next.js
Henrique Rodrigues
Henrique Rodrigues

Posted on

Criando um monorepo com Lerna e Next.js

Usar uma estrutura monorepo para seu aplicativo pode ser muito vantajoso. Uma estrutura monorepo pode tornar mais fácil gerenciar vários aplicativos ou pacotes dependentes.

O que é Lerna?

Lerna é uma ferramenta que otimiza o fluxo de trabalho em torno do gerenciamento de repositórios de vários pacotes com git e npm.

O que é Next.js?

Next.js é uma estrutura da web de desenvolvimento front-end React de código aberto criada por Vercel que permite funcionalidades como renderização do lado do servidor e geração de sites estáticos para aplicativos da web baseados em React.

Vamos começar instalando o Lerna globalmente

yarn global add lerna

Em seguida precisamos criar uma pasta para nosso projeto

mkdir poc-lerna

Agora podemos executar o comando init do Lerna na pasta que criamos

lerna init

Print do comando lerna init rodado

Esse comando vai gerar essa estrutura no seu projeto

Estrura do projeto

Criando o pacote de front-end

Vamos criar nossa aplicação front-end utilizando o Next.js dentro de packages

cd packages && yarn create next-app

Agora a estrutura do projeto vai ficar desse jeito

Estrutura do projeto após instalar o next.js

Criando o pacote de componentes

O pacote de componentes vai ficar dentro da pasta packages e é nele que vamos criar os componentes utilizando o React que sera consumido dentro da aplicação front-end

Para criar esse pacote vamos utilizar o comando do Lerna

lerna create components

na linha entry point coloque dist/index.js, caso não tenha colocado abra o arquivo package.json dentro de componente e altere o valor de main para dist/index.js

Print do comando Lerna utilizado para criar o pacote de componente

Agora a estrutura do projeto vai ficar desse jeito

Estrutura do projeto após criar o pacote de componentes

Vamos adicionar microbundle ao nosso pacote de componentes

O que é microbundle?

Microbundle é um agrupador de zero configuração para módulos minúsculos, ele é um wrapper em torno de rollup.

cd packages/components && yarn add microbundle -D

Agora vamos alterar o script do pacote de componente para utilizar o microbundle

// packages/components/package.json

"scripts": {
   ..
   "dev": "microbundle watch --jsx React.createElement lib/*.js"
 },
Enter fullscreen mode Exit fullscreen mode

Além disso, vamos adicionar um source apontando para um aquivo de index.js dentro de lib no arquivo package.json

// packages/components/package.json

"source": "lib/index.js",
Enter fullscreen mode Exit fullscreen mode

Agora já podemos executar nossos pacotes utilizando o lerna, e caso tudo esteja certo vamos ver esse retorno no terminal

lerna run dev

Retorno do comando lerna run dev no terminal

Após esse comando conseguimos acessar nossa aplicação front-end acessando http://localhost:3000

Aplicação front-end rodando no localhost

Podemos também rodar nossos pacotes utilizando o comando acima passando --parallel, com isso conseguimos ver no terminal a compilação de ambos os pacotes mais detalhado.

Adicionando nosso pacote de componentes na aplicação front-end

Para fazer isso, podemos simplesmente adicionar o pacote de componentes no arquivo package.json do pacote front-end

// packages/front-end/package.json

"dependencies": {
   ..
   "components": "0.0.0"
 }
Enter fullscreen mode Exit fullscreen mode

Estamos utilizando a versão 0.0.0 pois é a mesma versão que esta no package.json do nosso pacote de components

Criando um componente

Para criar nosso componente precisamos primeiro adicionar o React dentro pacote de componentes

cd packages/components && yarn add react -D

Vamos criar um componente Button e importa-lo em nossa aplicação

// packages/components/lib/Button/index.js

import React, { Fragment } from "react";

const Button = ({ onClick, children }) => {
  return (
    <>
      <button className="button" onClick={onClick}>{children}</button>
      <style jsx="true">
        {`
          .button  {
            margin: 20px 0;
            background-color: #0070f3;
            border: 0;
            cursor: pointer;
            color: #FFFFFF;
            font-size: 1.3em;
            padding: 8px 16px;
          }
        `}
        </style>
    </>
  );
};

export default Button;

export default Button;
Enter fullscreen mode Exit fullscreen mode

Vamos criar um arquivo index.js dentro de lib e exportar esse componente

// packages/components/lib/index.js

"use strict";

import Button from "./Button";

module.exports = {
 Button
};
Enter fullscreen mode Exit fullscreen mode

Agora, podemos importar este componente em nosso pacote de front-end

// packages/front-end/pages/index.js

import Head from "next/head";
import { Button } from "components";

const Home = () => (
 <div className="container">
     ..
     <Button 
       onClick={() => console.log("button clicked!")}
     >
       Click me
     </Button>
     ..
 </div>
);

export default Home;
Enter fullscreen mode Exit fullscreen mode

Antes de rodar o projeto vamos rodar o comando do Lerna para vincular os pacotes locais e instalar as dependências de pacotes restantes

lerna bootstrap

Para finalizar vamos rodar novamente nosso projeto e visualizar a aplicação front-end no navegador, se você clicar no botão pode verificar no console que foi printado o texto button clicked!

lerna run dev

Print da tela do navegador mostrando o botão adicionado na aplicação

É isso! Esse é um exemplo simples de criar um monorepo com Lerna e Next.js e eu sei que existe outras maneiras de fazer isso, mais é uma base legal para entender um pouco de monerepo com Lerna e evoluir.

Aqui está o código completo deste artigo: lerna-with-nextjs

Caso queira se aprofundar no assunto

Lerna
Microbundle
Next.js


Obrigado por ler este artigo. Espero poder fornecer-lhes algumas informações úteis. Se sim, eu ficaria muito feliz se você recomendasse este post e clicasse no botão do ♥ para que mais pessoas possam ver isso.

Discussion (1)

Collapse
vitorcosta039 profile image
Vitor Costa • Edited on

Olá, td bem?
Primeiramente, parabéns pelo conteúdo, me ajudou muito!

Cara sobre o microbundle, usando como exemplo o // packages/components/lib/Button/index.js, como eu faria pra importar uma imagem nele, eu tento porém me dá um erro:
"Error: Unexpected character '�' (Note that you need plugins to import files that are not JavaScript)"

No caso, eu faço um import nomal:
import Logo from './logo.png'

já tentei de tudo mas não consigo resolver, se puder me ajudar ficaria agradecido!