Skip to content

BabelJs - Babel CLI

The Babel Command Line Interface (CLI), @babel/cli, is a powerful tool for transpiling JavaScript files directly from your terminal. This chapter delves deeper into its usage, options, and practical applications. While many complex projects use Babel through bundlers like Webpack, the CLI is excellent for server-side code, build scripts, or simpler projects.

Before proceeding, ensure you have a project set up with the necessary Babel packages installed, as covered in the ‘BabelJS - CLI’ and ‘Project Setup’ chapters. This includes @babel/core, @babel/cli, and @babel/preset-env, along with a babel.config.json file.

  1. Initialize Project & Install Dependencies:
mkdir advanced-babel-cli
cd advanced-babel-cli
npm init -y
npm install --save-dev @babel/core @babel/cli @babel/preset-env
  1. Babel Configuration (babel.config.json):
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current" // Example: target current Node.js version
}
}
]
]
}
  1. Sample Source Files:

Create a src directory with a few files:

src/main.js:

import { greet } from './utils/helper.js';
const user = "World";
console.log(greet(user));
async function delayedMessage() {
await new Promise(resolve => setTimeout(resolve, 100));
console.log('This message is delayed!');
}
delayedMessage();

src/utils/helper.js:

export const greet = (name) => `Hello, ${name} from a module!`;
export class Calculator {
add(a, b) {
return a + b;
}
}

Note: @babel/preset-env by default doesn’t transpile ES modules syntax (import/export) if the target environment supports it (like modern Node.js). If you need to transpile to CommonJS (e.g., for older Node versions or specific bundler expectations), you might adjust @babel/preset-env’s modules option, e.g., "modules": "commonjs" in its configuration. For this example, we’ll assume a target that might require module transformation or that we want to demonstrate bundling later.

As seen before, --out-file for single files and --out-dir for directories are fundamental:

# Compile a single file
npx babel src/main.js --out-file lib/main.compiled.js
# Compile entire src directory to lib directory
npx babel src --out-dir lib

For development, automatically recompile on file changes:

npx babel src --out-dir lib --watch

Babel will now monitor files in src and recompile them to lib whenever they are modified.

Source maps are crucial for debugging, as they map the compiled code back to your original source code. Options: true (separate .map file), inline (embed in JS file), or both.

npx babel src --out-dir lib --source-maps

This will create .js.map files alongside your compiled .js files in the lib directory.

Exclude specific files or patterns from compilation. This is useful for test files, documentation, etc. Patterns are glob-like.

# Ignore all .test.js files and files in any __tests__ directory
npx babel src --out-dir lib --ignore "**/*.test.js","**/__tests__/**"

When compiling a directory, Babel only processes files it recognizes as JavaScript. If you have other assets (e.g., JSON data, templates) in your src directory that need to be in the lib directory, use --copy-files.

npx babel src --out-dir lib --copy-files

If you use non-standard extensions (e.g., .mjs for ES modules, or .ts for TypeScript), tell Babel to process them:

# Assuming @babel/preset-typescript is configured for .ts files
npx babel src --out-dir lib --extensions ".ts,.js"
  • --no-babelrc: Ignores .babelrc and .babelrc.js files. Does not ignore babel.config.json or babel.config.js.
  • --config-file <path>: Specify a path to a babel.config.json (or .js, .cjs, .mjs) file. Use --config-file false to disable project-wide configuration.
  • --presets <list> and --plugins <list>: Comma-separated list of presets/plugins to use. Generally, using a config file is preferred for maintainability.

Combining Multiple Source Files into One (Use with Caution)

Section titled “Combining Multiple Source Files into One (Use with Caution)”

The Babel CLI can concatenate multiple input files into a single output file. However, this is a simple concatenation and does not handle module dependencies like a bundler (Webpack, Rollup, Parcel) would. It’s generally not recommended for projects using ES modules with import/export unless you have a very specific use case and understand the implications.

# Concatenates src/utils/helper.js and src/main.js into lib/bundle.js
# WARNING: This does NOT resolve ES module imports between these files correctly.
# npx babel src/utils/helper.js src/main.js --out-file lib/bundle.js (Not recommended for modules)

For proper module bundling, use tools like Webpack, Rollup, or Parcel, which use @babel/core programmatically.

It’s best to encapsulate CLI commands in package.json scripts for consistency and ease of use.

// package.json (scripts section)
"scripts": {
"clean": "rm -rf lib", // Helper script to clean output directory
"build": "npm run clean && babel src --out-dir lib --source-maps --copy-files",
"start:dev": "npm run build -- --watch", // Use -- to pass --watch to the build script's babel command
"lint": "eslint src/**/*.js" // Example: if you use ESLint
}

Now you can run:

  • npm run build: Cleans the lib directory and builds your project.
  • npm run start:dev: Builds and then watches for changes.

Usage with Plugins and Presets via CLI (Advanced/Specific Cases)

Section titled “Usage with Plugins and Presets via CLI (Advanced/Specific Cases)”

If you need to apply a specific plugin not covered by your presets or want to test a plugin in isolation:

# Example: Using a hypothetical plugin (install it first)
# npm install --save-dev @babel/plugin-proposal-pipeline-operator (example name)
# npx babel src/main.js --plugins @babel/plugin-proposal-pipeline-operator --out-file temp.js

This is usually for experimentation or very specific build steps. For most projects, defining plugins and presets in babel.config.json is the standard.

Real-World Application: Transpiling a Node.js Application

Section titled “Real-World Application: Transpiling a Node.js Application”

Imagine you’re building a Node.js server application using modern JavaScript features (async/await, ES modules, class properties) but need to deploy it to an environment running an older Node.js version that doesn’t fully support these features.

  1. Write your server code in src/server.js using modern syntax.

  2. Configure babel.config.json with @babel/preset-env targeting your deployment Node.js version (e.g., "targets": { "node": "12" }). You might also need "modules": "commonjs" in @babel/preset-env options if the target Node version requires CommonJS.

  3. Use an npm script like "build": "babel src --out-dir dist_server --copy-files".

  4. Your deployment process would then run npm run build, and you’d run the server from the dist_server directory (e.g., node dist_server/server.js).

The Babel CLI provides a flexible and direct way to integrate JavaScript transpilation into various development workflows. While bundlers are essential for complex front-end apps, the CLI remains a valuable tool for Node.js development, scripting, and simpler build tasks.

For the most up-to-date and comprehensive list of CLI options, always consult the official Babel documentation: https://babeljs.io/docs/en/babel-cli