This commit is contained in:
zuiidea
2016-10-08 22:31:19 +08:00
parent ad92f03f2d
commit 62cccd4154
19 changed files with 229 additions and 264 deletions
+1
View File
@@ -0,0 +1 @@
src/**/*-test.js
+6 -2
View File
@@ -1,6 +1,6 @@
{
"extends": "eslint-config-airbnb",
"parser": "babel-eslint",
"extends": "eslint-config-airbnb",
"rules": {
"spaced-comment": [0],
"no-unused-vars": [0],
@@ -12,7 +12,11 @@
"react/prop-types": [0],
"arrow-body-style": [0],
"react/prefer-stateless-function": [0],
"semi": [0]
"semi": [0],
"global-require": [0],
"no-shadow": [0],
"no-useless-computed-key": [0],
"no-underscore-dangle": [0]
},
"ecmaFeatures": {
"experimentalObjectRestSpread": true
+2 -13
View File
@@ -1,14 +1,3 @@
# Intellij
.idea
*.iml
*.iws
# Mac
.DS_Store
# node
node_modules
npm-debug.log
#other
dist
node_modules
.DS_Store
-18
View File
@@ -1,18 +0,0 @@
{
"propertyOrdering": false,
"hexLength": "short",
"stringQuotes": false,
"decimalZero": false,
"importantRule": false,
"zeroUnit": "no_unit",
"qualifyingElement": false,
"duplicateProperty": false,
"importPath": false,
"finalNewline": false,
"spaceAroundComma": false,
"fileExtensions": [".less", ".css"],
"excludedFiles": [
"test.less"
]
}
-15
View File
@@ -1,15 +0,0 @@
{
"extends": "stylelint-config-standard",
"rules": {
"string-quotes": "single",
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": [
"global",
"local"
]
}
]
}
}
+24 -57
View File
@@ -1,63 +1,30 @@
{
"name": "antd-admin",
"version": "1.0.0",
"description": "React Admin Boilerplate, with React + Ant Design",
"license": "Apache-2.0",
"engines": {
"node": ">=5.0 <7",
"npm": ">=3.3 <4"
},
"keywords": [
"ant",
"react",
"admin",
"frontend"
],
"devDependencies": {
"antd": "1.10.0",
"babel-core": "6.4.5",
"babel-eslint": "6.0.0",
"babel-loader": "6.2.1",
"babel-plugin-antd": "0.4.0",
"babel-polyfill": "6.9.1",
"babel-preset-es2015": "6.3.13",
"babel-preset-react": "6.3.13",
"babel-preset-stage-0": "6.5.0",
"css-loader": "^0.25.0",
"eslint": "2.7.0",
"eslint-config-airbnb": "6.x",
"eslint-plugin-react": "4.x",
"file-loader": "0.9.0",
"html-webpack-plugin": "^2.22.0",
"less": "2.7.1",
"less-loader": "^2.2.3",
"lesshint": "2.0.2",
"react": "15.0.2",
"react-cookie": "0.4.7",
"react-dom": "15.0.2",
"react-hot-loader": "1.3.0",
"react-router": "2.0.1",
"reqwest": "^2.0.5",
"strip-loader": "0.1.2",
"style-loader": "0.13.1",
"stylelint": "6.6.0",
"stylelint-config-standard": "9.0.0",
"url-loader": "0.5.7",
"webpack": "1.12.12",
"webpack-dev-server": "1.14.1"
"private": true,
"entry": {
"index": "./src/index.js"
},
"dependencies": {
"extract-text-webpack-plugin": "^1.0.1",
"superagent": "2.0.0",
"whatwg-fetch": "^1.0.0"
"dva": "^1.0.0",
"react": "^15.1.0",
"react-dom": "^15.1.0"
},
"devDependencies": {
"atool-build": "^0.7.6",
"atool-test-mocha": "^0.1.5",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-dva-hmr": "^0.1.0",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-runtime": "^6.9.2",
"dora": "0.3.x",
"dora-plugin-proxy": "^0.7.0",
"dora-plugin-webpack": "0.6.x",
"dora-plugin-webpack-hmr": "^0.1.0",
"expect": "^1.20.2",
"redbox-react": "^1.2.10"
},
"scripts": {
"build": "webpack --progress --colors --display-error-details",
"prod": "set NODE_ENV=production&&webpack --progress --colors --config webpack.config.prod.js -p --display-error-details",
"clean": "rd /s /q dist",
"dev": "webpack-dev-server --devtool eval --progress --colors --content-base dist --hot --inline --display-error-details",
"eslint": "eslint --ext .js,.jsx src/view",
"stylelint": "stylelint \"src/**/*.css\"",
"lesshint": "lesshint src/"
"start": "dora --plugins \"proxy,webpack,webpack-hmr\"",
"build": "atool-build",
"test": "atool-test-mocha ./src/**/*-test.js"
}
}
}
+10
View File
@@ -0,0 +1,10 @@
'use strict';
const mock = {};
require('fs').readdirSync(require('path').join(__dirname + '/mock'))
.forEach(function (file) {
Object.assign(mock, require('./mock/' + file));
});
module.exports = mock;
+14
View File
@@ -0,0 +1,14 @@
import React from 'react';
const Example = (props) => {
return (
<div>
Example
</div>
);
};
Example.propTypes = {
};
export default Example;
+10 -8
View File
@@ -1,14 +1,16 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Ant Design Admin</title>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div id="view" style="height:100%"></div>
<script src="http://localhost:8080/webpack-dev-server.js"></script>
<div id="root"></div>
<script src="common.js"></script>
<script src="index.js"></script>
</body>
</html>
+15 -24
View File
@@ -1,27 +1,18 @@
import React from 'react'
import ReactDOM from 'react-dom'
import {Router, Route, IndexRoute,IndexRedirect,Redirect,hashHistory} from 'react-router'
import './utils/index.js'
import './index.html';
import './index.less';
import dva from 'dva';
import App from './view/index'
import SignIn from './view/user/signIn'
import List from './view/data/list'
import Dashboard from './view/user/dashboard'
import Error from './view/common/error'
import './utils/lib.less'
// 1. Initialize
const app = dva();
const routes = (
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRedirect to="/dashboard" />
<Route path="dashboard" tableName="dashboard" component={Dashboard}/>
<Route path="index">
<Route path="list" tableName="list" component={List}/>
</Route>
<Route path="error" tableName="error" component={Error}/>
<Redirect from="*" to="error" />
</Route>
</Router>
)
// 2. Plugins
//app.use({});
ReactDOM.render(routes, document.getElementById('view'))
// 3. Model
//app.model(require('./models/example'));
// 4. Router
app.router(require('./router'));
// 5. Start
app.start('#root');
+24
View File
@@ -0,0 +1,24 @@
export default {
namespace: 'example',
state: {},
subscriptions: {
setup({ dispatch, history }) {
},
},
effects: {
*fetchRemote({ payload }, { call, put }) {
},
},
reducers: {
fetch(state, action) {
return { ...state, ...action.payload };
},
},
}
+11
View File
@@ -0,0 +1,11 @@
import React, { PropTypes } from 'react';
import { Router, Route, IndexRoute, Link } from 'dva/router';
import IndexPage from './routes/IndexPage';
export default function({ history }) {
return (
<Router history={history}>
<Route path="/" component={IndexPage} />
</Router>
);
};
+22
View File
@@ -0,0 +1,22 @@
import React, { Component, PropTypes } from 'react';
import { connect } from 'dva';
import { Link } from 'dva/router';
import styles from './IndexPage.less';
function IndexPage() {
return (
<div className={styles.normal}>
<h1>Welcome to dva!</h1>
<hr />
<ul className={styles.list}>
<li>To get started, edit <code>src/index.js</code> and save to reload.</li>
<li><a href="https://github.com/sorrycc/blog/issues/8" target="_blank">Getting Started</a></li>
</ul>
</div>
);
}
IndexPage.propTypes = {
};
export default connect()(IndexPage);
+8
View File
@@ -0,0 +1,8 @@
.normal {
margin: 100px;
}
.list {
margin-top: 20px;
}
+5
View File
@@ -0,0 +1,5 @@
import request from '../utils/request';
export async function query() {
return request('/api/users');
}
+11
View File
@@ -0,0 +1,11 @@
import expect from 'expect';
import example from '../../models/example';
describe('example', () => {
describe('reducer', () => {
it('it should save', () => {
expect(example.reducers['example/save']({}, { payload: { a: 1 }})).toEqual({ a: 1 });
});
})
});
+30
View File
@@ -0,0 +1,30 @@
import fetch from 'dva/fetch';
function parseJSON(response) {
return response.json();
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then((data) => ({ data }))
.catch((err) => ({ err }));
}
+36 -61
View File
@@ -1,66 +1,41 @@
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const fs = require('fs');
const path = require('path');
const babelLoaderConfig = {
presets: ['es2015', 'stage-0', 'react'],
plugins: [
['antd', {
'style': true
}]
],
};
module.exports = function(webpackConfig, env) {
webpackConfig.babel.plugins.push('transform-runtime');
module.exports = {
entry: [
'webpack-dev-server/client?http://0.0.0.0:8080',
'webpack/hot/only-dev-server',
'babel-polyfill',
'./src/index.js'
],
// Support hmr
if (env === 'development') {
webpackConfig.devtool = '#eval';
webpackConfig.babel.plugins.push(['dva-hmr', {
entries: [
'./src/index.js',
],
}]);
} else {
webpackConfig.babel.plugins.push('dev-expression');
}
output: {
path: __dirname + '/dist',
filename: 'bundle.js',
},
// Support CSS Modules
// Parse all less files as css module.
webpackConfig.module.loaders.forEach(function(loader, index) {
if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
loader.include = /node_modules/;
loader.test = /\.less$/;
}
if (loader.test.toString() === '/\\.module\\.less$/') {
loader.exclude = /node_modules/;
loader.test = /\.less$/;
}
if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.css$') > -1) {
loader.include = /node_modules/;
loader.test = /\.css$/;
}
if (loader.test.toString() === '/\\.module\\.css$/') {
loader.exclude = /node_modules/;
loader.test = /\.css$/;
}
});
resolve: {
modulesDirectories: ['node_modules', './src'],
extensions: ['', '.js', '.jsx'],
alias: {
antdcss: 'antd/dist/antd.min.css',
},
},
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel-loader?' + JSON.stringify(babelLoaderConfig)],
exclude: /node_modules/,
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
}, {
test: /\.less$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
},
{
test: /\.(png|jpg|svg)$/,
loader: 'url?limit=25000',
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Ant Design Admin',
filename: 'index.html',
template: './src/index.html'
}),
new ExtractTextPlugin("[name].css"),
new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV === 'production' ? 'false' : 'true')),
}),
],
return webpackConfig;
};
-66
View File
@@ -1,66 +0,0 @@
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const babelLoaderConfig = {
presets: ['es2015', 'stage-0', 'react'],
plugins: [['antd', {'style': true}]],
};
module.exports = {
entry: [
'./src/index.js',
],
output: {
path: __dirname + '/dist',
filename: 'bundle.js',
// publicPath: 'http://mycdn.com/',
},
resolve: {
modulesDirectories: ['node_modules', './src'],
extensions: ['', '.js', '.jsx'],
},
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['babel-loader?' + JSON.stringify(babelLoaderConfig), 'strip-loader?strip[]=logger.debug,strip[]=console.log,strip[]=console.debug'],
exclude: /node_modules/,
},
{
test: /\.(png|jpg|svg)$/,
loader: 'url?limit=25000',
},{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
}, {
test: /\.less$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
},
],
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
minimize: true,
compress: {warnings: false},
}),
new HtmlWebpackPlugin({
title: 'Ant Design Admin',
filename: 'index.html',
template: './src/index.html'
}),
new ExtractTextPlugin("[name].css"),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
__DEV__: JSON.stringify(JSON.parse(process.env.NODE_ENV === 'production' ? 'false' : 'true')),
}),
],
};