четверг, 20 октября 2016 г.

Мой Webpack, TypeScript, Babel, React, Redux, ESLint, JSCS, Sass, Flow Boilerplate

Как установить файлы через Typings:
typings install dt~jquery --global --save

Структура файлов и папок:
- папка flow
- папка node
- папка source
- файл .flowconfig
- файл flow.exe
- файл index.html
- файл version.txt

Структура файлов и папок внутри flow:
- файл CSSModule.js.flow
- файл WebpackAsset.js.flow

Структура файлов и папок внутри node:
- папка node_modules
- папка typings
- файл node.exe
- файл npm.cmd
- файл typings.cmd
- файл webpack.cmd
- файл package.json
- файл .eslintrc
- файл .jscsrc
- файл .typingsrc
- файл typings.json
- файл tslint.json
- файл eslint.json
- файл stylelint.json
- файл tsconfig.json
- файл webpack.config.js
- файл build.js
- файл server.js

Структура файлов и папок внутри source:
- папка app
- папка config
- папка lib
- файл index.js

Файл /flow/CSSModule.js.flow

// @flow

declare export default { [key: string]: string }

Файл /flow/WebpackAsset.js.flow

// @flow

declare export default string

Файл /.flowconfig

[ignore]
.*/node/.*

[include]
source/index.js

[libs]

[options]
module.name_mapper.extension='css' -> '<PROJECT_ROOT>/flow/CSSModule.js.flow'
module.name_mapper.extension='scss' -> '<PROJECT_ROOT>/flow/CSSModule.js.flow'
module.name_mapper.extension='png' -> '<PROJECT_ROOT>/flow/WebpackAsset.js.flow'
module.name_mapper.extension='jpg' -> '<PROJECT_ROOT>/flow/WebpackAsset.js.flow'
module.name_mapper.extension='gif' -> '<PROJECT_ROOT>/flow/WebpackAsset.js.flow'
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue

Файл /version.txt

1.4.0

Файл /index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link href="build/bundle.css?v=1.0.0-1472804427607" rel="stylesheet" type="text/css" />
    <title>Мой сайт</title>
</head>
<body>
    <div id="root"></div>
    <p id="version">Мой сайт (v1.0.0)</p>
    <script src="build/bundle.js?v=1.0.0-1472804427607" type="text/javascript"></script>
</body>
</html>

Файл /node/package.json

{
      "version": "1.0.0"
    , "name": "webpack-all-in-one"
    , "description": "Webpack all in one"
    , "keywords": ["webpack", "all"]
    , "author": "John Doe"
    , "engines": {
          "node": "6.9.0"
        , "npm": "3.10.9"
      }
    , "scripts": {
          "build": "node build"
      }
    , "dependencies": {
          "bluebird": "3.4.6"
        , "jquery": "3.1.1"
        , "react": "15.3.2"
        , "react-dom": "15.3.2"
        , "react-router": "2.8.1"
        , "react-router-redux": "4.0.6"
        , "react-redux": "4.4.5"
        , "redux": "3.6.0"
        , "redux-router": "2.1.2"
        , "redux-thunk": "2.1.0"
        , "redux-logger": "2.7.0"
      }
    , "devDependencies": {
          "webpack": "1.13.2"
        , "webpack-dev-middleware": "1.8.4"
        , "webpack-hot-middleware": "2.13.0"
        , "clean-webpack-plugin": "0.1.13"
        , "extract-text-webpack-plugin": "1.0.1"
        , "express": "4.14.0"
        , "typescript": "2.0.3"
        , "ts-loader": "0.9.5"
        , "tslint": "3.15.1"
        , "tslint-react": "1.1.0"
        , "tslint-loader": "2.1.5"
        , "babel-core": "6.17.0"
        , "babel-polyfill": "6.16.0"
        , "babel-preset-es2015": "6.16.0"
        , "babel-preset-stage-0": "6.16.0"
        , "babel-preset-react": "6.16.0"
        , "babel-preset-react-hmre": "1.1.1"
        , "babel-plugin-syntax-flow": "6.13.0"
        , "babel-plugin-transform-flow-strip-types": "6.14.0"
        , "babel-plugin-tcomb": "0.3.19"
        , "babel-loader": "6.2.5"
        , "babel-eslint": "7.0.0"
        , "eslint": "3.8.1"
        , "eslint-plugin-react": "6.4.1"
        , "eslint-loader": "1.6.0"
        , "jscs": "3.0.7"
        , "jscs-loader": "0.3.0"
        , "node-sass": "3.10.1"
        , "sass-loader": "4.0.2"
        , "css-loader": "0.25.0"
        , "style-loader": "0.13.1"
        , "stylelint": "7.5.0"
        , "stylelint-loader": "6.2.0"
        , "file-loader": "0.9.0"
        , "url-loader": "0.5.7"
        , "html-loader": "0.4.4"
        , "json-loader": "0.5.4"
        , "source-map-loader": "0.1.5"
        , "tcomb": "3.2.15"
        , "tcomb-react": "0.9.3"
        , "@types/core-js": "0.9.34"
        , "@types/bluebird": "3.0.35"
        , "@types/glob": "5.0.30"
        , "@types/filesaver": "0.0.30"
        , "@types/jquery": "2.0.33"
        , "@types/history": "2.0.39"
        , "@types/react": "0.14.41"
        , "@types/react-dom": "0.14.18"
        , "@types/react-router": "2.0.38"
        , "@types/react-router-redux": "4.0.34"
        , "@types/react-redux": "4.4.32"
        , "@types/redux": "3.6.31"
        , "@types/redux-router": "1.0.33"
        , "@types/redux-thunk": "2.1.31"
        , "@types/redux-logger": "2.6.32"
        , "@types/tcomb": "1.0.27"
      }
    , "repository": {
          "type": "git"
        , "url": "http://stash.ca.sbrf.ru/scm/sirius/sirius-arm-new.git"
      }
}

