Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

rocket-translator

davidsdevel42MIT2.2.0

Translate your HTML files to React.js and Vue.js

vue, react, translator, html translator

readme

Rocket Translator npm version

Translate HTML code to Vue, React or Angular.

Instalation

To install simply: Use npm

npm i -g rocket-translator

or Yarn

yarn global add rocket-translator

Getting Started

Basic

You can convert this:

<div>Hello {name - state - "World"}!</div>

into this:

import React, {Component} from "react";

class MyComponent extends Component {
    constructor() {
        super();
        this.state = {
            name:"World"
        };
    }
    render(){
        return(
            <div>Hello {this.state.name}!</div>
        )
    }
}
export default MyComponent;

or this:

<template>
    <div>Hello {{name}}!</div>
</template>
<script>
    export default {
        name:"MyComponent",
        data(){
            return {
                name:"World"
            }
        }
    }
</script>

Or this:

import { Component } from '@angular/core';

@Component({
    selector: 'test-root',
    template:`<div>Hello {{name}}!</div>`
})

export class Test {
    name = "World";   
}

How to Use

To use, simpy create a HTML file, with the code to translate, and run:

rocket [mode] path/to/file.html [output folder]

The mode may be vue, react or angular.

The output folder is optional, if this is not defined will create a folder named dist.

Guide

States Simple

A State in a Vue or React component, are a way to set data that affect the view, and when this changes, the component re-render the view.

To get values from the HTML, we must declare into {}. And to the declare a state, we have 2 modes to set it: Simple, With Value.

The Simple mode, is declared writing only the state name into the template and writing the type: state.

Example:

<div>{myState - state}</div>

In the With Value mode, is declared when, we write the state name, the type: state and the value for this state.

Example:

<div>{stateName - state - "Some Value"}</div>

The value may be String, Number, Boolean,Array and Object.

And in the simple case, we obtain the next component state.

In Vue:

data(){
    return {
        myState:""
    }
}

In React we obtain:

this.state = {
    myState:""
}

And in Angular:

export class Test {
    myState = "";   
}

In the With value case we obtain. In Vue:

data() {
    return {
        stateName:"Some Value"
    }
}

On React:

this.state = {
    stateName:"Some Value"
}

And on Angular:

export class Test {
    stateName = "Some Value";   
}

Since version 2.0.0 you can add a prop in a bind attribute with the same format that in the bars expression stateName - state;

Example:

<div>
    <span :class="className - state">Hello World!!!</span>
</div>
<script>
    function setInitialState() {
        return {
            className: "foo"
        }
    }
</script>

Or you can add the value next the state word.

<div>
    <span :class="className - state - 'foo'">Hello World!!!</span>
</div>

To know more about states and JavaScript Management. You can see JavaScript Management section.

Props

The props in a component, are data that a parent (container) component pass to a child component.

And like the state, we may declare a prop with this format {propName - prop}.

Example:

<div>{parentData - prop}</div>

And declaring a prop, the final template will render, in Vue:

props:{
    parentData:{
        type:String,
        required:true,
        default:"Hello World"
    }
}

And in React, auto declares the prop.

return(
    <div>{this.props.parentData}</div>
)

And on Angular, Import Input from "@angular/core" and declare as prop.

import { Component, Input} from '@angular/core';

...

export class Test {
    @Input() parentData : string;   
}

Since version 2.0.0 you can add a prop in a bind attribute with the same format that in the bars expression propName - prop;

Example:

<span :class="externalState - prop">Hello World</span>

Computed

A Computed propierty is a function that return a String or Number value, and this is render on the template. And to declare a computed propierty, simply we can set the computed propierty name and the type: computed and create the function to execute that match with the computed name.

<div>{hello - computed}</div>
function hello() {
    return "Hello World";
}

This will create a computed properties that returns a Hello World.

Example:

<div>Hi I Am {fullName - computed}!</div>
<script>
function fullName() {
    var name = "Foo";
    var lastName = "Bar";

    return name + " " + lastName;
}
</script>

Too know more about JavaScript Management go to JavaScript Management section.

Methods

A Method is a function executed by an event on the final render or by the render. Is not necesary declare the method only set the event into the tag.

<button onclick="hello()">Say Hello</button>
<script>
function hello() {
    alert("Hello World");
}
</script>

Since Version 2.1.0 you can use async funtions.

<div>
    <div>{data - state}</div>
    <button onclick="fetchData()">Fetch Data</button>
