node package manager
Easy sharing. Manage teams and permissions with one click. Create a free org »

invisible-framework

The Invisible Framework

The best way to get started with the Invisible Framework is by trying out the demo application.

Introduction

The Invisible Framework and its cli (command line interface) are designed to get you from empty directory to production environment in a matter of seconds.

This documentation will guide you through the creation, testing, and deployment of a new Invisible Framework application.

The Invisible Framework requires Node.js v6+ and NPM v3+.

Installation and Setup

In this step, you'll start with an empty directory, then create the basic files required for an Invisible Framework application. You'll only need your terminal.

  1. From a starting location of your choosing, create a new project directory: mkdir my-project && cd my-project
  2. Initialize a Git repository: git init
  3. Initialize an NPM repository: npm init -y
  4. Install the Invisible Framework cli: npm i -S invisible-framework

When the installation completes, take a look at the contents of your project directory. You should see the standard node_modules directory, and you should see a few files that the Invisible Framework has generated for you: .editorconfig, .eslintrc, and .gitignore. These files represent the basic project configuration for Babel, ESLint, Git, and your editor.

Environment Configuration

A special environment configuration file named config.js is also created.

When created for the first time, config.js will contain default values for all of the Invisible Framework's configurable properties. The Invisible Framework is also capable of adding more configurable properties as they become available, and will non-destructively patch the local config.js file as needed.

Now that the Invisible Framework is configured, it's time to build your application.

Building the Client

With the Invisible Framework configured, let's start adding some UI code. In this tutorial, you'll need your terminal and a text editor.

  1. Start by creating a client directory at the root of your project: mkdir client. The Invisible Framework expects your UI code to live in this directory.
  2. Create the only required file, index.js, which is the JavaScript entry point for your application: touch client/index.js

Before we modify client/index.js, let's start the webpack dev server and Express API server. From your terminal, run: npm start.

NOTE: If you haven't already, take a moment to look at your project's package.json file. The Invisible Framework has automatically added its commands to your npm scripts.

With your webpack and Express servers running, let's open up the default application URL in your browser. Open a browser and navigate to http://localhost:3325. Behold the blank screen.

Now, using your editor, open client/index.js and add the following code:

console.log('I am alive');

Save client/index.js, then go back to your browser. You should see your logged message in the browser developer tools console. Congratulations! You just created a web application!

All files in the client directory are processed by Babel via webpack, and supports ES6 (including modules), JSX, CSS, JSON, images, and fonts. The Invisible Framework doesn't care how you structure your files and folders within the client directory. The only required file is your entry point: client/index.js.

See the the Invisible Framework demo project for more information.

Building the Server

Now that you have a world-class UI, let's talk APIs.

The Invisible Framework uses both webpack-dev-server and Express.js during development. The Express.js server is also used in production mode to handle the serving and caching of static assets, and to handle your local API.

The following Express middleware is pre-configured: morgan, compression, body-parser, helmet, and express-validator.

API Configuration

The Invisible Framework provides two API configuration options:

  1. A proxy API endpoint, located at /proxy, which will proxy all requests to a remote server of your choosing
  2. A local API endpoint, located at /api, which is handled by the local Express server

This configuration provides flexibility, and allows you to make cross-origin requests to a remote API of your choosing, develop your own local API, or use a combination of the two.

For example, one might point the API proxy to https://some-web-service.com, so a call to /proxy/users would resolve to https://some-web-service.com/users.

You may also decide to create a new API independent of the API proxy, with a call to /api/reports/dashboard resolving to the local Express server, and being handled by your custom route handler.

Let's do both.

Take a look at your .env file. Notice that the "REMOTE_API" key is set to "https://jsonplaceholder.typicode.com". This is our proxy endpoint. We can modify this value to suit our needs, but for demo purposes, we'll leave the default value.

The JSONPlaceholder service provides a mock API for testing purposes, and one of its endpoints is https://jsonplaceholder.typicode.com/posts, which returns a list of sample posts. Let's add some UI code to see if a call to /proxy/posts returns the same thing.

Using your editor, open client/index.js and replace its contents with the following code:

fetch('/proxy/posts')
.then(response => {
  response.json()
  .then(json => {
    console.log('I fetched data from my proxy API!');
    console.log(json);
  });
});