Файл /node/.eslintrc

{
      "extends": "eslint:recommended"
    , "parser": "babel-eslint"
    , "env": {
          "browser": true
        , "node": true
      }
    , "plugins": [
          "react"
      ]
    , "rules": {
          "no-debugger": 0
        , "no-console": 0
        , "new-cap": 0
        , "strict": 0
        , "no-underscore-dangle": 0
        , "no-use-before-define": 0
        , "eol-last": 0
        , "quotes": [2, "single"]
        , "jsx-quotes": [1, "prefer-single"]
        , "react/jsx-no-undef": 1
        , "react/jsx-uses-react": 1
        , "react/jsx-uses-vars": 1
    }
}


Файл /node/.jscsrc

пуст


Файл /node/.typingsrc

{
    "rejectUnauthorized": false
}

Файл /node/typings.json

{
    "globalDependencies": {
        "jquery": "registry:dt/jquery#1.10.0+20160704162008",
        "react": "registry:dt/react#0.14.0+20160805125551",
        "react-dom": "registry:dt/react-dom#0.14.0+20160412154040"
    }
}


Файл /node/tslint.json

{
  "extends": ["tslint:latest", "tslint-react"],
  "rules": {
    "indent": [ true, "spaces" ],
    "quotemark": [ true, "single", "jsx-double" ],
    "no-var-requires": false,
    "ordered-imports": false,
    "no-unused-variable": [true, "react"],
    "member-ordering": false,
    "object-literal-sort-keys": false,
    "no-shadowed-variable": false,
    "no-console": false
  }
}

Файл /node/eslint.json

