andreformento / vue-project

Front end project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Frontend Starter Kit

🍦 A boilerplate for HTML5, Material, Firebase, Parcel, Babel, PostHTML, and PostCSS.

Build Status Coverage Status // dependencies Status devDependencies Status

Live Demo

This seed repository provides the following features:

  • ---------- Essentials ----------
  • User interface components with Material.
  • Backend cloud services with Firebase.
  • Routing and navigation with Page.
  • Utility functions with Lodash.
  • Reactive extensions with ReactiveX.
  • Scalable state management with MobX.
  • Immutable collections with Immer.
  • Data visualizations with D3.
  • 3D scene graphs with Three.
  • ---------- Tools ----------
  • Module bundler with Parcel.
  • HTML transformations with PostHTML.
  • Future CSS features with PostCSS.
  • Next generation JavaScript with Babel.
  • Synchronised browser with BrowserSync.
  • HTML static code analyzer with HTMLHint.
  • CSS static code analyzer with StyleLint.
  • JavaScript static code analyzer with ESLint.
  • Type annotations with Flow.
  • Testing platform with Jest.
  • UI testing with Puppeteer.
  • Test coverage integration with Codecov.
  • Error tracking with Sentry.
  • ---------- Environments ----------
  • Client-side platform with HTML5.
  • Operating system with Linux.
  • Text editor with Atom.
  • Version control with Git.
  • Code repository with GitHub.
  • Fast and deterministic builds with Yarn.
  • Software container with Docker.
  • Continuous integration with CircleCI.

Here are some related seed repositories:

Table of Contents

Getting Started

  1. Clone this Boilerplate
$ git clone --depth 1 https://github.com/Shyam-Chen/Frontend-Starter-Kit.git <PROJECT_NAME>
$ cd <PROJECT_NAME>
  1. Install Dependencies
$ yarn install

# then install types
$ yarn typed
  1. Run the Application
$ yarn start
# or
$ yarn dev
  1. Run the Test
# unit testing
$ yarn test
# or
$ yarn unit

# lint the code
$ yarn lint

# check the type
$ yarn flow

# e2e testing
$ yarn e2e  # need to run `yarn dev` first

Practical Examples

  • CRUD Operations
    • Static
    • REST (axios)
    • GraphQL (apollo-client)
  • Form Controls
    • Template-driven (mobx)
    • Reactive Forms (rxjs)
  • Data Table
    • Static
    • REST (axios)
    • GraphQL (apollo-client)
  • Globalization
    • Internationalization
    • Localization
  • Authorization
    • REST (axios)
    • GraphQL (apollo-client)
  • Data Chart
    • SVG (d3)
    • Canvas (d3)
    • WebGL (three)
  • Realtime
    • WebSockets (socket.io-client)
    • GraphQL Subscriptions (subscriptions-transport-ws)
  • Playground
    • Counter
      • State Management (mobx)
      • Asynchronous (rxjs)
    • ...

Dockerization

  1. Build and run the Container
$ docker-compose up
  1. Run a command in a running container
$ docker-compose exec app <COMMAND>
  1. Remove the old container before creating the new one
$ docker-compose rm -fs

Configuration

Default configuration

// tools/env.js
export const SITE_URL = process.env.SITE_URL || 'https://web-go-demo.firebaseapp.com';
export const FUNC_URL = process.env.FUNC_URL || 'https://us-central1-web-go-demo.cloudfunctions.net';

export const INDEX_ENV = {
  APP_BASE: process.env.APP_BASE || '/',
  GOOGLE_ANALYTICS: process.env.GOOGLE_ANALYTICS || 'UA-84381641-2'
};

export const APP_ENV = {
  FIREBASE_CONFIG: {
    apiKey: process.env.FIREBASE_KEY || 'AIzaSyDBA0yVS0JuIqGaoN9nafvPFxPSVgmxwnw',
    authDomain: process.env.FIREBASE_DOMAIN || 'web-go-demo.firebaseapp.com',
    databaseURL: process.env.FIREBASE_PROJECT || 'https://web-go-demo.firebaseio.com',
    projectId: process.env.FIREBASE_DATABASE || 'web-go-demo',
    storageBucket: process.env.FIREBASE_STORAGE || 'web-go-demo.appspot.com',
    messagingSenderId: process.env.FIREBASE_MESSAGING || '584431831746'
  },
  SENTRY_URL: process.env.SENTRY_URL || 'https://70484e0dda784a1081081ca9c8237792@sentry.io/236866',
  FUNC_URL
};

export const DEV_PORT = process.env.DEV_PORT || 8000;
export const TEST_PORT = process.env.TEST_PORT || 8080;

export const PROXY_URL = process.env.PROXY_URL || 'http://localhost:3000'

Using Libraries

  1. Example of Component
<!-- src/shared/new-component/new-component.html -->
<div class="<%= style['card'] %>">
  <div class="<%= style['card-title'] %>"><%= title %></div>
  <div class="<%= style['card-content'] %>"><%= content %></div>
</div>