</div>
<script>
    function setInitialState() {
        return {
            data: ""
        }
    }
    async function fetchData() {
        try {
            const req = await fetch("http://someurl/data");
            const fetched = await req.json();
            data = fetched;
        }
        catch(err) {
            console.log(err);
        }
    }
</script>

Components (Partial)

To import a component inside the main component. Only add the tag with the component syntax.

<MyComponent />

And to add a attr with a state value add : on the attr front.

<MyComponent :my-bind-attr="stateName" />

To write the component content, add a component tag with the component content. And add the attr component-name with the component name. And others attrs can be passed to the component.

<component component-name="HelloWorldComponent" name="World">
    <div>
        <h1>Hello {name - prop}!</h1>
    </div>
</component>

State Watchers

To define a State Watcher you must create the function setStateWatchers this function must return all the states watchers.

function setStateWatchers() {
    return {
        state(e) {
            //Handle State
        },
        anotherState: function(e) {
            //Handle Another State
        }
    }
}

Also you can define as a var, let or const.

const setStateWatchers = () => {
    return {
        //Watchers
    }
}

Inputs Handler

To handle a input, you must add the attr name on the input tag, and the value will be take to add a state with that name.

<input type="text" name="username" />

On Vue will render.

<template>
    <input type="text" v-model="username" name="username"/>
</template>
<script>
    export default {
        name:"MyComponent",
        data() {
            return {
                username:""
            }
        }
    }
</script>

On React.

import React, {Component} from "react";

class MyComponent extends Component {
    constructor() {
        super();
        this.state = {
            username:""
        }
    }
    inputHandler({target}){
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        this.setState({
            [name]: value
        })
    }
}

Do not implement on Angular. We will add this features in futures versions.

Conditionals

To declare a conditional, add the if tag, with the cond attr, where cond is the condition to evaluate.

Example:

<if cond="auth">
    <span>Congratulations! you are Sign in this platform</span>
</if>

And you can set it with an else tag.

<if cond="password.length < 6">
    <span>Password must have more of 6 characters</span>
</if>
<else>
    <span>Password is very strong</span>
</else>

Since version 2.0.0 we add the else-if tag. Like the if tag, this take the attr cond with the condition.

<if cond="age < 18">
    <span>Too Young</span>
</if>
<else-if cond="age > 30">
    <span>Too Old</span>
</else-if>

And now you can add the tag attribute to set conditional tag name.

Example:

<div>
    <if cond="auth === true" tag="span">
        I must buy {item}
    </if>
</div>

The for tag now will be a li tag.

Vue

<ul>
    <li v-for="item in buyList">
        I must buy {{item}}
    </li>
</ul>

Angular

<ul>
    <li *ngFor="let item of buyList">
        I must buy {{item}}
    </li>
</ul>

On React put the content inside the tag.

var loop_0000 = this.state.buyList.map(item => 
        (<li>{item}</li>)
    );

The default tag on Vue is the template tag. On React don't have default tag. Put the content without tag. And on Angular the default tag is the div tag.

List Render

Like the conditionals, add a loop is't very easy, add a for tag, with the val attr.

<for val="varName in stateName">
    <span>{varName}</span>
</for>

And since the version 2.0.0 you can add the tag attribute to define the tag to put the loop content.

Example:

<ul>
    <for val="item in buyList" tag="li">
        I must buy {item}
    </for>
</ul>

The for tag now will be a li tag.

Vue

<ul>
    <li v-for="item in buyList">
        I must buy {{item}}
    </li>
</ul>

Angular

<ul>
    <li *ngFor="let item of buyList">
        I must buy {{item}}
    </li>
</ul>

On React put the content inside the tag.

var loop_0000 = this.state.buyList.map(item => 
        (<li>{item}</li>)
    );

The default tag on Vue is the template tag. On React don't have default tag. Put the content without tag. And on Angular the default tag is the div tag.

Bind Attributes

A Bind Attribute is a form to set a state value on a tag attribute. And the syntax is like on Vue.

If you want add a default value you must add a - followed of the type.

<button :class="classButton - state">Do Click</button>

The type can be state or prop.

And with the type state you can add the String value next state word.

<button :class="classButton - state - 'bar'">Do Click</button>

JavaScript Management

To the JavaScript Management, we add a few of keywords to help with the code imports. We must follow some rules to the correctly function of the translator.

To include JavaScript on the template, add a script tag with the JavaScript code to translate. Or you can add the line #js path/to/js.js to import a external file.

Lifecycles

Since version 2.0.0 we add supports for framework lifecycle; and like methods and computed, all lifecycles will be filtered.

We add 8 lifecycles to define the final component.

  • setInitialState
  • setStateWatchers
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmount
  • unmounted
