myHotTake

Tag: monorepo setup

  • How to Build a JavaScript Monorepo with Babel, ESLint & Webpack

    If you find this story helpful or intriguing, feel free to give it a like or share it with others who might enjoy it!


    I’m embarking on an ambitious project: building a skyscraper. The skyline awaits my creation, and I know that to succeed, I need the perfect blend of tools, much like how I approach setting up a monorepo with Babel, ESLint, and Webpack.

    First, I envision Babel as my architectural blueprint. Just as blueprints translate the architect’s vision into detailed plans that workers can understand, Babel transforms cutting-edge JavaScript into code that any browser can execute. With Babel, I ensure that my skyscraper—my code—stands tall and accessible, no matter the browser’s age or capability.

    Next, I bring in ESLint, my diligent site inspector. Like an inspector meticulously checking every beam and bolt, ESLint scans through my code, ensuring it adheres to the highest standards. It catches potential flaws, ensuring that the structure is not only impressive but also stable and safe. With ESLint, I can confidently say that my skyscraper meets all the necessary regulations and is devoid of errors that might cause future problems.

    Finally, I turn to Webpack, my project’s construction manager. Just as a manager coordinates various teams to ensure the skyscraper rises seamlessly, Webpack bundles all my code into a cohesive unit. It optimizes resources, manages dependencies, and ensures that each component of my skyscraper fits perfectly together. With Webpack, the complex array of features and functionalities are streamlined, resulting in a polished and efficient structure.


    Step 1: Setting Up the Monorepo

    First, I create my foundational monorepo structure, akin to laying down the skyscraper’s base. I start by initializing a new npm project.

    mkdir my-skyscraper
    cd my-skyscraper
    npm init -y

    I then add a packages directory where different parts of my project will reside, similar to different floors of a skyscraper.

    mkdir packages

    Step 2: Configuring Babel

    Just like crafting detailed architectural blueprints, I set up Babel to ensure my code is universally understood.

    npm install --save-dev @babel/core @babel/preset-env

    I create a Babel configuration file that serves as my blueprint:

    // babel.config.json
    {
      "presets": ["@babel/preset-env"]
    }

    Step 3: Integrating ESLint

    Next, I bring in ESLint to ensure everything is built to code. It’s like having my inspector ensure every part of the project meets quality standards.

    npm install --save-dev eslint
    npx eslint --init

    I configure ESLint in a .eslintrc.json file, setting rules to keep my project in top shape:

    // .eslintrc.json
    {
      "env": {
        "browser": true,
        "es2021": true
      },
      "extends": "eslint:recommended",
      "parserOptions": {
        "ecmaVersion": 12
      },
      "rules": {
        "indent": ["error", 2],
        "quotes": ["error", "double"]
      }
    }

    Step 4: Setting Up Webpack

    Finally, I configure Webpack, my construction manager, to bundle everything efficiently.

    npm install --save-dev webpack webpack-cli

    I create a webpack.config.js file to manage all components:

    // webpack.config.js
    const path = require('path');
    
    module.exports = {
      entry: './packages/main/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
      module: {
        rules: [
          {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
            },
          },
        ],
      },
    };

    Final Thoughts

    With this setup, I’ve constructed a robust foundation for my JavaScript project, much like erecting a skyscraper with each tool playing a pivotal role. Babel ensures compatibility, ESLint guarantees quality, and Webpack orchestrates everything into a seamless structure.

    Key Takeaways:

    1. Babel acts as the blueprint, converting modern JavaScript for all environments.
    2. ESLint serves as the inspector, maintaining code quality and adherence to best practices.
    3. Webpack is the construction manager, bundling and optimizing the project efficiently.
  • How to Set Up TypeScript in a Monorepo: A Step-by-Step Guide

    If you enjoy this story, feel free to like or share it with others who might find it helpful!


    I’m the captain of a spaceship, cruising through the vast universe of programming. My ship isn’t just any ordinary vessel; it’s a massive monorepo spaceship with different modules, each representing a planet with its unique ecosystem. To ensure smooth travel and communication between these planetary modules, I rely on a special language: TypeScript.

    Setting up TypeScript for my spaceship is like installing a universal translator for all my planetary modules. First, I gather everyone on the bridge of the ship and declare that we need a common language file, which in our case is the tsconfig.json. This file is like the core translation manual, dictating how the language should be interpreted across the spaceship.

    I then visit each planet, ensuring they have their own local dialects set up. This involves adding individual tsconfig.json files for each module, making sure they extend the universal translator from the ship’s bridge. This way, each planet can maintain its unique characteristics while still being able to communicate with the rest of the ship in a unified manner.

    Next, I make a stop at the ship’s supply station to install the necessary TypeScript tools and dependencies. This is akin to stocking up on translation devices and ensuring every crew member has access to them through a shared repository, like my spaceship’s central store.

    Finally, I conduct a test run, navigating through the galaxy and checking if each planet can communicate seamlessly with one another. If any translation errors pop up, I adjust the settings in the tsconfig.json files until the language barrier is completely lifted.

    With everything in place, my spaceship soars through the universe, with every planetary module operating in harmony, thanks to our trusty TypeScript setup. If this story helped you navigate your own monorepo spaceship, feel free to share it with fellow captains!


    As the captain of my monorepo spaceship, I’ve ensured that our universal translator—TypeScript—is in place, allowing all planetary modules to communicate effectively. Now, let’s look at how this translates to the world of JavaScript and TypeScript with some concrete examples.

    1. Setting Up the Universal Translator (tsconfig.json): At the heart of our spaceship is the main tsconfig.json file, which serves as the core translation manual. Here’s what it might look like:
       {
         "compilerOptions": {
           "target": "ES6",
           "module": "commonjs",
           "rootDir": "./",
           "outDir": "./dist",
           "composite": true,
           "declaration": true
         },
         "include": ["packages/*"],
         "exclude": ["node_modules"]
       }

    This file sets the standard for how TypeScript should compile our code. The "include" and "exclude" paths help us specify which parts of our spaceship are to be translated.

    1. Local Dialects for Each Planet (Module-Specific tsconfig.json): Each planetary module has its own dialect that extends the main translator. Here’s an example of a tsconfig.json for a specific module:
       {
         "extends": "../../tsconfig.json",
         "compilerOptions": {
           "rootDir": "./src",
           "outDir": "./dist"
         },
         "include": ["src"]
       }

    By extending the main tsconfig.json, each module maintains its specific settings while still adhering to the universal standards of the spaceship.

    1. Module Communication (Importing and Exporting): With TypeScript set up, modules can now import and export functionalities seamlessly. Here’s a simple example of how one module might export a function:
       // In src/utils.ts of the utils module
       export function greet(name: string): string {
         return `Hello, ${name}!`;
       }

    And how another module might use this function:

       // In src/index.ts of the app module
       import { greet } from 'utils';
    
       console.log(greet("Captain"));

    This setup ensures that all modules can communicate efficiently, using the universal TypeScript translator to understand each other.

    Key Takeaways/Final Thoughts:

    • Centralized Configuration: The main tsconfig.json serves as a central configuration file, ensuring consistency across the monorepo.
    • Modular Customization: Each module can have its specific configuration by extending the main tsconfig.json, allowing for flexibility while maintaining harmony.
    • Seamless Communication: With TypeScript, modules can safely import and export functionalities, reducing errors and increasing maintainability.