<div class="<%= style['card'] %>">
  <div class="<%= style['card-title'] %> <%= style['card-title--unfancy'] %>"><%= title %></div>
  <div class="<%= style['card-content'] %>"><%= content %></div>
</div>
/* src/shared/new-component/new-component.css */
.card {  // element
  // ...

  &-title {  // element
    // ...

    &--unfancy {  // modifier
      // ...
    }
  }

  &-content {  // element
    // ...
  }
}
// src/shared/new-component/new-component.js
import { template as _ } from 'lodash';

import template from './new-component.html';
import style from './new-component.css';

export const newComponent = (name, data) =>
  document.querySelector(`#${name}`)
    .innerHTML = _(template, { imports: { style } })(data);
// src/shared/new-component/index.js
export * from './new-component';
// use the new component
import { newComponent } from '~/components/new-component';

newComponent('ex-1', { title: 'Title 1', content: 'Content 1' });
newComponent('ex-2', { title: 'Title 2', content: 'Content 2' });
<!-- use the new component -->
<div id="ex-1"></div>
<div id="ex-2"></div>
  1. Example of Route
// src/pages/new-route/new-route.js
import { template as _ } from 'lodash';

import { layout } from '~/components/layout';

export const newRoute = () => {
  page('/ex', () => {
    layout(_(`<p>New Route</p>`)(), 'ex');
  });
};
// src/pages/new-route/index.js
export * from './new-route';
// src/app.js
import { newRoute } from './pages/new-route';

newRoute();
  1. Example of REST
import axios from 'axios';

const API_LIST = 'https://web-go-demo.herokuapp.com/__/list';

axios.get(API_LIST)
  .then(res => console.log(res.data))
  .then(() => console.log('done'));

axios.get(API_LIST, { params: { text: 'a' } })
  .then(res => console.log(res.data))
  .then(() => console.log('done'));

axios.post(API_LIST, { text: 'Web GO' })
  .then(res => console.log(res.data))
  .then(() => console.log('done'));

axios.put(`${API_LIST}/5943881e058f440012d4ae47`, { text: 'Web GO' })
  .then(res => console.log(res.data))
  .then(() => console.log('done'));

axios.delete(`${API_LIST}/594388af058f440012d4ae49`)
  .then(res => console.log(res.data))
  .then(() => console.log('done'));
  1. Example of GraphQL
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import gql from 'graphql-tag';

const client = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: 'https://web-go-demo.herokuapp.com/__/graphql'
  })
});

client
  .query({
    query: gql`
      query List {
        list { _id text }
      }
    `
  })
  .then(res => console.log(res.data));

client
  .query({
    query: gql`
      query List {
        list(text: "a") { _id text }
      }
    `
  })
  .then(res => console.log(res.data));

client
  .mutate({
    mutation: gql`
      mutation List {
        addText(text: "Web GO") { _id text }
      }
    `
  })
  .then(res => console.log(res.data));

client
  .mutate({
    mutation: gql`
      mutation List {
        updateText(_id: "5943881e058f440012d4ae47", text: "Web GO") { _id text }
      }
    `
  })
  .then(res => console.log(res.data));

client
  .mutate({
    mutation: gql`
      mutation List {
        deleteText(_id: "594388af058f440012d4ae49") { _id text }
      }
    `
  })
  .then(res => console.log(res.data));
  1. Example of Socket Client
import io from 'socket.io-client';

const socket = io('wss://web-go-demo.herokuapp.com/');

socket.on('connect', () => console.log('Accept a connection.'));

socket.on('A', data => {
  console.log(data);
  socket.emit('B', { foo: 'baz' });
});
  1. Example of GraphQL Subscriptions
import { SubscriptionClient } from 'subscriptions-transport-ws';
import ApolloClient from 'apollo-client';

const client = new SubscriptionClient(
  'wss://web-go-demo.herokuapp.com/__/graphql',
  { reconnect: true }
);

const apolloClient = new ApolloClient({
  networkInterface: client
});
  1. Example of Lodash
import { lowerFirst, pad } from 'lodash';
import { Observable } from 'rxjs';
import { of } from 'rxjs/observable';

Observable::of(lowerFirst('Hello'), pad('World', 5))
  .subscribe(value => console.log(value));
  // hello
  // World
  1. Example of ReactiveX
import { Observable } from 'rxjs';
import { timer, of } from 'rxjs/observable';
import { mapTo, combineAll } from 'rxjs/operator';

Observable::timer(2000)
  ::mapTo(Observable::of('Hello', 'World'))
  ::combineAll()
  .subscribe(value => console.log(value));
  // ["Hello"]
  // ["World"]
  1. Example of MobX
import { observable, action, autorun } from 'mobx';

const store = observable({
  value: 0,

  increment: action(() => store.value++),
  decrement: action(() => store.value--),
  incrementAsync: action(() => setTimeout(() => store.increment(), 1000)),
  incrementIfOdd: action(() => {
    if (Math.abs(store.value % 2) === 1) {
      store.increment();
    }
  }),

  get evenOrOdd() {
    return store.value % 2 === 0 ? 'even' : 'odd';
  }
});

