TypeScript Tutorial: Building a Simple Web-Based Code Beautifier

In the world of web development, clean and readable code is paramount. It’s not just about making your code functional; it’s about making it maintainable, collaborative, and less prone to errors. Imagine working on a project with hundreds or even thousands of lines of code, all crammed together without proper indentation, spacing, or formatting. It would be a nightmare, right? This is where code beautifiers come in. They automatically format your code, making it easier to read and understand. In this tutorial, we’ll dive into how to build a simple web-based code beautifier using TypeScript, a language that brings structure and type safety to your JavaScript projects. We’ll explore the core concepts, step-by-step instructions, and practical examples to get you started.

Why Build a Code Beautifier?

While many Integrated Development Environments (IDEs) and code editors come with built-in formatting features, building your own code beautifier offers several advantages:

  • Customization: You have complete control over the formatting rules, allowing you to tailor them to your specific needs and coding style.
  • Learning: Building a code beautifier is an excellent learning experience, helping you understand how code parsing, abstract syntax trees (ASTs), and code generation work.
  • Integration: You can integrate your beautifier with other tools and workflows, such as continuous integration pipelines or code review systems.

Core Concepts

Before we start coding, let’s understand the key concepts involved:

  • TypeScript: A superset of JavaScript that adds static typing. This helps catch errors early and improves code maintainability.
  • AST (Abstract Syntax Tree): A tree-like representation of the code’s structure. Parsing your code into an AST is the first step in understanding and manipulating it.
  • Code Formatting: The process of applying rules to improve code readability, such as indentation, spacing, and line breaks.
  • Web-Based Interface: A user interface built with HTML, CSS, and JavaScript (or TypeScript) that allows users to input code, beautify it, and see the results.

Setting Up the Project

Let’s set up a basic project structure. We’ll use the following:

  • Node.js and npm: For package management and running our application.
  • TypeScript compiler (tsc): To compile TypeScript code into JavaScript.
  • HTML, CSS, and JavaScript: For the web interface.

Here are the steps:

  1. Create a Project Directory: Create a new directory for your project (e.g., `code-beautifier`).
  2. Initialize npm: Open your terminal, navigate to the project directory, and run `npm init -y`. This creates a `package.json` file.
  3. Install TypeScript: Run `npm install typescript –save-dev`. This installs TypeScript as a development dependency.
  4. Create a `tsconfig.json` file: Run `npx tsc –init`. This creates a `tsconfig.json` file with default settings. You can customize this file to configure your TypeScript compilation options. For example, you might want to set the `target` to `es6` (or a later version) and the `module` to `commonjs` (or `esnext` if you prefer).
  5. Create Project Folders and Files: Create the following folders and files in your project directory:
    • `src/` (This is where your TypeScript code will reside.)
    • `src/index.ts` (The main entry point for your TypeScript code.)
    • `public/` (This will hold your HTML, CSS, and any client-side JavaScript files.)
    • `public/index.html` (The HTML file for your web interface.)
    • `public/style.css` (The CSS file for styling your web interface.)

Writing the TypeScript Code

Now, let’s write the TypeScript code for our code beautifier. We’ll focus on basic indentation and spacing for this example. We will use a simple approach to demonstrate the core concept. More sophisticated beautifiers use ASTs and complex parsing libraries, which are beyond the scope of this tutorial, but can be explored for more advanced projects.

`src/index.ts`

This file will contain the core logic for beautifying the code.

// src/index.ts

function beautifyCode(code: string): string {
  let indentLevel = 0;
  let beautifiedCode = '';
  const lines = code.split('n');

  for (const line of lines) {
    let trimmedLine = line.trim();
    let indent = '  '.repeat(indentLevel);

    // Handle opening curly braces
    if (trimmedLine.endsWith('{')) {
      beautifiedCode += indent + trimmedLine + 'n';
      indentLevel++;
    }
    // Handle closing curly braces
    else if (trimmedLine.startsWith('}')) {
      indentLevel = Math.max(0, indentLevel - 1);
      indent = '  '.repeat(indentLevel);
      beautifiedCode += indent + trimmedLine + 'n';
    }
    // Handle other statements
    else {
      beautifiedCode += indent + trimmedLine + 'n';
    }
  }

  return beautifiedCode;
}

// Example Usage (for testing in the browser console)
// const code = `function myFunction() {n  if (true) {n    console.log('Hello');n  }n}`;
// const beautified = beautifyCode(code);
// console.log(beautified);

// Attach to the window object to make it accessible in the browser (for simplicity)
(window as any).beautifyCode = beautifyCode;

