GithubHelp home page GithubHelp logo

ak239 / astring Goto Github PK

View Code? Open in Web Editor NEW

This project forked from davidbonnet/astring

0.0 2.0 0.0 352 KB

Tiny and fast JavaScript code generator from an ESTree-compliant AST.

License: MIT License

JavaScript 91.93% HTML 8.07%

astring's Introduction

Astring

Build Status Coverage Status NPM Version devDependency Status Greenkeeper badge

A tiny and fast JavaScript code generator from an ESTree-compliant AST.

Key features

  • Generates JavaScript code up to version 7 and finished proposals.
  • Works on ESTree-compliant ASTs such as the ones produced by Acorn.
  • Extendable with custom AST node handlers.
  • Considerably faster than Babel (up to 50×), Escodegen (up to 10×), and UglifyJS (up to 125×).
  • Supports source map generation with Source Map.
  • Supports comment generation with Astravel.
  • No dependencies and small footprint (≈ 16 KB minified, ≈ 4 KB gziped).

Checkout the live demo showing Astring in action.

Contents

Installation

⚠️ Astring relies on String.prototype.repeat(amount) and String.prototype.endsWith(string). If the environment running Astring does not define these methods, use string.prototype.repeat, string.prototype.endsWith or babel-polyfill.

Install with the Node Package Manager:

npm install astring

Alternatively, checkout this repository and install the development dependencies to build the module file:

git clone https://github.com/davidbonnet/astring.git
cd astring
npm install

A browser-ready minified version of Astring is available at dist/astring.min.js.

Import

With JavaScript 6 modules:

import { generate } from 'astring';

With CommonJS:

const { generate } = require('astring');

When used in a browser environment, the module exposes a global variable astring:

<script src="astring.min.js" type="text/javascript"></script>
<script type="text/javascript">
	var generate = astring.generate;
</script>

API

The astring module exposes the following properties:

generate(node: object, options: object): string | object

Returns a string representing the rendered code of the provided AST node. However, if an output stream is provided in the options, it writes to that stream and returns it.

The options are:

  • indent: string to use for indentation (defaults to "\t")
  • lineEnd: string to use for line endings (defaults to "\n")
  • startingIndentLevel: indent level to start from (defaults to 0)
  • comments: generate comments if true (defaults to false)
  • output: output stream to write the rendered code to (defaults to null)
  • generator: custom code generator (defaults to astring.baseGenerator)
  • sourceMap: source map generator (defaults to null)

baseGenerator: object

Base generator that can be used to extend Astring.

Examples

The following examples are written in JavaScript 5 with Astring imported à la CommonJS.

Generating code

This example uses Acorn, a blazingly fast JavaScript AST producer and therefore the perfect companion of Astring.

// Make sure acorn and astring modules are imported
// Set example code
var code = "let answer = 4 + 7 * 5 + 3;\n";
// Parse it into an AST
var ast = acorn.parse(code, { ecmaVersion: 6 });
// Format it into a code string
var formattedCode = astring.generate(ast, {
	indent: '   ',
	lineEnd: '\n',
});
// Check it
console.log((code === formattedCode) ? 'It works !' : 'Something went wrong…');

Generating source maps

This example uses the source map generator from the Source Map module.

// Make sure acorn, sourceMap and astring modules are imported
var code = "function add(a, b) { return a + b; }\n";
var ast = acorn.parse(code, {
	ecmaVersion: 6,
	sourceType: 'module',
	// Locations are needed in order for the source map generator to work
	locations: true,
});
// Create empty source map generator
var map = new sourceMap.SourceMapGenerator({
	// Source file name must be set and will be used for mappings
	file: 'script.js',
});
var formattedCode = generate(ast, {
	// Enable source maps
	sourceMap: map,
});
// Display generated source map
console.log(map.toString());

Using writable streams

This example for Node shows how to use writable streams to get the rendered code.

// Make sure acorn and astring modules are imported
// Set example code
var code = "let answer = 4 + 7 * 5 + 3;\n";
// Parse it into an AST
var ast = acorn.parse(code, { ecmaVersion: 6 });
// Format it and write the result to stdout
var stream = astring.generate(ast, {
	output: process.stdout,
});
// The returned value is the output stream
console.log('stream is process.stdout?', stream === process.stdout);

Generating comments

Astring supports comment generation, provided they are stored on the AST nodes. To do so, this example uses Astravel, a fast AST traveller and modifier.

