Skip to content
forked from unjs/magicast

🧀 Programmatically modify JavaScript and TypeScript source codes with a simplified, elegant and familiar syntax powered by recast and babel.

License

Notifications You must be signed in to change notification settings

guncebektas/magicast

 
 

Repository files navigation

🧀 Magicast

npm version npm downloads bundle Codecov License JSDocs

Programmatically modify JavaScript and TypeScript source codes with a simplified, elegant and familiar syntax. Built on top of the AST parsed by recast and babel.

❯ 🧙🏼 Magical modify a JS/TS file and write back magically just like JSON!
❯ 🔀 Exports/Import manipulate module's imports and exports at ease
❯ 💼 Function Arguments easily manipulate arguments passed to a function call, like defineConfig()
❯ 🎨 Smart Formatting preseves the formatting style (quotes, tabs, etc.) from the original code
❯ 🧑‍💻 Readable get rid of the complexity of AST manipulation and make your code super readable

Install

Install npm package:

# using yarn
yarn add --dev magicast

# using npm
npm install -D magicast

# using pnpm
pnpm add -D magicast

Import utilities:

// ESM / Bundler
import { parseModule, generateCode, builders, createNode } from "magicast";

// CommonJS
const { parseModule, generateCode, builders, createNode } = require("magicast");

Examples

Example: Modify a file:

config.js:

export default {
  foo: ["a"],
};

Code to modify and append b to foo prop of defaultExport:

import { loadFile, writeFile } from "magicast";

const mod = await loadFile("config.js");

mod.exports.default.foo.push("b");

await writeFile(mod);

Updated config.js:

export default {
  foo: ["a", "b"],
};

Example: Directly use AST utils:

import { parseModule, generateCode } from "magicast";

// Parse to AST
const mod = parseModule(`export default { }`);

// Ensure foo is an array
mod.exports.default.foo ||= [];
// Add a new array member
mod.exports.default.foo.push("b");
mod.exports.default.foo.unshift("a");

// Generate code
const { code, map } = generateCode(mod);

Generated code:

export default {
  foo: ["a", "b"],
};

Example: Get the AST directly:

import { parseModule, generateCode } from "magicast";

const mod = parseModule(`export default { }`);

const ast = mod.exports.default.$ast
// do something with ast

Example: Function parameters:

import { parseModule, generateCode } from "magicast";

const mod = parseModule(`export default defineConfig({ foo: 'bar' })`);

// Support for both bare object export and `defineConfig` wrapper
const options = mod.exports.default.$type === 'function-call'
  ? mod.exports.default.$args[0]
  : mod.exports.default;

console.log(options.foo) // bar

Example: Create a function call:

import { parseModule, generateCode, builders } from "magicast";

const mod = parseModule(`export default {}`);

const options = mod.exports.default.list = builders.functionCall('create', [1, 2, 3])

console.log(mod.generateCode()) // export default { list: create([1, 2, 3]) }

High Level Helpers

We also experiments to provide a few high level helpers to make common tasks easier. You could import them from magicast/helpers. They might be move to a separate package in the future.

import { 
  deepMergeObject,
  addNuxtModule,
  addVitePlugin,
  // ...
} from "magicast/helpers";

We recommend to check out the source code and test cases for more details.

Development

  • Clone this repository
  • Install latest LTS version of Node.js
  • Enable Corepack using corepack enable
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev

License

Made with 💛

Published under MIT License.

About

🧀 Programmatically modify JavaScript and TypeScript source codes with a simplified, elegant and familiar syntax powered by recast and babel.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 100.0%