├── .babelrc
├── README.md
├── .travis.yml
├── src
├── css
│ ├── BlockExample.css
│ └── TextBlockExample.css
├── containers
│ ├── App.js
│ ├── Test.js
│ └── Root.js
├── components
│ ├── BlockExample.js
│ └── TextBlockExample.js
└── index.js
├── webpack.config.prod.js
├── index.html
├── .editorconfig
├── .gitignore
├── server.js
├── .eslintrc
├── webpack.config.js
├── package.json
└── .stylelintrc
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["react-hot-loader/babel", "transform-decorators-legacy", "transform-runtime"],
3 | "presets": ["es2015", "react", "stage-0"]
4 | }
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-starter
2 |
3 |
4 | For information about this starter application, see https://medium.com/@olegafx/frontend-welcome-to-the-future-91ff064884b6
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | cache:
4 | directories:
5 | - ~/.npm
6 | - ~/.cache
7 | notifications:
8 | email: false
9 | node_js: '8'
10 |
--------------------------------------------------------------------------------
/src/css/BlockExample.css:
--------------------------------------------------------------------------------
1 | .blockFlex {
2 | display: flex;
3 | background-color: #444;
4 | margin-left: 45px;
5 | }
6 |
7 | .text {
8 | color: white;
9 | font-size: 3rem;
10 | }
11 |
--------------------------------------------------------------------------------
/src/css/TextBlockExample.css:
--------------------------------------------------------------------------------
1 | .blockFlex {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 |
7 | .text {
8 | font-size: 2rem;
9 | line-height: 1.5;
10 | color: #000000cc;
11 | }
--------------------------------------------------------------------------------
/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import Test from './Test';
4 |
5 | export default class Root extends Component {
6 | constructor (props) {
7 | super(props);
8 | }
9 |
10 | render () {
11 | return (
12 |
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/webpack.config.prod.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var config = require('./webpack.config');
3 |
4 | config.plugins.push(
5 | new webpack.DefinePlugin({
6 | 'process.env': {
7 | 'NODE_ENV': JSON.stringify('production')
8 | }
9 | })
10 | );
11 |
12 | module.exports = config;
13 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React starter project
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | max_line_length = 80
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | max_line_length = 0
15 | trim_trailing_whitespace = false
16 |
17 | [COMMIT_EDITMSG]
18 | max_line_length = 0
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ########## App ##########
2 | /dist/
3 | /log/
4 |
5 | ########## Jetbrains ##########
6 | .idea
7 |
8 | ########## Node ##########
9 | node_modules
10 | npm-debug.log
11 |
12 | ########## Temp files ##########
13 | # Windows
14 | Thumbs.db
15 | ehthumbs.db
16 | Desktop.ini
17 |
18 | # OSX
19 | .DS_Store
20 | .AppleDouble
21 | .LSOverride
22 | .Spotlight-V100
23 | .Trashes
24 |
--------------------------------------------------------------------------------
/src/components/BlockExample.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import styles from '../css/BlockExample.css';
4 |
5 | export default class TextBlockExample extends Component {
6 | constructor (props) {
7 | super(props);
8 | }
9 |
10 | render () {
11 | return (
12 |
13 | It works!
14 |
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/containers/Test.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import BlockExample from '../components/BlockExample';
4 | import TextBlockExample from '../components/TextBlockExample';
5 |
6 | export default class TestPage extends Component {
7 | constructor (props) {
8 | super(props);
9 | }
10 |
11 | render () {
12 | return (
13 |
14 |
15 |
16 |
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var WebpackDevServer = require('webpack-dev-server');
3 | var config = require('./webpack.config');
4 |
5 | new WebpackDevServer(webpack(config), {
6 | publicPath: config.output.publicPath,
7 | hot: true,
8 | historyApiFallback: true,
9 | stats: {
10 | assets: false,
11 | children: false,
12 | colors: true,
13 | version: false,
14 | hash: false,
15 | timings: false,
16 | chunks: false,
17 | chunkModules: false
18 | }
19 | })
20 | .listen(3000, 'localhost', function (err) {
21 | if (err) {
22 | console.log(err);
23 | }
24 |
25 | console.log('Listening at localhost:3000');
26 | });
27 |
--------------------------------------------------------------------------------
/src/components/TextBlockExample.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import styles from '../css/TextBlockExample.css';
4 |
5 | export default class TextBlockExample extends Component {
6 | constructor (props) {
7 | super(props);
8 | }
9 |
10 | componentDidMount () {
11 | this.getData();
12 | }
13 |
14 | async getData () {
15 | const rawData = await fetch('http://headers.jsontest.com/');
16 | const data = await rawData.json();
17 |
18 | console.log('data', data);
19 | }
20 |
21 | render () {
22 | return (
23 |
24 | text block example
25 |
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import { AppContainer } from 'react-hot-loader';
4 |
5 | import 'babel-polyfill';
6 | import 'whatwg-fetch';
7 |
8 | import Root from './containers/Root';
9 |
10 | const renderApp = () => {
11 | render(
12 |
13 |
14 | ,
15 | document.getElementById('root')
16 | );
17 | };
18 |
19 | renderApp();
20 |
21 | if (module.hot) {
22 | module.hot.accept('./containers/Root', () => {
23 | const NextApp = require('./containers/Root').default;
24 |
25 | render(
26 |
27 |
28 | ,
29 | document.getElementById('root')
30 | );
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import Match from 'react-router/Match';
4 | import Miss from 'react-router/Miss';
5 | import Link from 'react-router/Link';
6 | import Router from 'react-router/BrowserRouter';
7 |
8 | import App from './App';
9 |
10 | import BlockExample from '../components/BlockExample';
11 | import TextExample from '../components/TextBlockExample';
12 |
13 | const NoMatch = ({ location }) => (
14 |
15 |
Whoops
16 |
Sorry but {location.pathname} didn’t match any pages
17 |
18 | );
19 |
20 | const Root = () => (
21 |
22 |
23 |
24 | - Home
25 | - Block
26 | - Text
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | );
39 |
40 | export default Root;
41 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jquery": true,
6 | "node": true
7 | },
8 |
9 | "plugins": [
10 | "react"
11 | ],
12 |
13 | "ecmaFeatures": {
14 | "modules": true,
15 | "jsx": true
16 | },
17 |
18 | "parser": "babel-eslint",
19 |
20 | "rules": {
21 | "camelcase": [2, {"properties": "never"}],
22 | "eqeqeq": 2,
23 | "global-strict": 0,
24 | "indent": [2, 2],
25 | "jsx-quotes": [2, "prefer-double"],
26 | "max-params": [2, 3],
27 | "no-console": 0,
28 | "no-shadow": 1,
29 | "no-undef": 1,
30 | "no-underscore-dangle": 0,
31 | "no-use-before-define": 1,
32 | "no-var": 2,
33 | "quotes": [2, "single", "avoid-escape"],
34 | "object-shorthand": [2, "always"],
35 | "semi": 1,
36 | "strict": [1, "function"],
37 | "react/display-name": 0,
38 | "react/jsx-no-undef": 1,
39 | "react/jsx-uses-react": 1,
40 | "react/jsx-uses-vars": 1,
41 | "react/no-did-mount-set-state": 1,
42 | "react/no-did-update-set-state": 1,
43 | "react/no-multi-comp": 1,
44 | "react/no-unknown-property": 1,
45 | "react/prop-types": 1,
46 | "react/react-in-jsx-scope": 1,
47 | "react/self-closing-comp": 1,
48 | "react/wrap-multilines": 1
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var autoprefixer = require('autoprefixer');
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
4 |
5 | var path = require('path');
6 |
7 | module.exports = {
8 | entry: {
9 | 'index': [
10 | 'webpack-dev-server/client?http://0.0.0.0:3000',
11 | 'webpack/hot/only-dev-server',
12 | 'react-hot-loader/patch',
13 | './src/index'
14 | ]
15 | },
16 |
17 | output: {
18 | filename: '[name].js',
19 | path: path.join(__dirname, '/dist/'),
20 | publicPath: '/dist/'
21 | },
22 |
23 | module: {
24 | loaders: [
25 | {
26 | test: /\.css$/,
27 | loader: ExtractTextPlugin.extract('css-loader?modules&localIdentName=' + (process.env.NODE_ENV === 'production' ? '[hash:base64]' : '[name]__[local]___[hash:base64:5]') + '&importLoaders=1!postcss-loader') },
28 | {
29 | test: /\.js$/,
30 | loaders: ['babel-loader'],
31 | exclude: /node_modules/
32 | }
33 | ]
34 | },
35 |
36 | postcss: function () {
37 | return [autoprefixer];
38 | },
39 |
40 | resolve: {
41 | extensions: ['', '.jsx', '.js', '.json'],
42 | modulesDirectories: ['node_modules']
43 | },
44 |
45 | plugins: [
46 | new ExtractTextPlugin('index.css'),
47 | new webpack.optimize.OccurenceOrderPlugin(),
48 | new webpack.HotModuleReplacementPlugin(),
49 | new webpack.NoErrorsPlugin()
50 | ]
51 | };
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-starter",
3 | "version": "2.0.0",
4 | "description": "React starter project",
5 | "keywords": [
6 | "react",
7 | "bootstrap",
8 | "babel",
9 | "cssnext",
10 | "postcss"
11 | ],
12 | "author": "Oleg Kislitsyn",
13 | "license": "MIT",
14 | "repository": {
15 | "type": "git",
16 | "url": "git@git-ok:olegafx/dev.sm-tr.com.git"
17 | },
18 | "main": "src/index.js",
19 | "scripts": {
20 | "build": "./node_modules/.bin/webpack -p --bail --config ./webpack.config.prod.js",
21 | "start": "node server.js"
22 | },
23 | "pre-commit": [
24 | "lint-staged"
25 | ],
26 | "lint-staged": {
27 | "eslint": "*.js",
28 | "stylelint": "*.css"
29 | },
30 | "devDependencies": {
31 | "babel-eslint": "6.1.0",
32 | "eslint": "3.0.1",
33 | "eslint-plugin-react": "5.2.2",
34 | "stylelint": "6.8.0",
35 | "webpack-dev-server": "1.14.1",
36 | "why-did-you-update": "0.0.8"
37 | },
38 | "dependencies": {
39 | "autoprefixer": "6.4.1",
40 | "babel-core": "6.14.0",
41 | "babel-loader": "6.2.5",
42 | "babel-plugin-transform-decorators-legacy": "1.3.4",
43 | "babel-plugin-transform-runtime": "6.12.0",
44 | "babel-polyfill": "6.13.0",
45 | "babel-preset-es2015": "6.14.0",
46 | "babel-preset-react": "6.11.1",
47 | "babel-preset-stage-0": "6.5.0",
48 | "babel-runtime": "6.9.2",
49 | "css-loader": "0.25.0",
50 | "extract-text-webpack-plugin": "1.0.1",
51 | "lint-staged": "3.0.1",
52 | "lodash": "4.13.1",
53 | "postcss-loader": "0.13.0",
54 | "pre-commit": "1.1.3",
55 | "react": "15.3.1",
56 | "react-dom": "15.3.1",
57 | "react-hot-loader": "3.0.0-beta.3",
58 | "react-router": "4.0.0-2",
59 | "webpack": "1.13.2",
60 | "whatwg-fetch": "1.0.0"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "color-named": "never",
4 | "color-no-hex": true,
5 |
6 | "font-family-name-quotes": "always-where-recommended",
7 | "font-weight-notation": "numeric",
8 |
9 | "function-comma-newline-after": "never-multi-line",
10 | "function-comma-newline-before": "never-multi-line",
11 | "function-comma-space-after": "always",
12 | "function-comma-space-before": "never",
13 | "function-linear-gradient-no-nonstandard-direction": true,
14 | "function-name-case": "lower",
15 | "function-url-data-uris": "never",
16 | "function-url-quotes": "always",
17 | "function-whitespace-after": "always",
18 |
19 | "number-leading-zero": "always",
20 | "number-max-precision": 4,
21 | "number-no-trailing-zeros": true,
22 | "number-zero-length-no-unit": true,
23 |
24 | "string-no-newline": true,
25 | "string-quotes": "single",
26 |
27 | "time-no-imperceptible": true,
28 |
29 | "unit-blacklist": ["px", "em", "deg"],
30 | "unit-case": "lower",
31 | "unit-no-unknown": true,
32 |
33 | "value-no-vendor-prefix": true,
34 |
35 | "value-list-comma-newline-after": "never-multi-line",
36 | "value-list-comma-newline-before": "never-multi-line",
37 | "value-list-comma-space-after": "always",
38 | "value-list-comma-space-before": "never",
39 |
40 | "custom-property-no-outside-root": true,
41 |
42 | "property-case": "lower",
43 | "property-no-vendor-prefix": true,
44 |
45 | "keyframe-declaration-no-important": true,
46 |
47 | "declaration-block-no-duplicate-properties": [true, {
48 | ignore: ["consecutive-duplicates"]
49 | }],
50 |
51 | "indentation": 2,
52 | "max-empty-lines": 1,
53 | "max-line-length": 120,
54 | "max-nesting-depth": 1,
55 | "no-duplicate-selectors": true,
56 | "no-eol-whitespace": true,
57 | "no-extra-semicolons": true,
58 | "no-invalid-double-slash-comments": true,
59 | "no-missing-eof-newline": true,
60 | "no-unknown-animations": true,
61 | "selector-no-id": true
62 | }
63 | }
64 |
--------------------------------------------------------------------------------