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 需要知道它可以将正确的