Code Monkey home page Code Monkey logo

webapp's Introduction

WebApp is an example of a generic web application with React and Redux.

Features

  • Babel 6
  • React
  • React-router
  • Redux
  • Webpack
  • Isomorphic (universal) rendering
  • Hot reload (aka Hot Module Replacement) for React components, Redux reducers, Redux action creators, translated messages
  • Internationalization with React-intl v2
  • User authentication (JSON Web Token) & authorization (roles)
  • REST API
  • Microservice architecture
  • Responsive web design
  • Koa
  • Bunyan logging (log file rotation is built-in)
  • Correctly handles Http Cookies on the server-side
  • To be done: Persistence (PostgreSQL, Bookshelf)
  • To be done: GraphQL + Relay
  • To be done: native Node.js clustering
  • // maybe: Protection against Cross Site Request Forgery attacks

Quick Start

  • npm install
  • npm run dev
  • wait for it to finish the build (green stats will appear in the terminal, and it will say "Now go to http://127.0.0.1:3000")
  • go to http://127.0.0.1:3000
  • interact with the development version of the web application
  • Ctrl + C
  • npm run production
  • wait a bit for Webpack to finish the build (green stats will appear in the terminal, plus some node.js server running commands)
  • go to http://127.0.0.1:3000
  • interact with the production version of the web application

Installation

npm install

Configuration

One can configure this application through creation of configuration.js file in the root folder (use configuration.defaults.js file as a reference).

All the options set in that file will overwrite the corresponding options set in configuration.defaults.js file.

Running (in development)

npm run dev

After it finishes loading go to http://127.0.0.1:3000

(the web page will refresh automatically when you save your changes)

localhost vs 127.0.0.1

On my Windows machine in Google Chrome I get very slow Ajax requests.

That's a strange bug related to Windows and Google Chrome discussed on StackOverflow

To workaround this bug I'm using 127.0.0.1 instead of localhost in the web browser.

Architecture

The application consists of microservices

  • web-server is the gateway (serves static files and proxies to all the other microservices)
  • page-server renders web pages on the server side (using react-isomorphic-render)
  • authentication-service handles user authentication (sign in, sign out, register) and auditing (keeps a list of user sessions and traces latest activity time)
  • password-service performs password hashing and checking (these operations are lengthy and CPU-intensive)
  • api-service provides some generic Http REST Api
  • image-server (will be split into storage-server and image-service) resized uploaded images
  • log-service aggregates logs from all the other services

Security

The application should be run as an unprivileged user.

When switching to TLS will be made all cookies should be recreated ({ secure: true } option will be set on them automatically upon Https detection when they are recreated).

Image Server

In order to be able to upload pictures ImageMagic is required to be installed

https://github.com/elad/node-imagemagick-native#installation-windows

http://www.imagemagick.org/script/binary-releases.php

Redis

This application can run in demo mode without Redis being installed.

If you want this application make use of Redis then you should install it

https://github.com/MSOpenTech/redis/releases

and configure it in your configuration.js file

redis:
{
  host: ...,
  port: ...,
  password: ... // is optional
}

MongoDB

This application can run in demo mode without MongoDB being installed.

If you want this application make use of MongoDB then you should install it and configure it in your configuration.js file

mongodb:
{
  host: ...,
  port: ...,
  password: ... // is optional
}

PostgreSQL

This application can run in demo mode without PostgreSQL being installed.

If you want this application make use of PostgreSQL then you should install it and configure it in your configuration.js file

postgresql:
{
  host: ...,
  port: ...,
  password: ... // is optional
}

Online status

Each Http request to the server will update the user's latest activity time.

If a certain Http request is automated and shouldn't be interpreted as a user being online then this Http request URL should contain bot=✓ parameter.

This works for GET requests, and I suppose it would work for POST requests too.

To do

ссылку на страницу логина и регистрации вместо button'а в header'е и двух button'ов в форме

для этого, у Button сделать свойства link и post.

link вместо будет делать (несовместимо с submit=true)

post вместо

будет делать (несовместимо с submit=true)

у form параметр submit будет вести на gateway

сделать страницу /register

придумать какой-то gateway, на который можно послать api_url, параметры, и страницу итоговую. этот gateway будет исполнять api_url с заданными параметрами, перенаправляя на итоговую страницу (либо на страницу ошибки).

В react-isomorphic-render мб перейти потом на async-props и react-router-redux, когда они стабилизируются со второй версией react-router'а