Explanation of the code:

  • `beautifyCode(code: string): string` Function: This function takes a string of code as input and returns the beautified code as a string.
  • `indentLevel` Variable: Keeps track of the current indentation level.
  • `lines = code.split(‘n’)`: Splits the input code into an array of lines.
  • Looping Through Lines: The code iterates through each line of the input code.
  • `trimmedLine = line.trim()`: Removes leading and trailing whitespace from the line.
  • Indentation Logic:
    • If a line ends with an opening curly brace (`{`), the indent level is increased, and the line is added to the output with the current indentation.
    • If a line starts with a closing curly brace (`}`), the indent level is decreased, and the line is added to the output with the current indentation.
    • For other lines, the line is added to the output with the current indentation.
  • Example Usage (commented out): Demonstrates how the function can be used.
  • Attaching to the window object: Makes the `beautifyCode` function globally accessible in the browser, allowing us to call it from our HTML. This is done for simplicity in this example. In a real-world application with modules, you would likely structure this differently.

Creating the Web Interface

Now, let’s create the HTML and CSS for our web-based code beautifier. This will provide the user interface to interact with our TypeScript logic.

`public/index.html`

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Code Beautifier</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>Code Beautifier</h1>

    <div class="input-section">
      <label for="codeInput">Enter Code:</label>
      <textarea id="codeInput" rows="10" cols="80"></textarea>
    </div>

    <button id="beautifyButton">Beautify</button>

    <div class="output-section">
      <label for="outputCode">Beautified Code:</label>
      <textarea id="outputCode" rows="10" cols="80" readonly></textarea>
    </div>
  </div>

  <script src="index.js"></script>
</body>
</html>

Explanation:

  • Basic HTML Structure: Sets up the basic structure of the HTML document.
  • Title: Sets the title of the page.
  • CSS Link: Links to the `style.css` file for styling.
  • Input Section: Contains a `textarea` for the user to enter their code.
  • Beautify Button: A button that, when clicked, will trigger the beautification process.
  • Output Section: Contains a `textarea` to display the beautified code. The `readonly` attribute prevents the user from editing the output directly.
  • JavaScript Link: Links to the `index.js` file (which will be generated from our TypeScript code).

`public/style.css`

/* public/style.css */
body {
  font-family: sans-serif;
  background-color: #f4f4f4;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.container {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 80%; /* Adjust as needed */
  max-width: 900px;
}