Set Initial States

setInitialState have the same function that the state keyword in previous versions, this define states that will not be rendered on template.

Example:

<div>
    <span>Hi I Am: {fullName - computed}</span>
</div>
<script>
    function setInitialState() {
        return {
            name: "Foo",
            lastName: "Bar"
        }
    }
    function fullName() {
        return `${name} ${lastName}`;
    }
</script>
Set State Watchers

setStateWatchers have the same function that the watch keyword in previous versions, this define all the states watchers.

Example:

<div>
    <span>You have do {clicks - state - 0} clicks</span>
    <button onclick="countClick()">Do Click</button>
</div>
<script>
    function setStateWatchers() {
        return {
            clicks(clicksNumber) {
                if (clicksNumber > 10) {
                    alert("You do more than 10 clicks");
                }
            }
        }
    }
    function countClick() {
        clicks++;
    }
</script>

Functions

The Functions are to change the method and computed properties execution. If the method or computed name match with the function name, this will be that method or computed.

<div>
    <span>This is my {computedPropierty - computed} propierty</span>
    <button onclick="sayHello()">Say Hello</button>
</div>
<script>
    function computedPropierty() {
        return "Computed"
    }

    function sayHello() {
        alert("Hello World");
    }
</script>

Filter

The JavaScript Filter is structured to filter the states and props. If into the code we have a function that contain a var with the state or prop name, this will be replaced automaticaly. Is not necesary declare like a state.

function setInitialState() {
    return {
        name: "Hello",
        lastName: "World"
    }
}

function sayHello() {
    alert(name + " " + lastName);
    /* 
        will return on React: alert(this.state.name + " " + this.state.lastName);
        and on Vue: alert(this.name + " " + this.lastName);
    */
} 

Note: You must evite use vars with state names, until we fix this.

HTML Syntax

Like on JavaScript, on HTML we have a specific syntax, that we must follow to the correctly translator function.

Bars Declaration

The most used is the bars declaration {}, this is used to assign a state, prop, computed or the out framework syntax.

Framework Declarative Syntax: { name }

State without value: {stateName - state}

State With Value: {stateName - state - value} The value can be type: String, Number, Boolean, Array, Object, null, undefined, NaN or Infinity.

Prop: {propName - prop}

Computed Propierty: {computedName - computed}

Import Tag

To import a JavaScript external file, we use: #js path/to/js.js.

Note: We want add CSS Support.

Bind Attributes

To execute JavaScript syntax or assign a state or prop value on an HTML attribute, we use :attrName="Js or State".

Conditionals And Loops Tags

We add three HTML tags to assign Conditionals and Loops. if, else-if, else and for.

<if cond="condToEvaluate">
    <span>If Content</span>
</if>
<else-if cond="condToEvaluate">
    <span>Else If Content</span>
</else-if>
<else>
    <span>Else Content</span>
</else>
<for val="varName in stateName">
    <span>For Content</span>
</for>

Component Tag

We add this tag to declare a custom component inside the Main Component

<component component-name="ComponentName">
    <span>Component Content</span>
</component>

CLI

CLI use is simple: rocket [mode] <input-file> <output-folder>

mode will be the target framework: React, Vue or Angular. input-file will be the HTML component filepath. output-folder is optional. Will be the folder path. If is not defined, create a folder named dist.

Options

--ignore-input-name

Option --ignore-input-name, is used to evite that the filter, parse the name attribute on input, select or textarea tags.

See a React Example Without --ignore-input-name:

render() {
    return (
        <div>
            <input onChange={this.inputHandler} type="text" name="username"/>
            <input onChange={this.inputHandler} type="password" name="password"/>
        </div>
    )
}

With --ignore-input-name:

render() {
    return (
        <div>
            <input type="text" name="username"/>
            <input type="password" name="password"/>
        </div>
    )
}
--jsx

Option --jsx is used to compile Vue and React as JSX, without this, Vue will be compiled as HTML and React with React.createElement

--allow-ssr

Option --allow-ssr compile frameworks as Server Side Render-Frameworks, Next to React, Nuxt to Vue. With this a tags will be converted on Link or nuxt-link and can add, getInitialProps and asyncData methods.

Note: Angular SSR are not currently supported

To Do