сохранять данные пользователей в PostgreSQL (bookshelf)

при переключении языка - записывать язык в данные пользователя в бд, чтобы потом знать, на каком языке ему слать письма.

хранить пользователей в mongodb (и токены)

мониторинг - показывать в меню только для роли 'administrator' в мониторинге - логгировать время каждого запроса (оборачивать yield next()) показывать статус бекапа базы данных

имя пользователя - dropdown с пунктами "Профиль", "Уведомления", "Выйти"

если клик на имени пользователя при наличии - переход сразу в "Уведомления".

сделать компонент (взять из тех двух библиотек)

мобильное меню сделать с поддержкой pan на touchdown, как в materialize css

на странице мониторинга - количество зареганных пользователей + график, количество сессий + график

писать в лог файл все http запросы на web server, чтобы потом если что смотреть, какие дыры нашли

на личной странице пользователя ему одному сделать список IP, для которых есть remember me (мб страны, города), и когда была последняя активность по этим remember me. возможность разлогинивать сессии (уничтожение remember me из базы данных + вызов sign_out для сессии каким-то образом). отображать список текущих сессий (ip, города, страны) и время recent activity

// bcrypt работает медленно, мб заменить её на что-нибудь. // может быть уже есть какая-то новая альтернатива bcrypt'у.

file-server -> storage-server

при загрузке картинок:

jpg - ресайзы делать: 300x300, 600x600, 1000x1000, 1500x1500, 2100x2100, 2800x2800, 3600x3600, 4500x4500

если размер картинки меньше 1.1 * размер ресайза, то не делать ресайз

png - ресайзы как для jpg svg - без ресайза

сделать ограничение на размер картинки - мегабайтов 10.

возможность добавлять картинку по url'у

имя ресайза: [email protected]

при upload-е выдавать ошибку "недостаточно места на диске", если свободного места меньше 5%, например.

ошибку реконнекта к лог сервису - выдавать в лог

буферить сообщения, если нету соединения к лог сервису

видео - mp4, webm; с первым кадром (ресайзы - как для jpg) ограничение - мегабайтов 100

пока - только возможность добавлять video по url'у

