使用 create-react-app
创建项目
npx create-react-app .
create-react-app: https://facebook.github.io/create-react-app/docs/getting-started
- 安装
react-app-rewired
和customize-cra
yarn add react-app-rewired customize-cra --dev
- 增加
config-overrides.js
文件
// config-overrides.js
module.exports = function override(config, env) {
// do stuff with the webpack config...
return config;
};
- 修改 package.json
scripts
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
},
react-app-rewired: https://github.com/timarney/react-app-rewired
根据 ant-design
文档修改 config-overrides.js
/* config-overrides.js */
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
- module.exports = function override(config, env) {
- // do stuff with the webpack config...
- return config;
- };
+ module.exports = {
+ webpack: override(
+ fixBabelImports('import', {
+ libraryName: 'antd',
+ libraryDirectory: 'es',
+ style: true,
+ }),
+ fixBabelImports('ant-design-pro', {
+ libraryName: 'ant-design-pro',
+ libraryDirectory: 'lib',
+ style: true,
+ camel2DashComponentName: false,
+ }),
+ addLessLoader({
+ javascriptEnabled: true,
+ localIdentName: '[local]--[hash:base64:5]',
+ // modifyVars: { '@primary-color': '#1DA57A' },
+ }),
+ ),
+ };
参考文档: https://ant.design/docs/react/use-with-create-react-app-cn#%E4%BD%BF%E7%94%A8-babel-plugin-import
- 删除默认的
src/index.js
入口文件和相关依赖 - 创建
src/pages/
目录 - 创建
src/pages/index.js
和src/pages/login.js
- 参考
dva
快速开始指南编写src/pages/index.js
和src/pages/login.js
已经相关依赖的代码 - 多页应用应该使用 hashHistory,注意修改
/* config-overrides.js */
+ const supportMultiPage = (config, env) => {
+ // do stuff with the webpack config...
+ return config;
+ };
module.exports = {
webpack: override(
+ supportMultiPage,
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
}),
...
),
},
/* config-overrides.js */
const {
override,
fixBabelImports,
addLessLoader,
} = require('customize-cra');
+ const paths = require('react-scripts/config/paths');
+ paths.appIndexJs = `${paths.appSrc}/pages/index.js`;
+ paths.servedPath = './';
...
/* config-overrides.js */
...
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
...
+ const getEntryConfig = env => {
+ const arr = 'development' === env ? [require.resolve('react-dev-utils/webpackHotDevClient')] : [];
+ return entry => {
+ return [...arr, `${paths.appSrc}/pages/${entry}.js`];
+ };
+ };
+
+ const removePlugin = (plugins, name) => {
+ const list = plugins.filter(it => !(it.constructor && it.constructor.name && name === it.constructor.name));
+ if (list.length === plugins.length) {
+ throw new Error(`Can not found plugin: ${name}.`);
+ }
+ return list;
+ };
+
+ const genHtmlWebpackPlugin = env => {
+ const minify = {
+ removeComments: true,
+ collapseWhitespace: true,
+ removeRedundantAttributes: true,
+ useShortDoctype: true,
+ removeEmptyAttributes: true,
+ removeStyleLinkTypeAttributes: true,
+ keepClosingSlash: true,
+ minifyJS: true,
+ minifyCSS: true,
+ minifyURLs: true,
+ };
+ const config = Object.assign(
+ {},
+ { inject: true, template: paths.appHtml },
+ 'development' !== env ? { minify } : undefined,
+ );
+ return entry => {
+ return new HtmlWebpackPlugin({
+ ...config,
+ chunks: ['vendors', `runtime~${entry}.html`, entry],
+ filename: `${entry}.html`,
+ });
+ };
+ };
+
+ const supportMultiPage = (config, env) => {
+ const list = ['index', 'login'];
+ config.entry = {};
+ config.plugins = removePlugin(config.plugins, 'HtmlWebpackPlugin');
+ const getEntry = getEntryConfig(env);
+ const getHtmlWebpackPlugin = genHtmlWebpackPlugin(env);
+ list.forEach(it => {
+ config.entry[it] = getEntry(it);
+ config.plugins.push(getHtmlWebpackPlugin(it));
+ });
+
+ if ('development' === env) {
+ config.output.filename = 'static/js/[name].bundle.js';
+ }
+ return config;
+ };
...
/* config-overrides.js */
...
module.exports = {
webpack: override(
...
),
+ devServer: configFunction => {
+ return (proxy, allowedHost) => {
+ const config = configFunction(proxy, allowedHost);
+ config.historyApiFallback.rewrites = [{ from: /^\/login\.html/, to: '/build/login.html' }];
+ return config;
+ };
+ },
};
/* config-overrides.js */
...
+ const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
...
const supportMultiPage = (config, env) => {
...
if ('development' === env) {
config.output.filename = 'static/js/[name].bundle.js';
} else {
+ config.plugins = removePlugin(config.plugins, 'GenerateSW');
+ const workboxWebpackPlugin = new WorkboxWebpackPlugin.GenerateSW({
+ clientsClaim: true,
+ exclude: [/\.map$/, /asset-manifest\.json$/, /\.html$/],
+ importWorkboxFrom: 'local',
+ // navigateFallback: paths.servedPath + '/index.html',
+ // navigateFallbackBlacklist: [
+ // // Exclude URLs starting with /_, as they're likely an API call
+ // new RegExp('^/_'),
+ // // Exclude URLs containing a dot, as they're likely a resource in
+ // // public/ and not a SPA route
+ // new RegExp('/[^/]+\\.[^/]+$'),
+ // ],
+ });
+ config.plugins.push(workboxWebpackPlugin);
+ }
return config;
};
...
/* src/pages/index.js 和 src/pages/login.js 中同时修改 */
+ import * as serviceWorker from '../serviceWorker';
...
+ serviceWorker.register();
yarn add react-app-polyfill
/* src/pages/index.js 和 src/pages/login.js 中同时修改 */
+ import 'react-app-polyfill/ie11';
+ import 'react-app-polyfill/stable';
/* package.json */
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
- "last 1 safari version",
+ "last 1 safari version",
+ "last 1 ie version"
]
},
- 修改 index.html 文件
+ <script>/*@cc_on window.location.href="http://support.dmeng.net/upgrade-your-browser.html?referrer="+encodeURIComponent(window.location.href); @*/</script>
<title>React App</title>
- 修改 minifyJS 参数
const genHtmlWebpackPlugin = env => {
const minify = {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
- minifyJS: true,
+ minifyJS: {
+ comments: '@cc_on',
+ },
minifyCSS: true,
minifyURLs: true,
};
...
};