/*
{
      // Здесь нет правил для ECMAScript 6
      "parserOptions": { // Настройки парсера кода
          "ecmaVersion": 3 // версия проверяемого кода ECMAScript
        , "sourceType": "script" // источник кода - отдельно загружаемые файлы
        , "ecmaFeatures": { // особенности кода ECMAScript
            "impliedStrict": true // проверять, что код написан с соблюдением правил строгого режима "use strict"; ?
          }
      }
    , "env": { // Настройки окружения
          "browser": true // разрешить использование глобальных браузерных переменных?
        , "commonjs": true // разрешить использование глобальных переменных CommonJS?
        , "worker": true // разрешить использование глобальных переменных web workers?
        , "amd": true // разрешить использование глобальных переменных require() и define() ?
        , "jquery": true // разрешить использование глобальных переменных jQuery?
      }
    , "globals": { // перечень глобальных переменных, которые явно не определены, то могут использоваться в каждом файле
          "require": true
        , "define": true
        , "ActiveXObject": true
      }
    , "rules": { // Правила
        // Possible Errors - случаи возможных ошибок в коде
          "comma-dangle": [2, "never"] // наличие запятой в конце списка элементов объекта или массива
        , "no-cond-assign":  [2, "always"] // запретить присвоение значений внутри условия: if (x = 1)
        , "no-console": 2 // запретить использование console в коде
        , "no-constant-condition": 2 // запретить писать только true или false внутри устловия: if (true)
        , "no-control-regex": 2 // запретить скрытые символы внутри регулярных выражений: /\\x1f/
        , "no-debugger": 2 // запретить использование debugger; в коде
        , "no-dupe-args": 2 // запретить дублирование аргументов в функции
        , "no-dupe-keys": 2 // запретить дублирование ключей в объектах
        , "no-duplicate-case": 2 // запретить дублирование case в switch
        , "no-empty": 2 // запретить пустые блоки в коде
        , "no-empty-character-class": 2 // запретить пустые квадратные скобки в регулярных выражениях: /^abc[]/
        , "no-ex-assign": 2 // запретить присвоение занчений переменной error в блоке catch: catch (error) {error = 10;}
        , "no-extra-boolean-cast": 2 // запретить преобразование к типу Boolen посредством символов !!: if (!!foo) {}
        , "no-extra-parens": 0 // запретить писать лишние круглые скобки
        , "no-extra-semi": 2 // запретить писать лишние точки с запятыми
        , "no-func-assign": 2 // запретить переопределение уже созаднных функций
        , "no-inner-declarations": 2 // запретить опеределение функций и определений внутри условий
        , "no-invalid-regexp": 2 // проверить правильность написания регулярного выражения
        , "no-irregular-whitespace": 2 // запретить писать необычные виды пробелов
        , "no-negated-in-lhs": 2 // запретить писать условия с отрицанием вида if (!key in object)
        , "no-obj-calls": 2 // запретить вызов глобальных объектов: Math(); или JSON();
        , "no-regex-spaces": 2 // запретить писать простые пробелы внутри регулярных выражений: /foo   bar/
        , "no-sparse-arrays": 2 // запретить пропускать элементы в массивах: ["red", , "blue"]
        , "no-unexpected-multiline": 2 // запретить неожиданный переход на следующую строку
        , "no-unreachable": 2 // запретить написание кода, который никогда не будет выполнен
        , "use-isnan": 2 // запретить написание прямого сравнения с NaN: if (foo == NaN)
        , "valid-jsdoc": 2 // проверить правильность написания комментариев в формате JSDoc
        , "valid-typeof": 2 // проверить правильность написания сравнения с типом данных вида: typeof foo === "strnig"
        // Best Practices - наилучшие практики проверки кода
        , "accessor-pairs": 2 // проверить наличие get для каждого свойства объекта, для которого прописан set
        , "array-callback-return": 0 // проверить наличие return в функции, использующейся в качестве обработчика массива
        , "block-scoped-var": 2 // запретить использование переменной вне блока, в котором она была опеределена
        , "complexity": [2, 15] // цикломатическая сложность программы
        , "consistent-return": 0 // проверить, что все return возвращают значения или не возвращают ничего
        , "curly": 2 // проверить наличие фигурных скобок
        , "default-case": 2 // проверить наличие default в switch
        , "dot-location": [2, "property"] // проверить, что точка привязана к свойству, а не к объекту
        , "dot-notation": 2 // проверить, что вместо [] используется точка для получения значения свойств объекта
        , "eqeqeq": 2 // проверить, что используется только строго сравнение === и !==
        , "guard-for-in": 2 // проверить, что при перечислении свойств объекта используется проверка: if (foo.hasOwnProperty(key))
        , "no-alert": 2 // проверить, что в коде нет функции alert();, confirm();, prompt();
        , "no-caller": 2 // запретить использование в коде arguments.caller и arguments.callee
        , "no-case-declarations": 2 // запретить объявление переменных let, const, function и class внутри case и default в switch
        , "no-div-regex": 2 // проверить наличия escape для регулярного выражения вида /=foo/, которое может быть интерпретировано, как операция деления /=
        , "no-else-return": 0 // запретить написание внутри функции необязательно блока с кодом else {return x;}
        , "no-empty-function": 0 // запретить наличие в коде функций с пустым телом
        , "no-empty-pattern": 2 // запретить наличие в коде пустых паттернов деструктурирования объектов и массивов
        , "no-eq-null": 2 // запретить нестрогое сравнение с null: if (foo == null)
        , "no-eval": 2 // запретить использование функции eval
        , "no-extend-native": [2, {"exceptions": []}] // запретить расширение встроенных объектов
        , "no-extra-bind": 2 // запретить бессмысленное примение функции bind
        , "no-extra-label": 2 // запретить бессмысленное примение label
        , "no-fallthrough": 2 // запретить конструкции case без break; или return;
        , "no-floating-decimal": 2 // запретить писпть числа с плавающей точкой без нулей: .2 или 2.
        , "no-implicit-coercion": 0 // запретить преобразование типов с помощью конструкций вида: "" + foo, !!foo, +foo, ~foo
        , "no-implicit-globals": 2 // запретить объявление глобальных переменных без привязки к window
        , "no-implied-eval": 2 // запретить выполнять код через setTimeout(), setInterval() и execScript() вида: setTimeout("alert('Hi!');", 100); или execScript("alert('Hi!')");
        , "no-invalid-this": 2 // запретить неправильное использование this
        , "no-iterator": 2 // запретить изменять свойство __iterator__
        , "no-labels": 2 // запретить использование меток label
        , "no-lone-blocks": 2 // запретить использование одиночных блоков { }
        , "no-loop-func": 0 // запретить создавать функции внутри циклов
        , "no-magic-numbers": 0 // запретить использование магических чисел
        , "no-multi-spaces": 2 // запретить использование множественных пробелов в коде
        , "no-multi-str": 2 // запретить разбиение строк с помощью символа \
        , "no-native-reassign": 2 // запретить переопределение встроенных объектов: String = "hello world";
        , "no-new": 2 // запретить вызов функции конструктора объектов с new без присвоения его значения переменной: new Thing();
        , "no-new-func": 2 // запретить использование Function: var x = new Function("a", "b", "return a + b");
        , "no-new-wrappers": 2 // запретить использовать String, Number и Boolean с оператором new
        , "no-octal": 2 // запретить использовать литералы восьмиричных чисел: var num = 071;
        , "no-octal-escape": 2 // запретить использовать восьмиричные escape-последовательности: var foo = "Copyright \251";
        , "no-param-reassign": 0 // запретить измнение значений параметров функций: function foo(bar) {bar = 13;}
        , "no-process-env": 2 // запретить использование process.env: if (process.env.NODE_ENV === "development")
        , "no-proto": 2 // запретить использование __proto__: var a = obj.__proto__;
        , "no-redeclare": 2 // запретить повторное объявление переменных: var a = 3; var a = 10;
        , "no-return-assign": 2 // запретить присвоение значений в return: function doSomething() {return foo = bar + 2;}
        , "no-script-url": 2 // запретить писать JavaScript-код в url: location.href = "javascript:void(0)";
        , "no-self-assign": 2 // запретить присваивать значение переменной самой себе: foo = foo;
        , "no-self-compare": 2 // запретить сравнивать значение перемнной с самой собой: if (x === x)
        , "no-sequences": 2 // запретить писать последовательности кода через запятую: a = b += 5, a + b;
        , "no-throw-literal": 2 // запретить выбрасывать исключения с помощью литералов, не являющихся объектами типа Error: throw "error"; throw 0; throw undefined; throw null;
        , "no-unmodified-loop-condition": 2 // запретить изменение переменных, использующихся в циклах, вне этих циклов
        , "no-unused-expressions": 2 // запретить наличие в коде неиспользуемых выражений: c = a, b;
        , "no-unused-labels": 2 // запретить наличие в коде неиспользуемых меток label циклов
        , "no-useless-call": 2 // запретить бессмысленное применение call и apply: foo.call(undefined, 1, 2, 3); или foo.apply(null, [1, 2, 3]);
        , "no-useless-concat": 2 // запретить бессмысленное объединение строк: var foo = "a" + "b";
        , "no-void": 2 // запретить использование оператора void
        , "no-with": 2 // запретить использование в коде with
        , "radix": [2, "always"] // требуется писать значение второго аргумента в функции parseInt()
        , "vars-on-top": 0 // все переменные должны быть объявлены на самом верху
        , "wrap-iife": [0, "outside"] // тип обертывания в круглые скобки немедленно вызываемой функйции: var x = (function () { return {y: 1};})();
        , "yoda": 2 // запретить стиль Йоды при написании условных выражений: if ("red" === color)
        // Strict Mode - правила строгого режима: "use strict";
        , "strict": [2, "never"] // запретить использование инструкции "use strict"; в коде
        // Variables - правила создания переменных
        , "no-catch-shadow": 2 // запретить называть переменную внутри catch уже использующимся именем другой переменной
        , "no-delete-var": 2 // запретить применять delete к обычным переменным
        , "no-label-var": 2 // запретить называть метку цикла label уже использующимся именем другой переменной
        , "no-restricted-globals": [2, "event"] // запретить использование данных глобальных переменных
        , "no-shadow-restricted-names": 2 // запретить создавать переменные с именами: NaN, Infinity, undefined, eval, arguments
        , "no-undef": 2 // запретить использование необъявленных переменных, кроме тех, что перечислены в "globals"
        , "no-undef-init": 2 // запретить присваивать переменной значение undefined: var foo = undefined;
        , "no-undefined": 0 // запретить переписывать значение переменной undefined
        , "no-unused-vars": 2 // запретить наличие в коде неиспользуемых переменных и функций
        , "no-use-before-define": 0 // запретить обращение к элементу до того, как он был объявлен в коде
        // Stylistic Issues - правила оформления кода
        , "array-bracket-spacing": [2, "never"] // запретить пробелы между скобками массивов: ['foo', 'bar', 'baz']
        , "block-spacing": [2, "never"] // запретить пробелы между скобками блоков: if (foo) {bar = 0;}
        , "brace-style": [0, "1tbs", {"allowSingleLine": true}] // стиль расположения скобок в конструкциях типа if () {} else {}
        , "camelcase": 2 // имена переменных должны быть записаны в стиле camelCase
        , "comma-spacing": [2, {"before": false, "after": true}] // стиль написания пробелов до и после запятой
        , "comma-style": [2, "first"] // стиль написания запятой - ведущая запятая
        , "computed-property-spacing": [2, "never"] // стиль пробелов в свойствах
        , "consistent-this": [2, "that", "self"] // переменные, заменяющие значение this
        , "eol-last": 0 // требовать оставлять пустую строку в конце каждого файла
        , "func-names": 0 // требовать прописывать имена функциям в выражениях: Foo.prototype.bar = function bar() {};
        , "id-length": [2, {"min": 1}] // минимальное число символов в названиях переменных и функций
        , "indent": 0 // минимальный отступ от левого края: 4 пробела
        , "key-spacing": [2, {"beforeColon": false, "afterColon": true}] // пробелы в свойствах объектов
        , "keyword-spacing": 2 // пробелы перед ключевыми словами
        , "linebreak-style": [2, "windows"] // стиль перехода на следующую строку
        , "max-depth": [2, {"maximum": 5}] // максимальная вложенность блоков кода друг в друга
        , "max-len": [2, {"code": 300, "tabWidth": 4, "ignoreUrls": true, "ignoreTrailingComments": true}] // максимальная длина строки
        , "max-nested-callbacks": [2, {"maximum": 3}] // максимальное число вложенных обратных вызовов
        , "max-params": [2, {"maximum": 5}] // максимальное числов аргументов в функции
        , "max-statements": [2, 50, {"ignoreTopLevelFunctions": true}] // максимальное число предложений в функции
        , "new-cap": 0 // проверять, что названия всех функций конструкторов объектов начинаются с заглваной буквы: var friend = new Person();
        , "new-parens": 2 // проверять наличие круглых скобков при вызове функции конструктора объектов без аргументов: var person = new Person();
        , "no-array-constructor": 2 // запретить использование функции Array: new Array(0, 1, 2)
        , "no-bitwise": 2 // запретить побитовые операции: var x = y | z;
        , "no-mixed-spaces-and-tabs": 2 // запретить писать в одной строке пробелы и табы
        , "no-multiple-empty-lines": [2, {"max": 2}] // запретить множественные пустые строки
        , "no-negated-condition": 0 // запретить отрицающие сравнения:if (!a) {doSomething();} else {doSomethingElse();}
        , "no-new-object": 2 // запретить создание пустых объектов с помощью new Object();
        , "no-spaced-func": 2 // запретить пробелы перед круглыми скобками при вызовах функций: fn ()
        , "no-trailing-spaces": [2, {"skipBlankLines": true}] // запретить пробелы в конце строк
        , "no-unneeded-ternary": 2 // запретить ненужные тернарные операторы: var isYes = answer === 1 ? true : false;
        , "no-whitespace-before-property": 2 // запретить пробелы перед свойствами объекта: foo. bar. baz
        , "object-curly-spacing": [2, "never"] // запретить пробелы между фигурными скобками объектов
        , "one-var-declaration-per-line": [2, "always"] // допустимо использование только 1 var на линию кода
        , "operator-assignment": [2, "always"] // lдопустимо только присвоение значений вида: x += y;
        , "operator-linebreak": [2, "before"] // допустимы только ведущие +, -, *, / при разбиении выражения на несколько строк
        , "padded-blocks": 0 // требуется всегда делать отступы в коде внутри блоков
        , "quotes": [2, "single", "avoid-escape"] // стиль написания кавычек
        , "require-jsdoc": [0, { // требуется для функций, методов и классов писать комментарии в формате JSDoc
                                            "require": {
                                                "FunctionDeclaration": true,
                                                "MethodDefinition": true,
                                                "ClassDeclaration": true
                                            }
                                        }]
        , "semi": [2, "always"] // требуется всегда писать в коде точку с запятой
        , "semi-spacing": 2 // требуется всегда ставить пробел после точки с запятой
        , "space-before-blocks": [0, {"keywords": "always", "classes": "always"}] // требуется писать пробелы переред открывающей фигурной скобкой
        , "space-before-function-paren": [0, {"anonymous": "always", "named": "always"}] // требуется писать пробелы переред открывающей круглой скобкой
        , "space-in-parens": [2, "never"] // запретить пробелы внутри круглых скобок: var foo = (1 + 2) * 3;
        , "space-infix-ops": 2 // требуется писать пробелы вокруг инфиксных операторов: a + b
        , "space-unary-ops": 2 // ребуется писать пробелы вокруг унарных операторов: +"3";
        , "spaced-comment": [0, "always"] // требуется, чтобы первым символом в комментарии был пробел
        , "wrap-regex": 0 // требуется обертывать литералы регулярных выражений в круглые скобки: (/foo/).test("bar");
      }
    , "plugins": [
          "react"
      ]
    , "extends": ["eslint:all", "plugin:react/all"]
}
*/
{
  "extends": "eslint:recommended",
  "parser": "babel-eslint",
  "env": {
    "browser": true,
    "node": true
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "no-debugger": 0,
    "no-console": 0,
    "new-cap": 0,
    "strict": 0,
    "no-underscore-dangle": 0,
    "no-use-before-define": 0,
    "eol-last": 0,
    "quotes": [2, "single"],
    "jsx-quotes": [1, "prefer-single"],
    "react/jsx-no-undef": 1,
    "react/jsx-uses-react": 1,
    "react/jsx-uses-vars": 1
  }
}

