diff --git a/Makefile b/Makefile deleted file mode 100644 index 3589102..0000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -webpack = webpack - -NODE_ENV ?= development -PORT ?= 8889 - -ifeq ($(NODE_ENV), development) - WEBPACK_FILE = dev -else - WEBPACK_FILE = prod -endif - -clean: - rm -rf build/ - -build: clean - webpack --config config/webpack/$(WEBPACK_FILE).js - webpack --config config/webpack/server.js - -start: build - node build/server.js \ No newline at end of file diff --git a/README.md b/README.md index efdb3b2..34625bb 100644 --- a/README.md +++ b/README.md @@ -22,36 +22,37 @@ Vortigern uses the following libraries and tools: - [React-Router-Redux](https://github.com/reactjs/react-router-redux) to keep application state sync with route changes. #### Utilities -- [classnames](https://github.com/JedWatson/classnames) -- [Redux Thunk](https://github.com/gaearon/redux-thunk) for dispatching async actions. - [Isomorphic Fetch](https://github.com/matthew-andrews/isomorphic-fetch) with [ES6-Promise](https://github.com/stefanpenner/es6-promise) for using fetch api on both client & server side. +- [Redux Thunk](https://github.com/gaearon/redux-thunk) for dispatching async actions. +- [Redux Connect](https://github.com/makeomatic/redux-connect) for resolving async props in react-router. - [React Helmet](https://github.com/nfl/react-helmet) +- [classnames](https://github.com/JedWatson/classnames) #### Build System - [Webpack](https://github.com/webpack/webpack) for bundling. - - [TypeScript Loader](https://github.com/andreypopp/typescript-loader) as ts loader. - - [Babel Loader](https://github.com/babel/babel-loader) as js loader. - - [React Hot Loader](https://github.com/gaearon/react-hot-loader) for providing hot reload capability to our development server - - [Isomorphic Style Loader](https://github.com/kriasoft/isomorphic-style-loader) for loading styles on server-side. - - [Style Loader](https://github.com/webpack/style-loader) - - [CSS Loader](https://github.com/webpack/css-loader) - - [PostCSS Loader](https://github.com/postcss/postcss) - - [Autoprefixer](https://github.com/postcss/autoprefixer) - - [PreCSS](https://github.com/jonathantneal/precss) - - [PostCSS Assets](https://github.com/assetsjs/postcss-assets) - - [JSON Loader](https://github.com/webpack/json-loader) - - [File Loader](https://github.com/webpack/file-loader) & [URL Loader](https://github.com/webpack/url-loader) - - [SourceMap Loader](https://github.com/webpack/source-map-loader) - - [Manifest Plugin](https://github.com/danethurber/webpack-manifest-plugin) - - [Extract Text Plugin](https://github.com/webpack/extract-text-webpack-plugin) for exporting bundled css. - - [Tslint Loader](https://github.com/wbuchwalter/tslint-loader) for using tslint as preloader on build process. - - [Stylelint Loader](https://github.com/adrianhall/stylelint-loader) for using stylelint as preloader on build process. - - [Istanbul Instrumenter Loader](https://github.com/deepsweet/istanbul-instrumenter-loader) for using istanbul on postload process while generating code coverage reports. + - [TypeScript Loader](https://github.com/andreypopp/typescript-loader) as ts loader. + - [Babel Loader](https://github.com/babel/babel-loader) as js loader. + - [React Hot Loader](https://github.com/gaearon/react-hot-loader) for providing hot reload capability to our development server + - [Isomorphic Style Loader](https://github.com/kriasoft/isomorphic-style-loader) for loading styles on server-side. + - [Style Loader](https://github.com/webpack/style-loader) + - [CSS Loader](https://github.com/webpack/css-loader) + - [PostCSS Loader](https://github.com/postcss/postcss) + - [PostCSS cssnext](https://github.com/MoOx/postcss-cssnext) + - [PostCSS Assets](https://github.com/assetsjs/postcss-assets) + - [JSON Loader](https://github.com/webpack/json-loader) + - [File Loader](https://github.com/webpack/file-loader) + - [URL Loader](https://github.com/webpack/url-loader) + - [Sourcemap Loader](https://github.com/webpack/source-map-loader) + - [Manifest Plugin](https://github.com/danethurber/webpack-manifest-plugin) + - [Extract Text Plugin](https://github.com/webpack/extract-text-webpack-plugin) for exporting bundled css. + - [tslint Loader](https://github.com/wbuchwalter/tslint-loader) for using tslint as preloader on build process. + - [stylelint Loader](https://github.com/adrianhall/stylelint-loader) for using stylelint as preloader on build process. + - [Istanbul Instrumenter Loader](https://github.com/deepsweet/istanbul-instrumenter-loader) for using istanbul on postload process while generating code coverage reports. #### Dev & Prod Server - [Webpack Dev Server](https://github.com/webpack/webpack-dev-server) - - [Webpack Dev Middleware](https://github.com/webpack/webpack-dev-middleware) - - [Webpack Hot Middleware](https://github.com/webpack/webpack-hot-middleware) + - [Webpack Dev Middleware](https://github.com/webpack/webpack-dev-middleware) + - [Webpack Hot Middleware](https://github.com/webpack/webpack-hot-middleware) - [Express](https://github.com/expressjs/express) for running server both on client and server side. - [Compression](https://github.com/expressjs/compression) for gzip compression - [Serve Favicon](https://github.com/expressjs/serve-favicon) for serving favicon. @@ -65,11 +66,17 @@ Vortigern uses the following libraries and tools: - [Chalk](https://github.com/chalk/chalk) for colored terminal logs. #### Testing -- [Karma](https://github.com/karma-runner/karma) as test runner. +- [Karma](https://github.com/karma-runner/karma) as test runner with following plugins + - [Karma-Webpack](https://github.com/webpack/karma-webpack) + - [Karma-Mocha](https://github.com/karma-runner/karma-mocha) + - [Karma-Chai](https://github.com/xdissent/karma-chai) + - [Karma-Coverage](https://github.com/karma-runner/karma-coverage) + - [Karma-PhantomJS Launcher](https://github.com/karma-runner/karma-phantomjs-launcher) - [Mocha](https://github.com/mochajs/mocha) as testing framework. - [Chai](https://github.com/chaijs/chai) as assertion library. - [Enzyme](https://github.com/jquery/jquery) for rendering React Components. -- [Karma-Webpack](https://github.com/webpack/karma-webpack), [Karma-Mocha](https://github.com/karma-runner/karma-mocha), [Karma-Chai](https://github.com/xdissent/karma-chai), [Karma-Coverage](https://github.com/karma-runner/karma-coverage), [Karma-PhantomJS Launcher](https://github.com/karma-runner/karma-phantomjs-launcher) as Karma plugins. +- [Fetch Mock](https://github.com/wheresrhys/fetch-mock) for testing async actions. +- [Redux Mock Store](https://github.com/arnaudbenard/redux-mock-store) for creating mock stores. ## Folder Structure ```bash @@ -99,9 +106,8 @@ Vortigern uses the following libraries and tools: ├── .stylelintrc # Configures stylelint. ├── Dockerfile # Dockerfile. ├── favicon.ico # Favicon. -├── Makefile # Makefile. ├── package.json # Package configuration. -├── README.md # Readme. +├── README.md # This file ├── tsconfig.json # TypeScript transpiler configuration. ├── tslint.json # Configures tslint. └── typings.json # Typings package configuration. @@ -111,27 +117,36 @@ Vortigern uses the following libraries and tools: ```bash $ git clone https://github.com/barbar/vortigern $ cd vortigern -$ npm run setup +$ npm install ``` ## Usage -All commands defaults to development environment. +All commands defaults to development environment. You can set `NODE_ENV` to `production` or use the shortcuts below. ```bash -# Running the app on development mode -$ npm start +# Running -# Building for production -$ npm run build:prod +$ npm start # This starts the app in development mode -# Running app on production mode +# Starting it with the production build +$ NODE_ENV=production npm start # or $ npm run start:prod -# Running unit tests -$ npm run test +# Building + +$ npm build # This builds the app in development mode + +# Commands below builds the production build +$ NODE_ENV=production npm build # or +$ npm run build:prod + +# Testing +$ npm test ``` +For Windows users, we recommend using the shortcuts instead of setting environment variables because they work a little different on Windows. + ## Notes ```bash # If you want install additional libraries, you can also install their typings from DefinitelyTyped @@ -140,6 +155,7 @@ $ typings install dt~ --global --save $ typings install --save ``` -## Credits +## Legal -The photo in this readme belongs to [hhvferry.com](http://www.hhvferry.com/vortscrap.html). +Vortigern is released under the MIT license. +The image in this README belongs to [hhvferry.com](http://www.hhvferry.com/vortscrap.html). diff --git a/config/test/karma.conf.js b/config/test/karma.conf.js index 90432b6..a14a3d1 100644 --- a/config/test/karma.conf.js +++ b/config/test/karma.conf.js @@ -1,7 +1,7 @@ +var path = require('path'); var webpack = require('webpack'); -var autoprefixer = require('autoprefixer'); -var precss = require('precss'); var postcssAssets = require('postcss-assets'); +var postcssNext = require('postcss-cssnext'); var appConfig = require('../main'); module.exports = function (config) { @@ -43,10 +43,16 @@ module.exports = function (config) { webpack: { devtool: 'inline-source-map', - module: { - noParse: [ - /node_modules\/sinon\// + resolve: { + root: path.resolve(__dirname), + modulesDirectories: [ + '../../src', + 'node_modules' ], + extensions: ['', '.json', '.js', '.ts', '.tsx', '.jsx'] + }, + + module: { loaders: [ { test: /\.tsx?$/, @@ -62,7 +68,7 @@ module.exports = function (config) { }, { test: /\.css$/, - include: /src\/app/, + include: path.resolve('./src/app'), loaders: [ 'style', 'css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]', @@ -71,7 +77,7 @@ module.exports = function (config) { }, { test: /\.css$/, - exclude: /src\/app/, + exclude: path.resolve('./src/app'), loader: 'style!css' } ], @@ -79,33 +85,18 @@ module.exports = function (config) { { test: /\.tsx?$/, loader: 'istanbul-instrumenter-loader', - include: /src\/app/, - exclude: [ - /node_modules/ - ] + include: path.resolve('./src/app') } ] }, postcss: function () { return [ - precss, - autoprefixer({ browsers: ['last 2 versions'] }), + postcssNext(), postcssAssets({ relative: true }) ]; }, - resolve: { - alias: { - sinon: 'sinon/pkg/sinon' - }, - modulesDirectories: [ - '../../src', - 'node_modules' - ], - extensions: ['', '.json', '.js', '.ts', '.tsx', '.jsx'] - }, - externals: { 'react/lib/ExecutionEnvironment': true, 'react/lib/ReactContext': 'window' diff --git a/config/webpack/dev.js b/config/webpack/dev.js index b435ed8..56a1efe 100644 --- a/config/webpack/dev.js +++ b/config/webpack/dev.js @@ -1,8 +1,7 @@ var path = require('path'); var webpack = require('webpack'); -var autoprefixer = require('autoprefixer'); -var precss = require('precss'); var postcssAssets = require('postcss-assets'); +var postcssNext = require('postcss-cssnext'); var stylelint = require('stylelint'); var ManifestPlugin = require('webpack-manifest-plugin'); @@ -12,13 +11,15 @@ var config = { debug: true, resolve: { + root: path.resolve(__dirname), extensions: ['', '.ts', '.tsx', '.js', '.jsx'] }, entry: { app: [ 'webpack-hot-middleware/client?reload=true', - './src/client.tsx' + './src/client.tsx', + './src/vendor/main.ts' ] }, @@ -51,17 +52,20 @@ var config = { }, { test: /\.css$/, - include: /src\/app/, + include: path.resolve('./src/app'), loaders: [ - 'style', - 'css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]', - 'postcss' + 'style-loader', + 'css-loader?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]', + 'postcss-loader' ] }, { test: /\.css$/, - exclude: /src\/app/, - loader: 'style!css' + exclude: path.resolve('./src/app'), + loaders: [ + 'style-loader', + 'css-loader' + ] }, { test: /\.eot(\?.*)?$/, @@ -85,12 +89,10 @@ var config = { } ] }, - postcss: function () { return [ stylelint({ files: '../../src/app/*.css' }), - precss, - autoprefixer({ browsers: ['last 2 versions'] }), + postcssNext(), postcssAssets({ relative: true }) ]; }, diff --git a/config/webpack/index.js b/config/webpack/index.js new file mode 100644 index 0000000..461405f --- /dev/null +++ b/config/webpack/index.js @@ -0,0 +1,7 @@ +'use strict'; + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./prod'); +} else { + module.exports = require('./dev'); +} diff --git a/config/webpack/prod.js b/config/webpack/prod.js index c45afc0..e4c52c9 100644 --- a/config/webpack/prod.js +++ b/config/webpack/prod.js @@ -1,21 +1,33 @@ var path = require('path'); var webpack = require('webpack'); -var autoprefixer = require('autoprefixer'); -var precss = require('precss'); var postcssAssets = require('postcss-assets'); +var postcssNext = require('postcss-cssnext'); var stylelint = require('stylelint'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); var ManifestPlugin = require('webpack-manifest-plugin'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); var config = { bail: true, resolve: { + root: path.resolve(__dirname), extensions: ['', '.ts', '.tsx', '.js', '.jsx'] }, entry: { - app: './src/client.tsx' + app: './src/client.tsx', + vendor: [ + './src/vendor/main.ts', + 'react', + 'react-dom', + 'react-router', + 'react-helmet', + 'react-redux', + 'react-router-redux', + 'redux', + 'redux-connect', + 'redux-thunk' + ] }, output: { @@ -46,19 +58,19 @@ var config = { }, { test: /\.css$/, - include: /src\/app/, + include: path.resolve('./src/app'), loader: ExtractTextPlugin.extract( - 'style', - 'css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]', - 'postcss' + 'style-loader', + 'css-loader?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]', + 'postcss-loader' ) }, { test: /\.css$/, - exclude: /src\/app/, + exclude: path.resolve('./src/app'), loader: ExtractTextPlugin.extract( - 'style', - 'css' + 'style-loader', + 'css-loader' ) }, { @@ -87,20 +99,25 @@ var config = { postcss: function () { return [ stylelint({ files: '../../src/app/*.css' }), - precss, - autoprefixer({ browsers: ['last 2 versions'] }), + postcssNext(), postcssAssets({ relative: true }) ]; }, plugins: [ + new webpack.optimize.OccurrenceOrderPlugin(), + new webpack.optimize.DedupePlugin(), + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + filename: 'js/[name].[chunkhash].js', + minChunks: Infinity + }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), new ExtractTextPlugin('css/[name].[hash].css'), - new webpack.optimize.DedupePlugin(), new ManifestPlugin({ fileName: '../manifest.json' }), diff --git a/config/webpack/server.js b/config/webpack/server.js index e7569a4..310febc 100644 --- a/config/webpack/server.js +++ b/config/webpack/server.js @@ -15,7 +15,7 @@ var config = { target: 'node', resolve: { - extensions: ["", '.ts', '.tsx', '.js', '.jsx'] + extensions: ['', '.ts', '.tsx', '.js', '.jsx'] }, entry: './src/server.tsx', @@ -48,10 +48,9 @@ var config = { }, { test: /\.css$/, - include: /src\/app/, loaders: [ 'isomorphic-style-loader', - 'css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]' + 'css-loader?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]' ] } ] diff --git a/package.json b/package.json index e319b1b..f5b29aa 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,18 @@ { "name": "vortigern", - "version": "0.0.2", + "version": "0.1.0", "description": "A universal boilerplate for building web applications w/ TypeScript, React, Redux and more.", "main": "build/server.js", "scripts": { - "setup": "npm install && typings install", - "build": "make build:dev", - "build:prod": "cross-env NODE_ENV=production make build", - "build:dev": "cross-env NODE_ENV=development make build", - "start": "npm run start:dev", - "start:prod": "cross-env NODE_ENV=production make start", - "start:dev": "cross-env NODE_ENV=development make start", + "postinstall": "typings install", + "clean": "rm -rf build/", + "prebuild": "npm run clean", + "build": "webpack --config config/webpack/index.js", + "build:prod": "cross-env NODE_ENV=production npm run build", + "postbuild": "webpack --config config/webpack/server.js", + "prestart": "npm run build", + "start": "node build/server.js", + "start:prod": "cross-env NODE_ENV=production npm start", "test": "node_modules/.bin/karma start config/test/karma.conf.js" }, "author": "Barbar Startup Factory ", @@ -24,6 +26,11 @@ "name": "Batuhan Icoz", "email": "hey@batuhanicoz.com", "url": "http://batuhanicoz.com/" + }, + { + "name": "Omer Ufuk Efendioglu", + "email": "ufukomer@gmail.com", + "url": "http://ufukomer.com/" } ], "homepage": "https://github.com/barbar/vortigern.git", @@ -52,7 +59,6 @@ ], "license": "MIT", "devDependencies": { - "autoprefixer": "^6.3.6", "babel-core": "^6.7.7", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.6.0", @@ -63,13 +69,9 @@ "cross-env": "^1.0.8", "css-loader": "^0.23.1", "enzyme": "^2.3.0", - "es6-promise": "^3.1.2", - "express": "^4.13.4", "extract-text-webpack-plugin": "^1.0.1", "fetch-mock": "^4.5.4", "file-loader": "^0.8.5", - "history": "^2.1.0", - "isomorphic-fetch": "^2.2.1", "isomorphic-style-loader": "^1.0.0", "istanbul-instrumenter-loader": "^0.2.0", "json-loader": "^0.5.4", @@ -81,24 +83,19 @@ "karma-mocha": "^1.0.1", "karma-mocha-reporter": "^2.0.2", "karma-phantomjs-launcher": "^1.0.0", - "karma-sinon": "^1.0.4", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^1.7.0", "mocha": "^2.4.5", "phantomjs-prebuilt": "^2.1.7", "postcss-assets": "^4.1.0", + "postcss-cssnext": "^2.6.0", "postcss-loader": "^0.9.1", - "postcss-scss": "^0.1.7", - "precss": "^1.4.0", "react-addons-test-utils": "^15.0.1", - "react-helmet": "^3.0.2", "react-hot-loader": "^1.3.0", "redux-logger": "^2.6.1", "redux-mock-store": "^1.1.0", - "redux-thunk": "^2.0.1", "rimraf": "^2.5.2", "serve-favicon": "^2.3.0", - "sinon": "^1.17.4", "source-map-loader": "^0.1.5", "style-loader": "^0.13.1", "stylelint": "^6.2.2", @@ -115,11 +112,18 @@ "webpack-manifest-plugin": "^1.0.1" }, "dependencies": { + "es6-promise": "^3.1.2", + "express": "^4.13.4", + "history": "^2.1.0", + "isomorphic-fetch": "^2.2.1", "react": "^15.0.1", "react-dom": "^15.0.1", + "react-helmet": "^3.0.2", "react-redux": "^4.4.5", "react-router": "^2.3.0", "react-router-redux": "^4.0.5", - "redux": "^3.5.2" + "redux": "^3.5.2", + "redux-connect": "^2.4.0", + "redux-thunk": "^2.0.1" } } diff --git a/src/app/components/Header/Header.tsx b/src/app/components/Header/Header.tsx index fd91c3f..426fa03 100644 --- a/src/app/components/Header/Header.tsx +++ b/src/app/components/Header/Header.tsx @@ -1,19 +1,21 @@ import * as React from 'react'; import { Link } from 'react-router'; -export class Header extends React.Component { - render() { +class Header extends React.Component { + render() { const s = require('./style.css'); - return ( - + ); + } } + +export { Header } diff --git a/src/app/containers/About/About.test.tsx b/src/app/containers/About/About.test.tsx index 210eb64..36e20f8 100644 --- a/src/app/containers/About/About.test.tsx +++ b/src/app/containers/About/About.test.tsx @@ -4,11 +4,7 @@ import { About } from './About'; describe('', () => { - let component; - - beforeEach(() => { - component = renderComponent(About); - }); + const component = renderComponent(About); it('Renders with correct style', () => { const s = require('./style.css'); diff --git a/src/app/containers/About/About.tsx b/src/app/containers/About/About.tsx index 45cf315..b196058 100644 --- a/src/app/containers/About/About.tsx +++ b/src/app/containers/About/About.tsx @@ -1,12 +1,14 @@ import * as React from 'react'; const s = require('./style.css'); -export class About extends React.Component { - render() { - return ( -
-

About

-
- ); - } +class About extends React.Component { + render() { + return ( +
+

About

+
+ ); + } } + +export { About } diff --git a/src/app/containers/App/App.test.tsx b/src/app/containers/App/App.test.tsx index 66fbeeb..b968b6a 100644 --- a/src/app/containers/App/App.test.tsx +++ b/src/app/containers/App/App.test.tsx @@ -4,11 +4,7 @@ import { App } from './App'; describe('', () => { - let component; - - beforeEach(() => { - component = renderComponent(App); - }); + const component = renderComponent(App); it('Renders with correct style', () => { const s = require('./style.css'); diff --git a/src/app/containers/App/App.tsx b/src/app/containers/App/App.tsx index 2afe178..17b5897 100644 --- a/src/app/containers/App/App.tsx +++ b/src/app/containers/App/App.tsx @@ -3,16 +3,18 @@ import * as React from 'react'; import * as Helmet from 'react-helmet'; import { Header } from '../../components'; -export class App extends React.Component { - render() { +class App extends React.Component { + render() { const s = require('./style.css'); - return ( -
- -
- {this.props.children} -
- ); - } + return ( +
+ +
+ {this.props.children} +
+ ); + } } + +export { App } diff --git a/src/app/containers/Counter/Counter.test.tsx b/src/app/containers/Counter/Counter.test.tsx index 791c7ca..f6175b5 100644 --- a/src/app/containers/Counter/Counter.test.tsx +++ b/src/app/containers/Counter/Counter.test.tsx @@ -1,23 +1,19 @@ import { expect } from 'chai'; -import * as sinon from 'sinon'; import { renderComponent } from '../../helpers/TestHelper'; import { Counter } from './Counter'; +/** Mock App. State */ +const state: Object = { + counter: { count: 1 } +}; + describe('', () => { - let component; - let increment; - let decrement; + let component; - beforeEach(() => { - increment = sinon.spy(); - decrement = sinon.spy(); - component = renderComponent(Counter, { - increment, - decrement, - counter: { count: 1 } - }); - }); + beforeEach(() => { + component = renderComponent(Counter, state); + }); it('Renders with correct style', () => { const s = require('./style.css'); @@ -37,15 +33,15 @@ describe('', () => { }); it('Calls the increment', () => { - expect(component.find({name:'incBtn'})).to.exist; - component.find({name:'incBtn'}).simulate('click'); - expect(increment.calledOnce).to.equal(true); + expect(component.find({ name: 'incBtn' })).to.exist; + component.find({ name: 'incBtn' }).simulate('click'); + expect(component.find('p').text()).to.eql('2'); }); it('Calls the decrement', () => { - expect(component.find({name:'decBtn'})).to.exist; - component.find({name:'decBtn'}).simulate('click'); - expect(decrement.calledOnce).to.equal(true); + expect(component.find({ name: 'decBtn' })).to.exist; + component.find({ name: 'decBtn' }).simulate('click'); + expect(component.find('p').text()).to.eql('0'); }); }); diff --git a/src/app/containers/Counter/Counter.tsx b/src/app/containers/Counter/Counter.tsx index 72d2b53..f4cb325 100644 --- a/src/app/containers/Counter/Counter.tsx +++ b/src/app/containers/Counter/Counter.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { connect } from 'react-redux'; import { increment, decrement } from '../../redux/modules/counter/counter'; import { ICounter } from '../../redux/modules/counter/counter.model'; +const { connect } = require('react-redux'); const s = require('./style.css'); interface IProps { @@ -10,42 +10,36 @@ interface IProps { decrement: Redux.ActionCreator; } -function mapStateToProps(state: any) { - return { - counter: state.counter - }; -} - -function mapDispatchToProps(dispatch: Redux.Dispatch) { - return { +@connect( + state => ({ counter: state.counter }), + dispatch => ({ increment: () => dispatch(increment()), decrement: () => dispatch(decrement()) - }; -} - -export class Counter extends React.Component { + }) +) +class Counter extends React.Component { - render() { - const { increment, decrement, counter } = this.props; + render() { + const { increment, decrement, counter } = this.props; - return ( -
-

Counter Example

- - -

{counter.count}

-
- ); - } +

{counter.count}

+ + ); + } } -export default connect(mapStateToProps, mapDispatchToProps)(Counter); +export { Counter } diff --git a/src/app/containers/Home/Home.test.tsx b/src/app/containers/Home/Home.test.tsx index a2feaed..42b8bbc 100644 --- a/src/app/containers/Home/Home.test.tsx +++ b/src/app/containers/Home/Home.test.tsx @@ -4,11 +4,7 @@ import { Home } from './Home'; describe('', () => { - let component; - - beforeEach(() => { - component = renderComponent(Home); - }); + const component = renderComponent(Home); it('Renders with correct style', () => { const s = require('./style.css'); diff --git a/src/app/containers/Home/Home.tsx b/src/app/containers/Home/Home.tsx index 452914b..e58ace6 100644 --- a/src/app/containers/Home/Home.tsx +++ b/src/app/containers/Home/Home.tsx @@ -1,13 +1,15 @@ import * as React from 'react'; const s = require('./style.css'); -export class Home extends React.Component { - render() { - return ( -
- -

Hello!

-
- ); - } +class Home extends React.Component { + render() { + return ( +
+ +

Hello!

+
+ ); + } } + +export { Home } diff --git a/src/app/containers/Html/Html.tsx b/src/app/containers/Html/Html.tsx index b2770e8..ad0fa8f 100644 --- a/src/app/containers/Html/Html.tsx +++ b/src/app/containers/Html/Html.tsx @@ -2,54 +2,56 @@ import * as React from 'react'; import * as Helmet from 'react-helmet'; interface HtmlProps { - manifest?: Object; - markup?: string; - store?: Redux.Store; + manifest?: Object; + markup?: string; + store?: Redux.Store; } -export class Html extends React.Component { - resolve(files) { +class Html extends React.Component { + resolve(files) { return files.map((src) => { if (!this.props.manifest[src]) { return; } - return 'public/' + this.props.manifest[src]; + return '/public/' + this.props.manifest[src]; }).filter((file) => file !== undefined); } - render() { - const head = Helmet.rewind(); - const { markup, store } = this.props; + render() { + const head = Helmet.rewind(); + const { markup, store } = this.props; - const styles = this.resolve(['vendor.css', 'app.css']); - const renderStyles = styles.map((src, i) => - - ); + const styles = this.resolve(['vendor.css', 'app.css']); + const renderStyles = styles.map((src, i) => + + ); - const scripts = this.resolve(['vendor.js', 'app.js']); - const renderScripts = scripts.map((src, i) => - - ); + const scripts = this.resolve(['vendor.js', 'app.js']); + const renderScripts = scripts.map((src, i) => + + ); - // tslint:disable-next-line:max-line-length - const initialState = (