message: { text: '...', images: [{ id: '...', type: 'jpg', meta: ..., url: ..., // если добавлена по url'у sizes: [{ width: ..., height: ..., size: ...байтов }] }], videos: [{ { id: '...', type: 'mp4', width: ..., height: ..., meta: ..., size: ...байтов, url: ..., // если добавлено по url'у preview: то же самое, что для картинки (без meta) }] }

написать метод для api, проверяющий наличие аутентикации, и производящий её, если есть remember me cookie, и выдающий ошибку, если аутентикация по remember me не удалась

страницы пользователя: profile + history, feedback

Напоминания взять отсюда

http://materializecss.com/dialogs.html

(в showcase)

Увеличение фотографий

http://materializecss.com/media.html

(в showcase)

endless scroll в логах: выгрузка тех страниц, которые выходят за предел "показывать страниц", + url нормальный (с какой страницы показывать до + "показывать страниц")

на странице логов - фильтр по error, warning, info и т.п.

из log server - писать в MongoDB (опционально)

https://github.com/mafintosh/mongojs

на клиенте сделать log, посылающий всё в консоль, и заменить все console.log на log.info и console.error на log.error

сделать пользователей (регистрация + вход)

защитить логи на доступ только админу (раздел + на web server proxy делать только для админов)

сделать application settings get (языки (считывать имена файлов из папки), путь к картинкам) - в начале, перед показом страницы

языки оттуда подставлять в locale switcher

путь к картинкам подставлять из settings на странице пользователей

image server -> file upload server

image server: imagemagick

ресайз картинки сделать (2 размера: по клику и просто маленький)

добавлять расширение к имени файла

сделать ошибку "не удалось загрузить картинку" для пользователя (inline)

refresh тоже сделать с крутилкой

busy (uploading_picture, deleting, ...) - сделать индивидуальными для каждого id пользователя

создание пользователя сделать без диалога, инлайном ошибку - тоже

/users -> /user_ids /users сделать нормальным, и в action тоже

ошибку удаления и переименования (inline)

user: patch (rename) add user: validation

крутилки на добавление, удаление, переименование, загрузку.

async await

при вошедшем пользователе - проверить, что генерится страница нормально (то есть как бы работает вход на сервере при запросе страницы, даже если нету сессии, но есть "remember me")

remember me - хранить в базе данных, вместе с полем user_id

если происходит новый логин - добавлять новый remember me в базу (проверять по нескольким совпадение можно)

по каждой remember me писать дату последней активности

login_success чтобы перенаправляла на ту страницу, с которой входили

upload только при вошедшем пользователе (и ресайз тоже, и api тоже (не все методы - логин, например, публичен должен быть, и пинг, и настройки))

в showcase в форму добавить загрузку файла отсылать её по API на сервер

  • валидацию формы сделать (вводимых значений, с inline ошибками)

перевести title страниц

сделать статические страницы (nginx) для status 500 (как web server, так и page server) и 503, 401, 403, 404

showcase: сабмит формы, чтобы она сохраняла в оперативку на сервере, и обновляла store на клиенте (+ чтобы работала при обновлении страницы)

showcase form чтобы имел кнопку с валидацией и записью на сервере в оперативку, и получал бы с сервера

можно упаковывать каждый сервис в docker и как-то запускать это на Windows

в button.js сделать автопрефиксы

сделать перепосылку сообщений (с ID) при неполучении подтверждения

соединяться с log server, пока он не запустится (если отвалится, то пересоединяться)

вместо флага demo - entry в конфиге на redis, mongo, imagemagick (если нету чего-то - выдавать баннер в логах с флагом warning)

вычленить dropdown, menu, menu-button в react-responsive-ui зарелизить react-responsive-ui, с react и react-router - peerDependencies

сделать диалоговое окошко (и зарелизить в react-responsive-ui)

showcase элементов: dropdown, modal, ...

если нету imagemagick'а, то просто возвращать нересайженную картинку (npm run demo)

rotating log per worker

monitoring server, который будет принимать статистику по udp и писать в память или MongoDB

// мб в будущем: логи слать по ssl

// мб в будущем сделать можно загрузку более специфичного 'intl/locale-data/jsonp/ru-...'

мониторинг: image server (status, uptime, размер папки со временными файлами) и другие

сервер мониторинга с хранением в бд (пока в оперативе)

графики на d3

в меню сделать пункт Мониторинг

сделать возможность горячей замены image server'а (и других, (у web server'а хранить сессии в редисе для этого можно (если он установлен)))

// во время загрузки картинки - показывать выбранную картинку, уменьшенную, в обозревателе (либо прямо через src, либо предварительно уменьшив), и тикать, как установка приложения в AppStore, пока не загрузится на сервер

// мб перейти на imagemagick-native, когда будет исправлен build // https://github.com/elad/node-imagemagick-native/issues // + потестить ресайз аватаров: чтобы выравнивало по центру как по ширине, так и по высоте

// можно сделать проверку на установленность image magic (необязательно)

сделать 4 страницы example: ram, database, graphql, graphql + database

чтобы работало без наличия postgresql (чтобы запусклось, и в API выдавало ошибку просто с показом на странице)

http://city41.github.io/bookends/

вставить в production build и в development rendering server run

{ "plugins": ["react-intl"], "extra": { "react-intl": { "messagesDir": "./build/messages/", "enforceDescriptions": true } } }

попробовать defineMessages as define_messages (сработает ли в этом случае Babel plugin)

сделать showcase с drag n drop

https://github.com/gaearon/react-dnd

тикающие relative_time

В react-router сделать модульность (постепенную загрузку dependencies)

update-schema вызывать при изменении схемы Relay (nodemon)

graphiql в development mode

https://github.com/graphql/graphiql

localized routes

locale hot switch

https://github.com/gpbl/react-locale-hot-switch/

preload вызывается для всей цепочки (Layout, About) (автор пишет, что preload сам должен определять, нужно ли ему вызываться - на мой взгляд, не лучшее решение)

https://www.google.com/design/icons/

nodemon не watch'ит новые файлы

Долго рестартует web сервер после изменений - мб улучшить это как-то

// Мб перейти с bluebird на обычные Promises // Пока bluebird лучше: // http://programmers.stackexchange.com/questions/278778/why-are-native-es6-promises-slower-and-more-memory-intensive-than-bluebird // к тому же, в bluebird есть обработчик ошибок по умолчанию; есть .cancel(); есть много разного удобного.

Мб использовать это:

https://github.com/obscene/Obscene-Layout

Скрипты установки сразу писать на чём-нибудь типа fabric мб (если он кроссплатформенный)

NginX

https://github.com/acdlite/redux-react-router

Рендеринг React'а вместе с React-router'ом и Redux'ом взят отсюда (будет обновляться после 13.02.2016 - мержить к себе новые изменения):

https://github.com/erikras/react-redux-universal-hot-example/commits/master

Разделить проект на ядро (модуль npm) и чисто кастомный код (actions, stores, pages, components)

можно сделать уведомление (на почту, например, и ограничение функциональности) при заходе с "нового" ip-адреса (опция) ip-адреса можно "запоминать", назначая им имя, если ввести пароль

Загрузку видео + плеер http://videojs.com/

Прочее

В javascript'овом коде используется ES6/ES7 через Babel: https://github.com/google/traceur-compiler/wiki/LanguageFeatures

В качестве среды разработки используется Sublime Text 3, с плагинами

https://github.com/babel/babel-sublime

Чтобы Sublime Text 3 не искал в ненужных папках во время Find in Files, можно использовать такой "Where": ,-node_modules/,-build/

Для общей сборки и для запуска процесса разработки сейчас используется Gulp, но вообще он мало кому нравится, и мб его можно убрать из цепи разработки.

Для сборки клиентской части проекта используется WebPack

https://www.youtube.com/watch?v=VkTCL6Nqm6Y

http://habrahabr.ru/post/245991/

Webpack development server по умолчанию принимает все запросы на себя, но некоторые из них может "проксировать" на Node.js сервер, например. Для этого требуется указать шаблоны Url'ов, которые нужно "проксировать", в файле webpack/development server.js, в параметре proxy запуска webpack-dev-server'а.

Для "профайлинга" сборки проекта Webpack'ом можно использовать Webpack Analyse Tool http://stackoverflow.com/questions/32923085/how-to-optimize-webpacks-build-time-using-prefetchplugin-analyse-tool

На Windows при запуске в develpoment mode Webpack вызывает событие изменения файлов, когда делает их require() в первый раз, поэтому nodemon глючит и начинает много раз перезапускаться.

Ещё, на Windows у nodemon'а, который запускается параллельно в нескольких экземплярах, может быть ошибка "EPERM: operation not permitted", которая не исправляется: remy/nodemon#709

При сборке каждого chunk'а к имени фала добавляется хеш.

Таким образом обходится кеширование браузера (с исчезающе малой вероятностью "коллизии" хешей).

Нужные url'ы подставляются в index.html плагином HtmlWebpackPlugin.

При запуске через npm run dev работает hot reload для компонентов React, а также для Redux'а (например, для action response handlers)

Вместо LESS и CSS в "компонентах" React'а используются inline стили.

Можно также использовать Radium, если понадобится

https://github.com/FormidableLabs/radium

Для подгрузки "глобального" стиля используется модуль Webpack'а style-loader, и поэтому при запуске в режиме разработчика при обновлении страницы присутствует как бы "мигание" протяжённостью в секунду: это время от загрузки Html разметки до отработки javascript'а style-loader'а, который динамически создаёт элемент <style/> с "глобальными" стилями (преимущество: работает hot reload для "глобальных" стилей)

В качестве реализации Flux'а используется Redux:

https://github.com/gaearon/redux

Подключен react-hot-loader

http://gaearon.github.io/react-hot-loader/

Для подключения модулей из bower'а, по идее, достаточно раскомментировать два помеченных места в webpack.coffee.

Альтернативно, есть плагин:

https://github.com/lpiepiora/bower-webpack-plugin

Для кеширования Html5 через manifest можно будет посмотреть плагин AppCachePlugin

// Небольшой мониторинг есть по адресу http://localhost:5959/

// (npm модуль look) (не компилируется на новой Node.js, поэтому выключен)

React Context

http://jaysoo.ca/2015/06/09/react-contexts-and-dependency-injection/

Если возникает такая ошибка в клиентском коде:

"Module parse failed: G:\work\webapp\code\common\log levels.js Line 1: Unexpected token You may need an appropriate loader to handle this file type."

то это означает, что данный файл не подключен в webpack.config.js к babel-loader

Redis для Windows по умолчанию съедает сразу около 40-ка ГигаБайтов места.

Чтобы исправить это, нужно поправить файлы redis.windows.conf и redis.windows-service.conf:

maxmemory 1gb

(править файлы в Program Files не получится, их можно править, скопировав в другое место и потом перезаписав обратно поверх)

webapp's People

Contributors

catamphetamine avatar

Watchers

Chandra Veera avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.