Frontend app

We will create a very simple React webapp with Redux and using ArtemisaJS for fetching the list of users from the backend.

mkdir frontend
yarn init -y

yarn add react redux artemisa

yarn add -D babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0 babel-plugin-transform-runtime
 webpack

Also create a .babelrc file

{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}

Now a script to build, edit package.json and under scripts section add

  "scripts": {
    "build": "webpack --debug"
  },

Now lets create a new file for webpack

vi webpack.config.js

With content

module.exports = {
  entry: './src/app.jsx',
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: { presets: [ 'es2015', 'react' ] }
      }
    ]
  }
};

And now lets create the app.jsx file:

mkdir src
touch src/app.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux';
import { Provider } from 'react-redux';

const store = createStore((state={}, action) => state)

ReactDOM.render(
    <Provider store={store}>
    </Provider>,
    document.querySelector("#app"))

And create an index.html file

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <title>E2E testing with Docker</title>
</head>
<body>
<div id="app"></div>

<script src="bundle.js"></script>

</body>
</html>

Now lets build

yarn build

And open the index.html file with a browser

Let's now add a component to show the users

makdir src/components
touch src/components/UsersList.jsx
import React from 'react'
import { isFetchedSlot, isFetching, fetchingData } from 'artemisa'
import { get } from 'artemisa/lib/core/call'

class UsersList extends React.Component {

  render() {
    const { users } = this.props
    return (
      <table className="table table-striped">
        <thead><tr><th>Id</th><th>Name</th><th>Created</th></tr></thead>
        <tbody>
          {isFetchedSlot(users) && (
            users.value.map(u => (
              <tr>
                <td>{u._id}</td>
                <td>{u.name}</td>
                <td>{u.created_at}</td>
              </tr>
            ))
          )}
        </tbody>
      </table>
    )
  }
}

export default fetchingData({
  users: () => get('api/users')
})(UsersList)

Now we need to configure artemisa that is the library that makes it easier to call the backend to fetch data. Edit *app.jsx so that we include artemisa resolver and middleware

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { Provider } from 'react-redux';
import { service as artemisaMiddleware, reducer as artemisa } from 'artemisa'

import UsersList from './components/UsersList'

const store = createStore(combineReducers({ artemisa }), compose(
  applyMiddleware(thunkMiddleware, artemisaMiddleware),
  window.devToolsExtension ? window.devToolsExtension() : f => f
))

ReactDOM.render(
    <Provider store={store}>
      <div>
        <h1>E2E testing with Docker</h1>
        <div>
          <h2>Users</h2>
          <UsersList />
        </div>
      </div>
    </Provider>,
    document.querySelector("#app"))

And now we will configure webpack-dev-server so that it proxies are resquests to localhost/api to the back end

yarn add -D webpack-dev-server

Then edit webpack.config.js


const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: './src/app.jsx',
  resolve: {
    modules: [path.resolve(__dirname, "src"), "node_modules"],
    extensions: ['.js', '.jsx', '.json']
  },
  output: {
    path: `${__dirname}/build`,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: { presets: [ 'es2015', 'react' ] }
      }
    ]
  },
  plugins: [
    new webpack.DefinePlugin({
      __IS_BROWSER__: true,
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
    })
  ],
  devServer: {
    contentBase: 'public/',
    proxy: {
      '/api': {
        target: 'http://localhost:3001/',
        pathRewrite: { '^/api': '' }
      }
    }
  }
};

(we also added the IS BROWSER Env)

And we will reorganize the index.html file

mkdir public
mv index.html public

And add a script to start the server in package.json's scripts section

"start": "webpack-dev-server --history-api-fallback --progress --host 0.0.0.0 --port 3000 --inline --hot --config webpack.config.js --quiet"

This will start in port 3000, so we would need to change the backend to start on another port, let say 3001. In the backend code project edit bin/www changing this line

var port = normalizePort(process.env.PORT || '3001');

(Notice the part has changed to 3001)

Now let start both of them.

yarn start

You should see something like this

That's all !

We now have a backend that serves a list of users, and a front end that consumes that API to fetch users.

< Back | Next >

results matching ""

    No results matching ""