TypeScript: Build a Simple Web-Based Code Formatter

In the world of web development, writing clean, readable, and maintainable code is crucial. It’s not just about getting the code to work; it’s about making it easy for you and others to understand, modify, and debug. One of the best ways to achieve this is by using a code formatter. A code formatter automatically adjusts the spacing, indentation, and overall structure of your code, ensuring consistency and readability across your projects. This tutorial will guide you through building a simple, web-based code formatter using TypeScript. We’ll explore the core concepts, step-by-step implementation, and address common pitfalls.

Why Code Formatting Matters

Imagine reading a book where the paragraphs are all jumbled together, with no spaces between sentences and inconsistent indentation. It would be a nightmare, right? Code is no different. Poorly formatted code is difficult to read and understand, leading to:

  • Increased debugging time: It takes longer to spot errors when the code is messy.
  • Higher maintenance costs: Modifying poorly formatted code is more challenging and error-prone.
  • Reduced collaboration efficiency: Team members struggle to understand each other’s code.

A good code formatter solves these problems by automatically:

  • Enforcing consistent style guidelines.
  • Improving code readability.
  • Reducing the chances of human error.

Core Concepts: TypeScript and Prettier

Before we dive into the implementation, let’s briefly discuss the technologies we’ll be using:

TypeScript

TypeScript is a superset of JavaScript that adds static typing. This means you can define the data types of variables, function parameters, and return values. TypeScript helps catch errors early in the development process, making your code more reliable and easier to maintain. It also provides better code completion and refactoring capabilities in your IDE.

Prettier

Prettier is an opinionated code formatter. It takes your code and automatically formats it to adhere to a consistent style. Prettier supports various languages, including JavaScript, TypeScript, HTML, CSS, and more. It eliminates the need for manual formatting and ensures that your code always looks clean and consistent.

Setting Up Your Project

Let’s get started by setting up our project. We’ll use a simple HTML file, a TypeScript file, and install Prettier as a development dependency. Follow these steps:

  1. Create a new project directory (e.g., `code-formatter`).
  2. Navigate into the directory using your terminal: `cd code-formatter`.
  3. Initialize a new Node.js project: `npm init -y`. This creates a `package.json` file.
  4. Install TypeScript and Prettier as development dependencies: `npm install –save-dev typescript prettier`.
  5. Create a `tsconfig.json` file. You can generate a basic one using the TypeScript compiler: `npx tsc –init`. This file configures the TypeScript compiler.
  6. Create an HTML file named `index.html` in your project directory.
  7. Create a TypeScript file named `app.ts` in your project directory.

Your project structure should look something like this:

code-formatter/
├── index.html
├── app.ts
├── package.json
├── tsconfig.json
└── node_modules/  (This directory is created when you install npm packages)

Building the HTML Structure

Let’s create a basic HTML structure for our code formatter. Open `index.html` and add the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Code Formatter</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 20px;
        }
        textarea {
            width: 100%;
            height: 200px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <textarea id="codeInput" placeholder="Enter your code here"></textarea>
    <button id="formatButton">Format Code</button>
    <textarea id="codeOutput" placeholder="Formatted code"></textarea>
    <script src="app.js"></script>
</body>
</html>

This HTML creates a simple interface with:

  • A `textarea` for the user to input their code (`codeInput`).
  • A button to trigger the formatting (`formatButton`).
  • Another `textarea` to display the formatted code (`codeOutput`).
  • A link to the `app.js` file, which we’ll generate from our `app.ts` file.

Writing the TypeScript Logic

Now, let’s write the TypeScript code that will handle the formatting. Open `app.ts` and add the following code:

import prettier from "prettier";

const codeInput = document.getElementById("codeInput") as HTMLTextAreaElement;
const formatButton = document.getElementById("formatButton") as HTMLButtonElement;
const codeOutput = document.getElementById("codeOutput") as HTMLTextAreaElement;

async function formatCode() {
  if (!codeInput || !codeOutput) {
    console.error("Code input or output element not found.");
    return;
  }

  const code = codeInput.value;

  if (!code) {
    codeOutput.value = "";
    return;
  }

  try {
    const formattedCode = await prettier.format(code, {
      parser: "babel", // Or your preferred parser (e.g., "typescript", "html", "css")
      plugins: [], // You can add Prettier plugins here
    });
    codeOutput.value = formattedCode;
  } catch (error: any) {
    console.error("Formatting error:", error);
    codeOutput.value = `Formatting error: ${error.message}`;
  }
}

formatButton?.addEventListener("click", formatCode);

Let’s break down this code:

  • We import the `prettier` library.
  • We get references to the HTML elements (input, button, and output textareas).
  • The `formatCode` function is an `async` function that does the following:
    • Gets the code from the input textarea.
    • Uses `prettier.format()` to format the code. The `parser` option specifies the language of the code (in this case, “babel” which is suitable for JavaScript, but change to “typescript”, “html”, etc., as needed). The `plugins` array is where you can include Prettier plugins for additional formatting capabilities.
    • Displays the formatted code in the output textarea.
    • Handles any formatting errors.
  • We add an event listener to the format button to call the `formatCode` function when clicked.

Compiling and Running the Code

Now, let’s compile the TypeScript code into JavaScript and run it in the browser:

  1. Open your terminal and navigate to your project directory.
  2. Compile the TypeScript code: `npx tsc`. This will generate an `app.js` file.
  3. Open `index.html` in your web browser.
  4. Enter some code into the input textarea.
  5. Click the “Format Code” button.
  6. The formatted code should appear in the output textarea.

Addressing Common Mistakes

Here are some common mistakes and how to fix them:

1. Prettier Not Installed

If you get an error that Prettier is not found, make sure you have installed it as a development dependency using `npm install –save-dev prettier`.

2. Incorrect Parser

If the code is not formatted correctly, or if you get an error, the parser might be incorrect. Ensure that the `parser` option in `prettier.format()` is set to the correct language (e.g., “babel” for JavaScript, “typescript” for TypeScript, “html” for HTML, “css” for CSS). For example, if you are formatting HTML, your `prettier.format()` call might look like this:

const formattedCode = await prettier.format(code, {
  parser: "html",
  plugins: [],
});

3. Missing HTML Element References

Make sure that the `id` attributes in your HTML match the element references in your TypeScript code. For example, if your HTML has `