Save client/index.js, then go back to your browser, open the browser's developer tools to the "Console" view, and refresh the page. You should see your log message and a list of post objects returned from the JSONPlaceholder API.

Congratulations! Without any additional server-side work, you've established a connection to a remote API. No CORS to worry about, and any call that can be made to the remote API can be made to your /proxy endpoint.

Now, let's create our own API.

NOTE: If the npm start process is still running, stop it using ctrl+c.

Using the terminal, create a server directory, and a server/index.js file: mkdir server && touch server/index.js.

Using your editor, open server/index.js and add the following code:

const router = require('express').Router;
 
// Create a new router 
const rootRouter = router();
 
// Handle GET requests to the /test path 
rootRouter.get('/test', (req, res) => {
  const json = { name: 'Local API Test', passed: true };
 
  res.json(json);
});
 
module.exports = rootRouter;

Save server/index.js, then go back to your terminal and run npm start. Go back to your browser and refresh the page. Your application should be running.

Now, let's add another fetch to our UI to test our local API.

Using your editor, open client/index.js and add the following code:

fetch('/api/test')
.then(response => {
  response.json()
  .then(json => {
    console.log(json);
  });
});

Save client/index.js, then go back to your browser, open the browser's developer tools to the "Console" view, and refresh the page. You should see the response you hard-coded logged in the developer tools console.

Congratulations! With no server configuration or excess boilerplate, you've created a local API endpoint. You're now in complete control of your application's data sources.

NOTE: Just like the client, the server only requires one file: server/index.js. All other files and folders are up to you. Unlike the client, server files are not parsed by Babel, so your syntax is limited only by the version of Node.js that you're running.

See the the Invisible Framework demo project for more information.

Custom Express Middleware

(Documentation in progress)

Tests

One of the Invisible Framework's strengths is how easy it makes writing and running tests.

NOTE: If the npm start process is still running, stop it using ctrl+c.

ESLint

Let's make ESLint do some work. Using your editor, open client/index.js and add the following code:

console.log('unexpected console statement');

Save client/index.js, then go back to your terminal and run: npm test. ESlint should complain, because your code is failing the code style check. Fix the problems and run npm test again, and you should see that ESLint no longer complains.

Unit Tests

The Invisible Framework has support for Mocha, Chai, and Istanbul baked in, and it will find all files named unit.js and execute them.

Let's create a sample test. Using your terminal, create a test file: touch client/unit.js.

Using your editor, open client/unit.js and add the following code:

describe('test', () => {
  it('passes', () => {
    assert.isTrue(true);
  });
 
  it('fails', () => {
    assert.isTrue(false);
  });
});
 

Save client/unit.js, then go back to your terminal and run: npm test. You should see the output of the test results. A coverage directory will also be created, with test coverage reporting provided by Istanbul.

Notice that you didn't need to import describe, it, or assert. Mocha's describe and it, and Chai's assert methods are globally available in all of your tests.

Congratulations! You've created your first unit test without having to worry about any configuration or complex setup.

End-to-end Tests

The Invisible Framework has support for running end-to-end tests using Nightwatch. It will find all files named e2e.js and execute them.

Let's create a sample end-to-end test. Using your terminal, create a test file: touch client/e2e.js.

Using your editor, open client/e2e.js and add the following code:

module.exports = {
  'example e2e test': function(browser) {
    browser
    .url('http://localhost:3325')
    .waitForElementVisible('body', 1000)
    .assert.title('The Invisible Framework')
    .end();
  },
};
 

Save client/e2e.js, then go back to your terminal and run: npm run e2e. You should see the output of the test results. A reports directory will also be created, which contains test results generated by Nightwatch.

Congratulations! You've created your first end-to-end test. Just like with your unit test, you didn't have to spend any time settings up tools and configuration files.

Production

While the Invisible Framework does a lot to optimize the development experience, it also does a lot of heavy lifting to make deployment a breeze.

To run a local production build, just run npm run prod. This will use webpack to produce a directory of optimized static assets, and will run your Express.js server in production mode.

The Invisible Framework also supports deployment via Docker, and you can produce a Dockerfile and .dockerignore file by running: npm run docker.

From there you can build and run the docker container as usual. For example:

docker build -t my-app .
docker run -p 3325:3325 -d my-app