h1 {
  text-align: center;
  color: #333;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

textarea {
  width: 100%;
  padding: 10px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: monospace;
  font-size: 14px;
}

button {
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

button:hover {
  background-color: #0056b3;
}

.input-section, .output-section {
  margin-bottom: 15px;
}

Explanation:

  • Basic Styling: Provides basic styling for the page, including fonts, colors, and layout.
  • Container: Styles the main container, including padding, rounded corners, and a shadow.
  • Headings and Labels: Styles for headings and labels to improve readability.
  • Textareas: Styles for the input and output textareas, including font and border.
  • Button: Styles for the beautify button, including hover effects.

Adding JavaScript for Interaction

Now, let’s add the JavaScript code to handle the user interaction. This code will take the input from the textarea, call the `beautifyCode` function we wrote in TypeScript, and display the result in the output textarea.

`public/index.js`

This file will be generated by compiling your TypeScript code.

// public/index.js (Generated by TypeScript compiler)

// Assuming the beautifyCode function is available globally (as we attached it to window in src/index.ts)

document.addEventListener('DOMContentLoaded', () => {
  const codeInput = document.getElementById('codeInput');
  const beautifyButton = document.getElementById('beautifyButton');
  const outputCode = document.getElementById('outputCode');

  if (codeInput && beautifyButton && outputCode) {
    beautifyButton.addEventListener('click', () => {
      const code = codeInput.value;
      if (typeof beautifyCode === 'function') {
        const beautifiedCode = beautifyCode(code);
        outputCode.value = beautifiedCode;
      } else {
        outputCode.value = 'Error: beautifyCode function not found.';
        console.error('beautifyCode function is not defined. Ensure src/index.ts is compiled and accessible.');
      }
    });
  } else {
    console.error('One or more elements not found. Check your HTML.');
  }
});

Explanation:

  • `DOMContentLoaded` Event Listener: Ensures the JavaScript code runs after the HTML document has fully loaded.
  • Get Elements: Retrieves references to the input textarea, the beautify button, and the output textarea from the HTML.
  • Event Listener for Button Click: Attaches an event listener to the beautify button. When the button is clicked, the following happens:
    • Gets the code from the input textarea.
    • Calls the `beautifyCode()` function (which we attached to `window` in `src/index.ts`).
    • Displays the beautified code in the output textarea.
    • Includes error handling to check if the `beautifyCode` function is available and if the HTML elements are present.

Compiling and Running the Application

Now that we have all the code in place, let’s compile the TypeScript code and run the application.

  1. Compile TypeScript: Open your terminal in the project directory and run `npx tsc`. This will compile your `src/index.ts` file into `public/index.js`. The compiled JavaScript file will be placed in the `public` directory.
  2. Open the HTML file: Open the `public/index.html` file in your web browser. You should see the code beautifier interface.
  3. Test the Beautifier: Enter some code into the input textarea, click the “Beautify” button, and see the formatted output.

Common Mistakes and How to Fix Them

Here are some common mistakes and how to fix them when building a code beautifier:

  • Incorrect TypeScript Compilation:
    • Problem: You might encounter errors during the TypeScript compilation process (`npx tsc`).
    • Solution: Double-check your `tsconfig.json` file for any configuration errors (e.g., incorrect paths, module settings, or target). Also, ensure you have installed all necessary dependencies. Examine the error messages carefully as they will often point to the source of the problem.
  • JavaScript Errors in the Browser:
    • Problem: The browser console might show errors related to the JavaScript code (e.g., “`beautifyCode` is not defined”).
    • Solution: Verify that your `src/index.ts` file has been successfully compiled into `public/index.js`. Make sure the `index.js` file is correctly linked in your `index.html` file. Check that the `beautifyCode` function is correctly attached to the `window` object in `src/index.ts`. Inspect the network tab in your browser’s developer tools to ensure that `index.js` is loaded without errors.
  • Incorrect HTML Element IDs:
    • Problem: The JavaScript code might not be able to find the HTML elements if the IDs in your JavaScript code don’t match the IDs in your HTML.
    • Solution: Carefully check that the IDs used in your JavaScript code (e.g., `codeInput`, `beautifyButton`, `outputCode`) exactly match the IDs in your HTML.
  • CSS Styling Issues:
    • Problem: Your CSS styles might not be applied correctly.
    • Solution: Verify that your `style.css` file is correctly linked in your `index.html` file. Ensure that the CSS rules are correctly written and that there are no conflicting styles. Use your browser’s developer tools to inspect the elements and see which styles are being applied.
  • Incorrect Indentation Logic:
    • Problem: The beautified code might not be indented correctly.
    • Solution: Carefully review your indentation logic in the `beautifyCode` function. Make sure you are correctly incrementing and decrementing the `indentLevel` variable. Test with different code structures (e.g., nested `if` statements, functions, loops) to ensure the indentation works as expected.

Extending the Code Beautifier

This simple code beautifier provides a foundation for more advanced features. Here are some ideas for extending it:

  • More Sophisticated Indentation: Implement more complex logic to handle different code structures, such as `for` loops, `while` loops, `switch` statements, and more.
  • Syntax Highlighting: Integrate a syntax highlighting library to visually improve the readability of the code in both the input and output textareas.
  • Code Folding: Allow users to collapse and expand sections of code.
  • Customizable Formatting Rules: Allow users to configure the indentation style (e.g., spaces vs. tabs, indentation size) and other formatting rules.
  • Support for Different Languages: Extend the beautifier to support multiple programming languages (e.g., JavaScript, Python, CSS, HTML). This would likely involve using different parsing libraries and formatting rules for each language.
  • Error Handling and Validation: Add error handling to catch and display any errors during the beautification process. Validate the input code to prevent unexpected behavior.
  • Integration with Code Editors: Explore ways to integrate the beautifier with popular code editors as a plugin or extension.

Summary / Key Takeaways

In this tutorial, we’ve learned how to build a basic web-based code beautifier using TypeScript. We’ve covered the core concepts, set up a simple project, written the TypeScript code for indentation, created a web interface with HTML and CSS, and added JavaScript to handle user interaction. Building a code beautifier is a great way to learn about code parsing, ASTs, and code generation, while also improving your coding skills. Remember to experiment with the code, try different formatting rules, and explore ways to enhance its functionality. By taking the time to understand the fundamentals and by continuously practicing, you’ll become more proficient in writing clean and readable code, which is an invaluable skill for any software engineer.

FAQ

Here are some frequently asked questions:

  1. Why use TypeScript for a code beautifier? TypeScript provides static typing, which helps catch errors early and improves code maintainability. It also enhances code readability and makes it easier to refactor your code.
  2. What is an AST, and why is it important for code beautification? An AST (Abstract Syntax Tree) is a tree-like representation of your code’s structure. It’s important because it allows you to understand and manipulate the code’s structure, which is essential for tasks like code formatting, code analysis, and code generation.
  3. How can I handle different programming languages in my code beautifier? To support different programming languages, you would need to use different parsing libraries and formatting rules for each language. Each language has its own syntax and structure, so the parsing and formatting logic needs to be tailored to each one.
  4. Can I use this code beautifier in a production environment? The code beautifier presented here is a basic example. For production use, you would need to implement more sophisticated features, such as advanced formatting rules, error handling, and support for different languages. You might also consider using a pre-built code formatting library or tool.

The journey of a thousand lines of code begins with a single, well-formatted statement. With the tools and knowledge gained from this tutorial, you’re now equipped to not only write cleaner code, but also to build tools that help others do the same. Keep exploring, keep coding, and remember that every line of code you write is a step towards mastery.

” ,
“aigenerated_tags”: “TypeScript, Code Beautifier, Web Development, Tutorial, Beginner, Intermediate, Formatting, Front-End