Файл /node/stylelint.json

{
  "rules": {
    "block-no-empty": null,
    "color-no-invalid-hex": true,
    "declaration-colon-space-after": "always",
    "indentation": ["tab", {
      "except": ["value"]
    }],
    "max-empty-lines": 2,
    "unit-whitelist": ["px", em", "rem", "%", "s"]
  }
}

Файл /node/tsconfig.json

{
    "compilerOptions": {
          "declaration": false // true | false (default) - генерировать файлы .d.ts с описанием кода (declare) из TypeScript-файлов - Generates a .d.ts definitions file for compiled TypeScript files
        , "emitDecoratorMetadata": false // true | false (default) - сгенерировать мета-данные для типа/параметра декораторов - Emit metadata for type/parameter decorators.
        , "experimentalDecorators": false // true | false (default) - включить экспериментальную поддержку ES7 декораторов - Enables experimental support for ES7 decorators
        , "inlineSourceMap": false // true | false (default) - сгененрировать одиночный source map файл, включающий в себя все source map всех файлов вместо того, чтобы создавать отдельные .js.map файлы - Emit a single file that includes source maps instead of emitting a separate .js.map file.
        , "inlineSources": false // true | false (default) - Объединить весь исходный TypeScript код вместе со всеми source map в единый файл. Требуется чтобы правило inlineSourceMap было установлено в true. - Emit the TypeScript source alongside the sourcemaps within a single file. Requires inlineSourceMap to be set.
        , "isolatedModules": false // true | false (default) - убедиться, что вывод безопасен для компиляции только одиночных файлов путем создания ситуаций, которые сломают одиночный файл и приведут к ошибке - Ensures that the output is safe to only emit single files by making cases that break single-file transpilation an error
//     , "mapRoot": "" // "/maps" - корневая директория, в которой дебаггеру следует искать source map файлы вместо исходного их положения, определяемого при компиляции - Specifies the location where debugger should locate map files instead of generated locations.
        , "module": "amd" // "amd" (default) | "commonjs" | "system" | "umd" | "" - в какой тип модулей (amd, commonjs, system или umd) компилировать файлы - Specify module style for code generation
        , "newLine": "CRLF" // "CRLF" | "LF" | "" (default) - какие символы перехода на следующую строку (CRLF или LF) должны быть прописаны в скомпилированных файлах - Explicitly specify newline character (CRLF or LF); if omitted, uses OS default.
        , "noEmit": false // true | false (default) - проверить код на возможность компиляции, но не компилировать итоговые файлы даже, если в коде отсутсвуют ошибки - Check, but do not emit JS, even in the absence of errors.
        , "noEmitHelpers": true // true | false (default) - не вставлять в скомпилированные файлы вспомогательные функции типа __extends - Do not generate custom helper functions like __extends in compiled output.
        , "noImplicitAny": false // true | false (default) - запретить использовать тип any - выводить предупреждения, если выражения или объявления переменных имеют тип any - Warn on expressions and declarations with an implied any type.
        , "noResolve": true // true | false (default) - не добавлять тройной слэш /// или import target для модуля в скомпилированные файлы - Do not add triple-slash references or module import targets to the compilation context.
//     , "out": "" // "" - компиляция в разные файлы, если указана пустая строка "" или компиляция в единый файл, если указан итоговый файл "./js/single.js" -  - Concatenate and emit output to a single file.
//     , "outDir": "" // "dist" - если указана пустая строка "", то записывать скомпилированные файлы рядом с TypeScript-файлом или перенести итоговые скомпилированные файлы, включая их иерархическое расположение в подпапках, в заданную директорию "dist" - Redirect output structure to the directory.
        , "preserveConstEnums": false // true | false (default) - константы перечислений будут сохранены в качестве перечислений в скомпилированных файлах - Const enums will be kept as enums in the emitted JS.
        , "removeComments": false // true (default)| false - удалять или включать исходные комментарии в итоговые скомпилированные файлы - Configures if comments should be included in the output
        , "sourceMap": false // true (default) | false - генерировать source map файлы - для Generates corresponding .map file
//     , "sourceRoot": "" // "/dev" - корневая директория, в которой дебаггеру следует искать исхдные TypeScript-файлы вместо исходного их положения - Specifies the location where debugger should locate TypeScript files instead of source locations.
        , "suppressImplicitAnyIndexErrors": false // true | false (default) - если установлено true, то TypeScript позволит получить доступ к свойствам объекта по строковому индексу, если правило noImplicitAny активно, даже если TypeScript не знает о них. Это свойство не действует до тех пор, пока правило noImplicitAny не будет установлено активным. - If set to true, TypeScript will allow access to properties of an object by string indexer when noImplicitAny is active, even if TypeScript doesn"t know about them. This setting has no effect unless noImplicitAny is active.
        , "target": "es5" // "es3" | "es5" (default) | "es6" - в какую версию ECMAScript (3, 5 или 6) компилировать файлы - Specify ECMAScript target version": "es3", "es5", or "es6"
        , "allowJs": true // true | false (default) - разрешить компиляцию чистого JavaScript-кода
        , "strictNullChecks": true // true | false (default) - разрешить строгую проверку null
        , "noImplicitUseStrict": true // true | false (default) - запретить запись 'use strict' в итоговые файлы
        , "allowUnreachableCode": false // true | false (default) - запретить выводить сообщения об ошибка при обнаружении недостижимого кода
        , "jsx": "react" // "preserve" | "react" - определить тип генерируемого кода JSX
    }
  , "files": [
          "typings/index.d.ts"
    ]
}

Файл /node/webpack.config.js

const fs = require('fs')
        , path = require('path')
        , webpack = require('webpack')
        , CleanWebpackPlugin = require('clean-webpack-plugin')
        , ExtractTextPlugin = require('extract-text-webpack-plugin');

const fs = require('fs')
        , path = require('path')
        , webpack = require('webpack')
        , CleanWebpackPlugin = require('clean-webpack-plugin')
        , ExtractTextPlugin = require('extract-text-webpack-plugin');
        
const environment = require('./config/environment');

const indexFile = path.resolve(__dirname, '../source/index.js');

const entry = environment ? [
                                              'babel-polyfill'
                                            , indexFile
                                          ]
                                        : [
                                              'webpack/hot/dev-server'
                                            , 'webpack-hot-middleware/client'
                                            , 'babel-polyfill'
                                            , indexFile
                                          ];

module.exports = {
      entry: entry
    , resolve: {
            extensions: ['', '.js', '.jsx', '.ts', '.tsx']
          , alias: {
                  resetStyle: path.resolve(__dirname, '../source/app/common/reset.scss')
                , bodyStyle: path.resolve(__dirname, '../source/app/common/body.scss')
                , rootStyle: path.resolve(__dirname, '../source/app/common/root.scss')
                , hiddenStyle: path.resolve(__dirname, '../source/app/common/hidden.scss')
                , sortIconsStyle: path.resolve(__dirname, '../source/app/common/sort-icons.scss')
                , versionStyle: path.resolve(__dirname, '../source/app/common/version.scss')
                , windowOnErrorStyle: path.resolve(__dirname, '../source/app/window-onerror/window-onerror.scss')

                , 'react': path.resolve(__dirname, 'node_modules/react/lib/React.js')
                , 'react-dom': path.resolve(__dirname, 'node_modules/react/lib/ReactDOM.js')
                , 'react-router': path.resolve(__dirname, 'node_modules/react-router/lib/index.js')
                , 'react-router-redux': path.resolve(__dirname, 'node_modules/react-router-redux/lib/index.js')
                , 'react-redux': path.resolve(__dirname, 'node_modules/react-redux/lib/index.js')
                , 'redux': path.resolve(__dirname, 'node_modules/redux/lib/index.js')
                , 'redux-thunk': path.resolve(__dirname, 'node_modules/redux-thunk/lib/index.js')
                , 'redux-logger': path.resolve(__dirname, 'node_modules/redux-logger/lib/index.js')
                , 'tcomb': path.resolve(__dirname, 'node_modules/babel-plugin-tcomb/lib/index.js')

                , getHistory: path.resolve(__dirname, '../source/app/history/get-history.js')
                , historyStyle: path.resolve(__dirname, '../source/app/history/style.scss')
                , historyView: path.resolve(__dirname, '../source/app/history/history.js')
                , historyConstants: path.resolve(__dirname, '../source/app/history-data/history-constants.js')
                , historySortAction: path.resolve(__dirname, '../source/app/history-data/history-sort-action.js')
                , historySortReducer: path.resolve(__dirname, '../source/app/history-data/history-sort-reducer.js')
                , historyGetDataAction: path.resolve(__dirname, '../source/app/history-data/history-get-data-action.js')
                , historyGetDataReducer: path.resolve(__dirname, '../source/app/history-data/history-get-data-reducer.js')
            }
      }
    , output: {
          path: path.resolve(__dirname, '../build')
        , filename: 'bundle.js'
        , publicPath: '/build/'
        , pathinfo: true
      }
    , resolveLoader: {
          root: path.join(__dirname, 'node_modules')
      }
    , module: {
           preLoaders: [
                {
                      test: /\.js$/
                    , exclude: /node_modules/
                    , loader: 'jscs-loader!eslint-loader'
                }
              , {
                      test: /\.ts?$/
                    , exclude: /node_modules/
                    , loader: 'tslint-loader'
               }
              , {
                      test: /\.(sass|scss)$/
                    , loader: 'stylelint-loader'
               }
           ]
         , loaders: [
                {
                      test: /\.tsx?$/
                    , exclude: /node_modules/
                    , loader: 'awesome-typescript-loader'
                }
              , {
                      test: /\.jsx?$/
                    , exclude: /node_modules/
                    , loader: 'babel-loader'
                    , query: {
                          presets: [
                                  path.join(__dirname, 'node_modules/babel-preset-react-hmre')
                                , path.join(__dirname, 'node_modules/babel-preset-stage-0')
                                , path.join(__dirname, 'node_modules/babel-preset-react')
                                , path.join(__dirname, 'node_modules/babel-preset-es2015')
                          ]
                        , passPerPreset: true
                        , plugins: [
                                  path.join(__dirname, 'node_modules/babel-plugin-syntax-flow')
                                , path.join(__dirname, 'node_modules/babel-plugin-tcomb')
                                , path.join(__dirname, 'node_modules/babel-plugin-transform-flow-strip-types')
                          ]
                      }
                }
              , {
                      test: /\.html/
                    , exclude: /node_modules/
                    , loader: 'html-loader'
                }
              , {
                      test: /\.scss/
                    , exclude: /node_modules/
                    , loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader')
                }
              , {
                      test: /\.(jpe?g|png|gif)$/i
                    , exclude: /node_modules/
                    , loader: 'url-loader'
                    , query: {
                            limit: 10000 // 10 kb
                          , name: 'images/[hash].[ext]'
                      }
                }
              , {
                      test: /\.json$/
                    , loader: 'json-loader'
                }
          ]
       }
     , plugins: [
            new CleanWebpackPlugin(['build'], {root: path.resolve(__dirname, '../')})
          , new ExtractTextPlugin('../build/bundle.css')
          , new webpack.BannerPlugin('Build date: ' + new Date().toString())
          , new webpack.optimize.DedupePlugin()
          , new webpack.optimize.OccurenceOrderPlugin()
          , new webpack.HotModuleReplacementPlugin()
          , new webpack.NoErrorsPlugin()
          , new webpack.DefinePlugin({VERSION: JSON.stringify(fs.readFileSync(path.join(__dirname, '../version.txt'), 'utf-8')).trim()})
      ]
    , bail: true
    , debug: true
    , eslint: {
            configFile: path.join(__dirname, 'eslint.json')
          , failOnError: true
       }
     , jscs: {
            validateIndentation: 2
          , emitErrors: false
          , failOnHint: false
          , reporter: function(errors) {}
       }
     , tslint: {
            configuration: {
                rules: {
                    quotemark: [true, 'double']
                }
            }
          , failOnHint: true
       }
     , stylelint: {
            configFile: path.join(__dirname, 'stylelint.json')
          , configOverrides: {
                rules: {
                    "block-no-empty": null
                }
            }
       }
};

Файл /node/build.js

const fs = require('fs')
        , path = require('path')
        , indexFilePath = path.join(__dirname, '../index.html')
        , versionFilePath = path.join(__dirname, '../version.txt');

fs.writeFileSync(
      indexFilePath
    , fs.readFileSync(indexFilePath, 'utf-8').replace(
              /\?v=\d+\.\d+\.\d+-\d+"/g
            , `?v=${fs.readFileSync(versionFilePath, 'utf-8')}-${new Date().getTime()}"`
      ).replace(
              /v\d+\.\d+\.\d+/g
            , `v${fs.readFileSync(versionFilePath, 'utf-8')}`
      )
);

require('./server');

Файл /node/server.js

const path = require('path')
        , webpack = require('webpack')
        , webpackDevMiddleware = require('webpack-dev-middleware')
        , webpackHotMiddleware = require('webpack-hot-middleware')
        , webpackConfig = require('./webpack.config')
        , express = require('express')
        , http = require('http');

const app = express();

const webpackCompiler = webpack(webpackConfig);

app.use(webpackDevMiddleware(webpackCompiler, {noInfo: true, publicPath: webpackConfig.output.publicPath}));
app.use(webpackHotMiddleware(webpackCompiler));

app.use(express.static(path.resolve(__dirname, '../')));

app.get('/', function (request, response) {
    response.sendFile(path.resolve(__dirname, '../index.html'));
});

app.get('/path/to/options', function (request, response){
//  proxyToServer('10.80.238.27', 9081, 'http://10.80.238.27:9081/path/to/options', 'GET', response);
    response.json(generateOptions());
});

app.listen(80, '127.0.0.1', function (error) {
    if (error) {throw error;}
    console.log('Server is running at http://127.0.0.1:80');
});

function proxyToServer (host, port, path, method, response) {
    const options = {
          host: host // host to forward to
        , port: port // port to forward to
        , path: path // path to forward to
        , method: method // request method
        , headers: response.headers // headers to send
    };

    let data = '';

    const proxy = http.request(options, function (proxyResponse) {
        proxyResponse.setEncoding('utf8');
        proxyResponse.on('data', function (chunk) {
            data += chunk;
        });
        proxyResponse.on('end', function () {
            response.writeHead(200, {'Content-Type': 'application/json'});
            response.write(data);
            response.end();
        });
    });

    proxy.on('error', function (error) {
        console.log(`Problem with proxy request: ${error.message}`);
        response.writeHead(500);
        response.end();
    });

    proxy.end();
}

function randomNumber (min, max) {
    min = parseInt(min, 10);
    max = parseInt(max, 10);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function randomString (len) {
    const possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let text = '';
    for (let i = 0; i < len; i++) {
        text += possibleChars.charAt(Math.floor(Math.random() * possibleChars.length));
    }
    return text;
}

function generateOptions () {
    const result = [
          {
              'options': ['news', 'history']
            , 'message': ''
          }
        , {
              'options': []
            , 'message': 'У вас нет доступных опций.'
          }
    ][randomNumber(0, 1)];
    // return result;
    return {
          'options': ['news', 'history']
        , 'message': ''
    };
}

Комментариев нет:

Отправить комментарий