Features Support

  • <input checked="" disabled="" type="checkbox"> States
  • <input checked="" disabled="" type="checkbox"> Methods
  • <input checked="" disabled="" type="checkbox"> Computed
  • <input checked="" disabled="" type="checkbox"> Props
  • <input checked="" disabled="" type="checkbox"> States Watchers
  • <input checked="" disabled="" type="checkbox"> Components
  • <input checked="" disabled="" type="checkbox"> Bind States, Props, JS Expresions
  • <input checked="" disabled="" type="checkbox"> Input Handlers
  • <input checked="" disabled="" type="checkbox"> JavaScript Management (partial)
  • <input checked="" disabled="" type="checkbox"> Conditionals
  • <input checked="" disabled="" type="checkbox"> Nested Conditionals
  • <input checked="" disabled="" type="checkbox"> Loops
  • <input checked="" disabled="" type="checkbox"> Nested Loops
  • <input disabled="" type="checkbox"> Inner HTML
  • <input checked="" disabled="" type="checkbox"> Lifecycles
  • <input disabled="" type="checkbox"> React without JSX
  • <input disabled="" type="checkbox"> React without ES6
  • <input disabled="" type="checkbox"> Vue Standalone
  • <input checked="" disabled="" type="checkbox"> Vue With JSX
  • <input disabled="" type="checkbox"> Next Framework
  • <input checked="" disabled="" type="checkbox"> Angular 7 Support
  • <input disabled="" type="checkbox"> Previous Angular Versions
  • <input disabled="" type="checkbox"> Compiler Directives

Note: If you see that some feature is missing, you can open a pull request or write an issue, and tell what feature is missing.

Contributing

To contribute you can open a pull request with the changes to improve in the code, or open a new issue.

changelog

Version 2

2.2.0

JSX

Added support for JSX in Vue, and upgraded JSX generating method.

Updated CLI Interface

Updated Help Message, and added --jsx option, to build with JSX format.

Nested Conditionals and Loops

Added support to Nested conditionals and Loops.

States and Props Globals

Use RocketStates or RocketProps to get data if have a var with the same name

Example: We define the state name,

function setInitialState() {
    return {
        name: "Foo"
    }
}

function HelloWorld() {
    var name = "World";
    alert(`Hello ${name}`); //Will render: "Hello World"

    alert(`Hello ${RocketStates.name}`); //Will render: "Hello Foo"
}

function HelloFoo() {
    alert(`Hello ${name}`); //Will render: "Hello Foo"
}

2.1.1

Fixed Props Parser

Fixed Props Parser on Bind Attributes with Single Quotes

Improve Error Message

Error messages now will be agrouped by type.

2.1.0

Show All Errors

Now you can show all errors at the same time on CLI, to save many time.

Some Fixes Solved

Fixed React HTML Filter and Vue HTML filter, and Javascript Filter. And Fixed HTML Filter Error on parsed Methods and Computeds

Updated CLI Interface

Reformated Help Message, and added --ignore-input-name option, to evite parse name attributes on input, select, and textarea tags.

Normaly when we exec rocket vue my-component.html or rocket react my-component.html, the final component will parse name attribute.

<div>
    <input type="text" name="username">
    <input type="password" name="password">
</div>
<script>
    function setInitialState() {
        return {
            username: "",
            password: ""
        }
    }
</script>

Vue:

<template>
    <div>
        <input v-model="username" type="text" name="username">
        <input v-model="password" type="password" name="password">
    </div>
</template>
<script>
    export default {
        name: "MyComponent",
        data() {
            return {
                username: "",
                password: ""
            }
        }
    }
</script>

React:

import React, {Component} from "react";

class MyComponent extends Component {
    constructor() {
        super();
        this.state = {
            username: "",
            password: ""
        }
        this.handleInput = this.handleInput.bind(this);
    }
    inputHandler({target}){
        let {name, type} = target;
        let value = type === 'checkbox' ? target.checked : target.value;
        this.setState({
            [name]: value
        });
    }
    render() {
        return (
            <div>
                <input onChange={this.inputHandler} type="text" name="username"/>
                <input onChange={this.inputHandler} type="password" name="password"/>
            </div>
        )
    }
}

But, if we exec the same with --ignore-input-name flag. We optain:

Vue:

<template>
    <div>
        <input type="text" name="username">
        <input type="password" name="password">
    </div>
</template>
<script>
    export default {
        name: "MyComponent",
        data() {
            return {
                username: "",
                password: ""
            }
        }
    }
</script>

React:

import React, {Component} from "react";

class MyComponent extends Component {
    constructor() {
        super();
        this.state = {
            username: "",
            password: ""
        }
    }
    render() {
        return (
            <div>
                <input type="text" name="username"/>
                <input type="password" name="password"/>
            </div>
        )
    }
}
export default MyComponent;

Added Async Functions Support