autorun(() => {
  console.log(store.value, store.evenOrOdd);  // 0, even
  store.increment();  // 0 -> 1
  console.log(store.value, store.evenOrOdd);  // 1, odd
  store.incrementAsync();  // 1 -> 2
  store.incrementAsync();  // 2 -> 3
  console.log(store.value, store.evenOrOdd);  // 3, odd
  store.incrementIfOdd();  // 3 -> 4
  store.incrementIfOdd();  // 4 -> 4
  onsole.log(store.value, store.evenOrOdd);  // 4, even
});
  1. Example of Immer
import produce from 'immer';

const baseState = [
  { label: 'Babel', done: true },
  { label: 'Flow', done: false }
];

const nextState = produce(baseState, draftState => {
  draftState.push({ label: 'TypeScript' });
  draftState[1].done = true;
});

baseState.length;  // 2
nextState.length;  // 3
  1. Example of D3
import { select } from 'd3-selection';

const exWidth = 400;
const exHeight = 200;
const exDataset = [5, 10, 15, 20, 15, 10, 15, 20, 15, 10, 5];

const exSvgEl = select('#ex')
  .append('svg')
  .attr('width', exWidth)
  .attr('height', exHeight);

exSvgEl.selectAll('rect')
  .data(exDataset)
  .enter()
  .append('rect')
  .attr('x', (data, index) => index * (exWidth / exDataset.length))
  .attr('fill', data => `rgba(200, 100, 200, ${data / 25})`)
  .attr('y', data => exHeight - (data * 4))
  .attr('width', exWidth / exDataset.length - 1)
  .attr('height', data => data * 4);
<div id="ex"></div>
  1. Example of Three
import { PerspectiveCamera, Scene, BoxGeometry, MeshBasicMaterial, Mesh, WebGLRenderer } from 'three';

let [camera, scene, renderer, geometry, material, mesh] = [];

const init = () => {
  camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.z = 1000;

  scene = new Scene();

  geometry = new BoxGeometry(200, 200, 200);
  material = new MeshBasicMaterial({ color: 0xff0000, wireframe: true });

  mesh = new Mesh(geometry, material);
  scene.add(mesh);

  renderer = new WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.querySelector('#ex')
    .appendChild(renderer.domElement);
};

const animate = () => {
  requestAnimationFrame(animate);

  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.02;

  renderer.render(scene, camera);
};

init();
animate();
<div id="ex"></div>

Directory Structure

.
β”œβ”€β”€ flow-typed  -> module types
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ assets  -> audios, datas, fonts, images, styles, videos
β”‚   β”œβ”€β”€ pages
β”‚   β”‚   └── <feature>
β”‚   β”‚       β”œβ”€β”€ _languages  -> internationalization
β”‚   β”‚       β”œβ”€β”€ _includes  -> lite components
β”‚   β”‚       β”‚   └── <feature>.html
β”‚   β”‚       β”œβ”€β”€ _components  -> feature components
β”‚   β”‚       β”‚   └── <feature>
β”‚   β”‚       β”‚       β”œβ”€β”€ <feature>.{html,css,js,spec.js}
β”‚   β”‚       β”‚       └── index.js
β”‚   β”‚       β”œβ”€β”€ _<custom> -> private object
β”‚   β”‚       β”œβ”€β”€ <feature>.{html,css,js,spec.js}
β”‚   β”‚       └── index.js
β”‚   β”œβ”€β”€ shared  -> shared components
β”‚   β”œβ”€β”€ utils  -> utility functions
β”‚   β”œβ”€β”€ app.js
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ polyfills.js  -> shims, pre-vendor
β”‚   └── vendor.js  -> third-party libraries
β”œβ”€β”€ test  -> E2E testing
β”œβ”€β”€ tools
β”‚   β”œβ”€β”€ config
β”‚   β”‚   └── {babel,postcss,reshape,rollup}.js
β”‚   β”œβ”€β”€ rules
β”‚   β”‚   └── database.json,storage
β”‚   β”œβ”€β”€ tasks
β”‚   β”‚   └── {app,build,chunkhash,copy,entrypoint,lint,polyfills,precache,serve,sitemap,vendor,watch}.js
β”‚   β”œβ”€β”€ utils
β”‚   β”‚   └── {empty-mapper,handle-errors,index,inject-service,resolve-id,service-worker,setup-files}.js
β”‚   └── env.js
β”œβ”€β”€ .babelrc
β”œβ”€β”€ .editorconfig
β”œβ”€β”€ .eslintrc
β”œβ”€β”€ .firebaserc
β”œβ”€β”€ .flowconfig
β”œβ”€β”€ .gitattributes
β”œβ”€β”€ .gitignore
β”œβ”€β”€ .htmlhintrc
β”œβ”€β”€ .stylelintrc
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md
β”œβ”€β”€ circle.yml
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ firebase.json
β”œβ”€β”€ gulpfile.babel.js
β”œβ”€β”€ jest.config.js
β”œβ”€β”€ package.json
└── yarn.lock

Credits

About

Front end project

License:MIT License


Languages

Language:JavaScript 61.6%Language:HTML 30.7%Language:CSS 6.5%Language:Dockerfile 1.1%