// Make sure acorn, astravel and astring modules are imported
// Set example code
var code = [
	"// Compute the answer to everything",
	"let answer = 4 + 7 * 5 + 3;",
	"// Display it",
	"console.log(answer);",
].join('\n') + '\n';
// Parse it into an AST and retrieve the list of comments
var comments = [];
var ast = acorn.parse(code, {
	ecmaVersion: 6,
	locations: true,
	onComment: comments,
});
// Attach comments to AST nodes
astravel.attachComments(ast, comments);
// Format it into a code string
var formattedCode = astring.generate(ast, {
	indent: '   ',
	lineEnd: '\n',
	comments: true,
});
// Check it
console.log(code === formattedCode ? 'It works !' : 'Something went wrong…');

Extending

Astring can easily be extended by updating or passing a custom code generator. A code generator consists of a mapping of node names and functions that take two arguments: node and state. The node points to the node from which to generate the code and the state exposes the write method that takes generated code strings.

This example shows how to support the await keyword which is part of the asynchronous functions proposal. The corresponding AwaitExpression node is based on this suggested definition.

// Make sure the astring module is imported and that `Object.assign` is defined
// Create a custom generator that inherits from Astring's base generator
var customGenerator = Object.assign({}, astring.baseGenerator, {
	AwaitExpression: function(node, state) {
		state.write('await ');
		var argument = node.argument;
		if (argument != null) {
			this[argument.type](argument, state);
		}
	}
});
// Obtain a custom AST somehow (note that this AST is not obtained from a valid code)
var ast = {
	type: "AwaitExpression",
	argument: {
		type: "CallExpression",
		callee: {
			type: "Identifier",
			name: "callable",
		},
		arguments: [],
	},
};
// Format it
var code = astring.generate(ast, {
	generator: customGenerator,
});
// Check it
console.log(code === 'await callable();\n' ? 'It works!' : 'Something went wrong…');

Command line interface

The bin/astring utility can be used to convert a JSON-formatted ESTree compliant AST of a JavaScript code. It accepts the following arguments:

  • -i, --indent: string to use as indentation (defaults to "\t")
  • -l, --line-end: string to use for line endings (defaults to "\n")
  • -s, --starting-indent-level: indent level to start from (defaults to 0)
  • -h, --help: print a usage message and exit
  • -v, --version: print package version and exit

The utility reads the AST from a provided list of files or from stdin if none is supplied and prints the generated code.

Example

As in the previous example, these examples use Acorn to get the JSON-formatted AST. This command pipes the AST output by Acorn from a script.js file to Astring and writes the formatted JavaScript code into a result.js file:

cat script.js | acorn --ecma6 | astring --indent "  " > result.js

This command does the same, but reads the AST from an intermediary file:

acorn --ecma6 script.js > ast.json
astring --indent "  " ast.json > result.js

This command reads JavaScript 6 code from stdin and outputs a prettified version:

cat | acorn --ecma6 | astring --indent "  "

Building

All building scripts are defined in the package.json file. All commands must be run from within the root repository folder.

Production

The source code of Astring is written in JavaScript 6 and located at src/astring.js. It is compiled down to a JavaScript 5 file located at dist/astring.js, with its source map at dist/astring.js.map using Babel. This is achieved by running:

npm run build

If you are already using a JavaScript 6 to 5 compiler for your project, or a JavaScript 6 compliant interpreter, you can include the src/astring.js file directly.

A minified version of Astring located at dist/astring.min.js along with its source map at dist/astring.min.js.map can be generated by running:

npm run build-minified

Development

If you are working on Astring, you can enable Babel's watch mode to automatically generate dist/astring.js and dist/astring.js.map at each update by running:

npm start

Tests

While making changes to Astring, make sure it passes the tests:

npm test

You can also get an HTML report of the coverage:

npm run coverage

You can also run tests on a large array of files:

npm run test-scripts

Benchmark

The benchmark compares Astring against other code generators. These are not included in the dependencies and should be installed first:

Benchmarks can be run with:

npm run benchmark

Code format

Finally, make sure that the code is well formatted:

eslint src/astring.js

Roadmap

Planned features and releases are outlined on the milestones page.

astring's People

Contributors

alexkozy avatar bjornharrtell avatar davidbonnet avatar greenkeeper[bot] avatar motiz88 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.