Now we can declare a async function in Rocket Translator.

<div>
    <div>{data - state}</div>
    <button onclick="fetchData()">Fetch Data</button>
</div>
<script>
    function setInitialState() {
        return {
            data: ""
        }
    }
    async function fetchData() {
        try {
            const req = await fetch("http://someurl/data");
            const fetched = await req.json();
            data = fetched;
        }
        catch(err) {
            console.log(err);
        }
    }
</script>
import React, {Component} from "react";

class Test extends Component {
    constructor() {
        super();
        this.state = {
            data: ""
        };
        this.fetchData = this.fetchData.bind(this);
    }
    async fetchData(){
        try {
            const req = await fetch("http://someurl");
            const fetched = await req.json();
            this.setState({data: fetched});
        } catch (err) {
            console.log(err);
        }
    }
    render(){
        return(
            <div>
                <div>{this.state.data}</div>
                <button onClick={this.fetchData}>Fetch Data</button>
            </div>
        )
    }
}
export default Test;

Optimized with Webpack

Rocket Translator, now will be compiled with webpack to improve the performance, size, and speed. And minimize dependencies.

Fixed Same State Assignament on Javascript and HTML.

If a state is defined on Javascript and on HTML is defined without value, this don't assign the value.

<div>
    <span>Hello {name - state}</span>
</div>
<script>
    function setInitialState() {
        return {
            name: "World"
        }
    }
</script>

Final State.

{
    name: ""
}

Now if we define the same state on JS and HTML, is both have value, show an Error, if in HTML don't have a value, the value will be the defined on JS.

2.0.3

Updated CLI Help Message

Updated help message that was show [vue or react] and was changed with [mode].

2.0.2

Fix CLI Error

Fixed Error: Unable to start the CLI when we execute rocket command.

2.0.1

Fix "exports." on internal function vars.

When the take the data, create a temp file that contains the data setted in the html script tag. And replace the var, let and const with exports. that the module can export these vars.

Added "tag" for "if", "else-if" and "else" tags

Now you can add the tag attribute to set the tag to put the conditional content.

2.0.0

Added Angular Support!!!

This was be the most awaited feature in the project. We start with Angular 7, and in future versions we will add previous angular versions. Remember help with issues and pull request.

Some Fix

Fixed the State assignament on react and all states that has be changed, will be filtered as this.setState;

Fixed Quotes on Vue Filter.

Fixed the "Missing Var" Error.

Fixed the bind attribute value assignament.

Added the "tag" attribute for the "for" tag

Now you can add the tag attribute to set the tag to put the loop content.

Example:

<ul>
    <for val="item in buyList" tag="li">
        I must buy {item}
    </for>
</ul>

The for tag now will be a li tag.

<ul>
    <li v-for="item in buyList">
        I must buy {{item}}
    </li>
</ul>

On React put the content inside the tag.

var loop_0000 = this.state.buyList.map(item => 
        (<li>{item}</li>)
    );

The default tag on Vue is the template tag. On React don't have default tag. Put the content without tag. And on Angular the default tag is the div tag.

Added Else If Support

Now you can use the else-if tag, like the if tag, this have must have the cond attribute to define the condition.

<if cond="condition">
    <span>Content</span>
</if>
<else-if cond="secondCondition">
    <span>Content</span>
</else-if>

Define Functions Mode

Now you can define all functions, (methods, computed, lifecycles), as a function or as a var.

Example:

function sayHello() {
    alert("Hello World");
}
//Is't the same as
const sayHello = () => {
    alert("Hello World");
}

Lifecycles

Was added a lifecycle supports for all components, we add 6 framework lifecycle and 2 that help to define states and watchers.

  • setInitialState
  • setStateWatchers
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmount
  • unmounted

To set it create a function named with the lifecycle name, and this will be setted on the component.

Example:

function setInitialState() {
    return {
        name:""
    }
}
function mounted() {
    name = "Hello World";
}

Keywords

We change the state keyword with the function setInitialState, that must return all component's states

On version 1, we define a state like this:

state name = "Foo";
state lastName = "Bar";

Since version 2, will be defined:

function setInitialState() {
    return {
        name:"Foo",
        lastName:"Bar"
    }
}

And we change the watch keyword with the function setStateWatchers, that must return the watchers.

On version 1, we define a state like this:

watch clicks = e => {
    if (e > 10) {
        alert("You do more than 10 clicks");
    }
}

Since version 2, will be defined:

function setStateWatchers() {
    return {
        clicks(e) {
            if (e > 10) {
                alert("You do more than 10 clicks");
            }
        }
    }
}