Skip to content

1. Getting Started

Caio Vaccaro edited this page Apr 14, 2016 · 5 revisions

What we propose

We just have one concern here, the C of traditional MVC, the Angular's Service or Redux Reducer. They usually holds the Business Logic of your application -- what distinguish your product from others. Frameworks do have their role, and makes view rendering and model sincronization a lot easier. It would just be even easier for us if the Business Logic could be decoupled from tools and easily migrated when needed. So, use any framework or library you want, but keep your core code agnostic.

First, you should separate "framework-code" from "application-code". Frameworks should deal with HTTP requests, view/templaing/virtual-dom rendering, data synchronization and/or database integration if needed. Application should be just functions, pure functions in the best case scenario. Let's see an example.

Structure

/client  
    /lunar  
    /angular

The lunar folder

/lunar
	/folder-by-feature
	/eg-home
	/simulator
  • Your files will host all functions related to a specific feature.
  • Additionally, each feature have a set of public actions.
  • If writting tests, add your .spec file in there too.
/lunar/home
	home.js
	home.spec.js
	actions.js

The feature main file

You can divide this file into multiple modules as needed, but all functionalities should come into one file at the end.

Your file will look something like this:

// Import your actions constant file
import Lunar from 'lunarjs';
import actions from './actions';

// Your core feature code, an object with pure functions
export default Lunar({
	// You can have private properties if you want
	title: 'Lunar',
	actions: actions,
	[actions.FORMAT_TITLE]: function(data) {
		return data + ' ' + this.title;
	},
	[actions.INCREMENT]: function(data) {
		return ++data;
	},
	[actions.DECREMENT]: function(data) {
		return --data;
	}
}).createModule();

The actions file

Refactors happen all the time. In order to change your code in just one place we use actions constants that will set and get functions for you. All public functions from the application that you want the framework to be able to access should have an action:

export default {
	FORMAT_TITLE: 'FORMAT_TITLE',
	INCREMENT: 'INCREMENT',
	DECREMENT: 'DECREMENT'
};

React Example

We know that React concerns only the V (sort of) of our apps. After you create an Lunar module, you should have an endpoint where you call it. This can be the Component it self.

import React from 'react';
import Lunar from 'lunarjs';
import Home from './lunar/home';

class Title extends React.Component {
    constructor() {
        super();
        this.state = { title: '' }
    }
    componentDidMount() {
        Lunar(this).createActivator([Home]);

        this.request[Home.actions.FORMAT_TITLE]('Welcome')
            .then((data) => {
                this.setState({ title: data });
            }, (err) => {
                console.log('Error: ', err);
            }
         );
    }
    render() {
        return (
            React.createElement('h1', null, this.state.title)
        );
    }
}