diff --git a/package.json b/package.json index 87677d8..321f5dc 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "intl-messageformat": "^1.1.0", "react": "^0.14.0", "react-dom": "^0.14.3", - "react-intl": "^2.0.0-beta-2", + "react-intl": "^2.0.0-pr-3", "react-redux": "^4.0.0", "react-router": "^2.0.0-rc4", "redux": "^3.0.4", @@ -28,7 +28,6 @@ "redux-thunk": "^1.0.0" }, "devDependencies": { - "autoprefixer-loader": "^2.0.0", "babel-core": "^6.0.0", "babel-eslint": "^5.0.0-beta6", "babel-loader": "^6.0.0", @@ -40,30 +39,32 @@ "babel-runtime": "^5.6.15", "chai": "^3.0.0", "chokidar": "^1.2.0", - "css-loader": "^0.9.1", + "css-loader": "^0.23.0", + "cssnano": "^3.4.0", "eslint": "^1.10.3", "eslint-plugin-react": "^3.13.1", "extract-text-webpack-plugin": "^0.9.1", "html-webpack-plugin": "^1.7.0", "imports-loader": "^0.6.4", - "karma": "^0.13.0", - "karma-chai": "^0.1.0", - "karma-es5-shim": "^0.0.4", - "karma-mocha": "^0.1.10", - "karma-nyan-reporter": "^0.0.60", - "karma-phantomjs-launcher": "^0.2.1", + "karma": "*", + "karma-chai": "*", + "karma-es5-shim": "*", + "karma-mocha": "^0.2.1", + "karma-nyan-reporter": "^0.2.3", + "karma-phantomjs-launcher": "*", "karma-sinon": "^1.0.4", - "karma-sourcemap-loader": "^0.3.6", + "karma-sourcemap-loader": "*", "karma-webpack": "^1.5.1", "less": "^2.4.0", "less-loader": "^2.0.0", "mocha": "^2.2.5", "node-sass": "^3.4.2", "phantomjs": "^1.9.18", + "postcss-loader": "^0.8.0", "react-addons-test-utils": "^0.14.3", "sass-loader": "^3.1.2", "sinon": "^1.15.3", - "style-loader": "^0.8.3", + "style-loader": "^0.13.0", "webpack": "^1.12.9", "webpack-dev-server": "^1.14.0" } diff --git a/src/index.js b/src/index.js index 9c8437d..b05bd16 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,15 @@ import 'babel-polyfill'; import React from 'react'; import ReactDOM from 'react-dom'; -import { createStore, combineReducers } from 'redux'; +import { createStore, combineReducers, applyMiddleware } from 'redux'; import { Provider as ReduxProvider } from 'react-redux'; +// midleware, который позволяет возвращать из экшенов функции +// это полезно для работы с асинхронными действиями, +// а также дает возможность проверить какие-либо условия перед запуском экшена +// или даже вообще его не запускать в зависимости от условий +import thunk from 'redux-thunk'; + import { Router, browserHistory } from 'react-router'; import { syncReduxAndRouter, routeReducer } from 'redux-simple-router'; @@ -18,7 +24,10 @@ const reducer = combineReducers({ ...reducers, routing: routeReducer }); -const store = createStore(reducer); + +const store = applyMiddleware( + thunk +)(createStore)(reducer); syncReduxAndRouter(browserHistory, store); diff --git a/src/index.scss b/src/index.scss new file mode 100644 index 0000000..fb273bb --- /dev/null +++ b/src/index.scss @@ -0,0 +1,3 @@ +.testClass { + background: #f00; +} diff --git a/src/routes.js b/src/routes.js index 250d2cd..e9a8d43 100644 --- a/src/routes.js +++ b/src/routes.js @@ -4,6 +4,8 @@ import { Link } from 'react-router'; import { FormattedMessage } from 'react-intl'; +import styles from 'index.scss'; + function CoreLayout(props) { return (
@@ -23,7 +25,7 @@ function HomeView() { return (
Home! - Auth + Auth
); } diff --git a/webpack.config.js b/webpack.config.js index 74f817e..c902835 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,11 +4,14 @@ var path = require('path'); var webpack = require('webpack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); +var cssnano = require('cssnano'); const API_HOST = 'http://account.l'; // TODO: https://babeljs.io/docs/plugins/ // TODO: отдельные конфиги для env (аля https://github.com/davezuko/react-redux-starter-kit) +// https://github.com/glenjamin/ultimate-hot-reloading-example ( обратить внимание на плагины babel ) +// https://github.com/gajus/react-css-modules ( + BrowserSync) var isProduction = process.argv.some(function(arg) { return arg === '-p'; @@ -18,6 +21,8 @@ var isTest = process.argv.some(function(arg) { return arg.indexOf('karma') !== -1; }); +const CSS_LOADER = 'style!css?modules&importLoaders=1&localIdentName=[path][name]-[local]!postcss'; + var webpackConfig = { entry: { app: path.join(__dirname, 'src'), @@ -90,7 +95,7 @@ var webpackConfig = { { test: /\.scss$/, extractInProduction: true, - loader: 'style!css!autoprefixer?browsers=last 3 versions!sass' + loader: CSS_LOADER + '!sass' }, { test: /\.jsx?$/, @@ -103,16 +108,31 @@ var webpackConfig = { }, { // DEPRECATED test: /i18n\/.*\.less$/, - loader: 'style!css!autoprefixer?browsers=last 3 versions!less' + loader: CSS_LOADER + '!less' }, { // DEPRECATED test: /\.less$/, extractInProduction: true, exclude: /i18n\/.*\.less$/, - loader: 'style!css!autoprefixer?browsers=last 3 versions!less' + loader: CSS_LOADER + '!less' } ] - } + }, + + postcss: [ + cssnano({ + sourcemap: !isProduction, + autoprefixer: { + add: true, + remove: true, + browsers: ['last 2 versions'] + }, + safe: true, + discardComments: { + removeAll: true + } + }) + ] }; @@ -124,7 +144,7 @@ if (isProduction) { } }); - webpackConfig.plugins.push(new ExtractTextPlugin('dist/styles.css', { + webpackConfig.plugins.push(new ExtractTextPlugin('styles.css', { allChunks: true }));