diff --git a/demos/reactadmin/.babelrc b/demos/reactadmin/.babelrc
new file mode 100644
index 0000000..9b38634
--- /dev/null
+++ b/demos/reactadmin/.babelrc
@@ -0,0 +1,20 @@
+{
+ "presets": [
+ [ "env", { "modules": false } ],
+ "react",
+ "stage-0"
+ ],
+ "plugins": [
+ "react-hot-loader/babel",
+ "syntax-dynamic-import",
+ "transform-runtime",
+ [
+ "import", [ { "libraryName": "antd", "style": "css" } ]
+ ]
+ ],
+ "env": {
+ "test": {
+ "presets": [ "env", "react", "stage-0" ]
+ }
+ }
+}
diff --git a/demos/reactadmin/config/.eslintrc.js b/demos/reactadmin/config/.eslintrc.js
new file mode 100644
index 0000000..fd7cf78
--- /dev/null
+++ b/demos/reactadmin/config/.eslintrc.js
@@ -0,0 +1,62 @@
+module.exports = {
+ 'env': {
+ 'browser': true,
+ 'commonjs': true,
+ 'es6': true,
+ 'node': true
+ },
+ 'extends': 'airbnb',
+ 'globals': {},
+ 'parser': 'babel-eslint',
+ 'plugins': [
+ 'import',
+ 'jsx-a11y',
+ 'react'
+ ],
+ 'rules': {
+ /* ESLint 检查规则 */
+ /* @see https://eslint.org/docs/rules/ */
+ // Possible Errors
+ 'no-console': 'off', // 禁用 console
+ // Best Practices
+ 'eqeqeq': [2, 'allow-null'], // 要求使用 === 和 !==
+ 'no-param-reassign': 'off', // 禁止对 function 的参数进行重新赋值
+ // Variables
+ 'no-shadow-restricted-names': 'warn', // 禁止将标识符定义为受限的名字
+ // Stylistic Issues
+ 'comma-dangle': ['error', 'never'], // 要求或禁止末尾逗号
+ 'indent': ['error', 2], // 强制使用一致的缩进,缩进空格为 2
+ 'max-len': ['warn', 120, { 'ignoreUrls': true }], // 强制一行的最大长度,最大长度为 120
+ 'no-underscore-dangle': 'off', // 禁止标识符中有悬空下划线
+ // Node.js and CommonJS
+ 'global-require': 'off', // 要求 require() 出现在顶层模块作用域中
+ // ES6(ES2015)
+ 'arrow-body-style': 'off', // 要求箭头函数体使用大括号
+ 'arrow-parens': 'off', // 要求箭头函数的参数使用圆括号
+ 'no-restricted-syntax': 'off',
+
+ /* React 语法的 ESLint 检查规则 */
+ /* @see https://github.com/yannickcr/eslint-plugin-react */
+ 'react/no-multi-comp': 'off', // 防止每个文件有多个组件定义
+ 'react/prop-types': 'off', // 防止在 React 组件中没有对 props 的校验
+ 'react/forbid-prop-types': 'off',
+ 'react/prefer-stateless-function': 'off', // 强制无状态 React 组件为纯函数
+ 'react/jsx-filename-extension': 'off', // 限制可能包含 JSX 的文件扩展名
+ 'react/no-array-index-key': 'off', // 限制数组索引作为 key
+ 'react/no-string-refs': 'off',
+ 'react/jsx-no-target-blank': 'off',
+
+ /* JSX 元素的 ESLint 检查规则 */
+ /* @see https://github.com/evcohen/eslint-plugin-jsx-a11y */
+ 'jsx-a11y/href-no-hash': 'off',
+ 'jsx-a11y/no-noninteractive-element-interactions': 'off', // 不应该为非交互式元素分配鼠标或键盘事件监听器
+ 'jsx-a11y/label-has-for': 'off',
+ 'jsx-a11y/no-static-element-interactions': 'off',
+
+ /* 导入规则的 ESLint 检查规则 */
+ /* @see https://github.com/benmosher/eslint-plugin-import */
+ 'import/no-dynamic-require': 'off', // 禁止 require() 调用表达式
+ 'import/no-extraneous-dependencies': 'off', // 禁止使用无关的 package
+ 'import/no-unresolved': [2, { commonjs: true, amd: true }] // 导入的模块可以解析为本地文件系统上的模块
+ }
+};
diff --git a/demos/reactadmin/config/env.js b/demos/reactadmin/config/env.js
new file mode 100644
index 0000000..6864360
--- /dev/null
+++ b/demos/reactadmin/config/env.js
@@ -0,0 +1,87 @@
+const fs = require('fs');
+const path = require('path');
+const paths = require('./paths');
+
+// 确保包含 env.js 之后的 paths.js 将会读取 .env 变量。
+delete require.cache[require.resolve('./paths')];
+
+const NODE_ENV = process.env.NODE_ENV;
+if (!NODE_ENV) {
+ throw new Error(
+ 'The NODE_ENV environment variable is required but was not specified.'
+ );
+}
+
+// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
+const dotenvFiles = [
+ `${paths.dotenv}.${NODE_ENV}.local`,
+ `${paths.dotenv}.${NODE_ENV}`,
+
+ // 对于 `test` 环境,不要包含 `.env.local`,因为通常你会希望测试能为每个人产生相同的结果
+ NODE_ENV !== 'test' && `${paths.dotenv}.local`,
+ paths.dotenv
+].filter(Boolean);
+
+// 从 .env* 文件加载环境变量。
+// 如果此文件丢失,请使用 silent 抑制警告。
+// dotenv 将永远不会修改任何已经设置的环境变量。
+// @see https://github.com/motdotla/dotenv
+dotenvFiles.forEach(dotenvFile => {
+ if (fs.existsSync(dotenvFile)) {
+ require('dotenv').config({
+ path: dotenvFile
+ });
+ }
+});
+
+// 我们支持根据 `NODE_PATH` 解析模块。
+// 这使您可以在导入大型 monorepos 中使用绝对路径:
+// https://github.com/facebookincubator/create-react-app/issues/253。
+// 它的工作类似于 Node 本身的 `NODE_PATH`:
+// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
+// 请注意,与 Node 不同,只有来自 `NODE_PATH` 的相对路径才能得到认可。
+// 否则,我们有可能将 Node.js 的核心模块导入到应用程序而不是 Webpack 垫片。
+// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
+// 我们也解决了这些问题,确保使用它们的所有工具始终如一地工作
+const appDirectory = fs.realpathSync(process.cwd());
+process.env.NODE_PATH = (process.env.NODE_PATH || '')
+ .split(path.delimiter)
+ .filter(folder => folder && !path.isAbsolute(folder))
+ .map(folder => path.resolve(appDirectory, folder))
+ .join(path.delimiter);
+
+// 抓取 NODE_ENV 和 REACT_APP_* 环境变量,
+// 并通过 Webpack 配置中的 DefinePlugin 将它们预先注入到应用程序中。
+const REACT_APP = /^REACT_APP_/i;
+
+function getClientEnvironment(publicUrl) {
+ const raw = Object.keys(process.env)
+ .filter(key => REACT_APP.test(key))
+ .reduce(
+ (env, key) => {
+ env[key] = process.env[key];
+ return env;
+ },
+ {
+ // 用于确定我们是否以生产模式运行。
+ // 最重要的是,它将 React 切换到正确的模式。
+ NODE_ENV: process.env.NODE_ENV || 'development',
+
+ // 用于解决 `public` 中静态资源的正确路径。
+ // 例如,。
+ // 这只能用作逃生舱口。通常情况下,您可以在代码中将图像放入 `src` 和 `import` ,以获取路径。
+ PUBLIC_URL: publicUrl
+ }
+ );
+ // 对所有值进行排序,以便我们可以进入 Webpack DefinePlugin。
+ const stringified = {
+ 'process.env': Object.keys(raw).reduce((env, key) => {
+ env[key] = JSON.stringify(raw[key]);
+ return env;
+ }, {})
+ };
+
+ return { raw, stringified };
+}
+
+module.exports = getClientEnvironment;
diff --git a/demos/reactadmin/config/jest/cssTransform.js b/demos/reactadmin/config/jest/cssTransform.js
new file mode 100644
index 0000000..cc4a31f
--- /dev/null
+++ b/demos/reactadmin/config/jest/cssTransform.js
@@ -0,0 +1,12 @@
+// This is a custom Jest transformer turning style imports into empty objects.
+// http://facebook.github.io/jest/docs/tutorial-webpack.html
+
+module.exports = {
+ process() {
+ return 'module.exports = {};';
+ },
+ getCacheKey() {
+ // The output is always the same.
+ return 'cssTransform';
+ }
+};
diff --git a/demos/reactadmin/config/jest/fileTransform.js b/demos/reactadmin/config/jest/fileTransform.js
new file mode 100644
index 0000000..70a5cc9
--- /dev/null
+++ b/demos/reactadmin/config/jest/fileTransform.js
@@ -0,0 +1,10 @@
+const path = require('path');
+
+// This is a custom Jest transformer turning file imports into filenames.
+// http://facebook.github.io/jest/docs/tutorial-webpack.html
+
+module.exports = {
+ process(src, filename) {
+ return `module.exports = ${JSON.stringify(path.basename(filename))};`;
+ }
+};
diff --git a/demos/reactadmin/config/paths.js b/demos/reactadmin/config/paths.js
new file mode 100644
index 0000000..63c6f0f
--- /dev/null
+++ b/demos/reactadmin/config/paths.js
@@ -0,0 +1,52 @@
+const path = require('path');
+const fs = require('fs');
+const url = require('url');
+
+// 确保解决了项目文件夹中的任何符号链接:
+// https://github.com/facebookincubator/create-react-app/issues/637
+const appDirectory = fs.realpathSync(process.cwd());
+const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
+
+const envPublicUrl = process.env.PUBLIC_URL;
+
+function ensureSlash(servedUrl, needsSlash) {
+ const hasSlash = servedUrl.endsWith('/');
+ if (hasSlash && !needsSlash) {
+ return servedUrl.substr(servedUrl, servedUrl.length - 1);
+ } else if (!hasSlash && needsSlash) {
+ return `${servedUrl}/`;
+ }
+ return servedUrl;
+}
+
+const getPublicUrl = appPackageJson =>
+ envPublicUrl || require(appPackageJson).homepage;
+
+// 我们使用`PUBLIC_URL` 环境变量或 "homepage" 字段推断应用程序的“公共路径”。
+// Webpack 需要知道它可以将正确的