更新时间:2019-01-11
版本信息:CRA v2.1.1 + Webpack v4.19.1 + react-app-rewired v1.6.2

一、前言

为什么要进行多页面配置

在使用 React 进行开发的过程中,我们通常会使用 create-react-app 脚手架命令来搭建项目,避免要自己配置 webpack,提高我们的开发效率。但是使用 create-react-app 搭建的项目是单页面应用,如果我们是做中后台管理页面或 SPA,这样是满足要求的,但如果项目有多入口的需求,就需要我们进行一些配置方面的修改。

一般现在有两种方式将脚手架搭建的项目修改为多入口编译:

  1. 执行 npm run eject 命令,弹出配置文件,进行自定义配置。请参见:React-CRA 多页面配置(npm run eject)。
  2. 使用 react-app-rewired 修改脚手架配置,在项目中安装 react-app-rewired 后,可以通过创建一个 config-overrides.js 文件来对 webpack 配置进行扩展。

本文对第 2 种方法给出具体配置方案,第 1 种方案详见:React-CRA 多页面配置(npm run eject)。在阅读本文之前,可以先了解一下第 1 种方案,有助于更好的理解本文内容。

webpack 基础

本文对 React 多页面应用配置的探讨是基于使用 create-react-app 脚手架命令构建的项目,并不是 webpack 多页面配置教程。但上述两种方案都应该具有一定的 webpack 的基础,实际上当你决定要改造或增强项目的构建打包配置的时候,你应该先对 webpack 进行一定的了解。

如果你之前使用 webpack v3.x 版本,这里附上 webpack v4.0.0 更新日志 以及 webpack4升级完全指南。

方案说明

通过使用 react-app-rewired 可以修改脚手架配置,从而实现扩展 webpack 配置,如增加对 less 文件的支持、增加 antd 组件的按需加载、处理 html 文档中的图片路径问题等,甚至可以将单页面入口编译修改为多页面入口编译的方式。

但是需要说明的是,我们可以通过 react-app-rewired 在不暴露配置文件的情况下达到扩展项目配置的目的,但并不建议使用这种方式进行多页面入口编译的配置,虽然本文主要就是介绍这种方案。本文的意义更多的是记录对这种方案的尝试,如果真的需要进行多页面配置,最好还是使用 npm run eject 暴露配置文件的方式。

主要原因是,通过 react-app-rewired 来实现多页面配置,是需要对脚手架原来的配置具有一定了解的,相较于 npm run eject 暴露配置文件的方式来说,这种方式是不太具有透明度的,后面维护的难度较大。本文方案完成的基础是,我之前已经通过 npm run eject 这种方式改造过一次多页面的配置,相当于说我已经拆过这个箱子了,我基本上了解了这个箱子里有什么,因此我在配置这个方案的过程中其实是对照着 npm run eject 这个方案中的配置文件来逐步进行的。

版本的变动

使用 CRA 脚手架命令生成的项目免去了我们自己配置 webpack 的麻烦,其内置的各种配置所需要的插件和依赖包的版本都是确定的,是经过了检验的成熟配置,不会因为其中某个依赖包版本的问题造成构建出错。但当我们决定要自己动手配置 webpack 的时候,就意味着我们要自己根据需要安装一些 plugin 或 npm 依赖包,而这些插件和依赖包的版本可能不适用于当前 CRA 的版本,从而造成构建过程中出现一些不可预期的错误。

因此,我们需要查看 CRA 脚手架项目的 package.json 文件,对于其中已经列出的 dependencies 依赖包,我们不应该改变这些依赖包的版本,而对于未列出的 npm 包,我们在使用的过程中需要逐个验证,不要一次性安装很多个 npm 包,否则执行构建命令的时候如果出错就会很难排查,最好是根据我们需要的功能逐个的安装相应的 npm 包,确定没有问题,再进行下一个功能的扩展。

正是由于版本的变动会对配置产生很大的影响,因此当我们确定了一个配置方案之后,不要再轻易去改动其中涉及到的 npm 包的版本,通过 package-lock.json 文件锁定版本,防止配置方案错乱。

另外,在本文编辑的时候,CRA 的最新版本为 v2.1.2,这个版本的 CRA 生成的项目,当前版本的 react-app-rewired v1.6.2 已经无法使用,具体信息可以参见 CRA >=2.1.2 breaking issue 2.1.2。至少在本文编辑的时候(2019.01.05),是无法适用于 CRA >=2.1.2 版本的,因此本文方案是基于最后一个可以适用的 CRA v2.1.1 版本来做的,package.json 文件中其他的 version 信息会附在方案后面。

2019-01-11 补充:上面提到的版本基本都是指 package.json 文件中列出的依赖包的版本,但是严格来讲还应包含一些构建配置中使用的 node.js 工具包,比如 globby、dir-glob等,这些工具包的版本更新也有可能会造成构建出错。这种情况的出现往往是无法预期的,它们造成的影响一般比较广泛,而不仅仅是出现在我们方案配置的过程中,这种错误基本上都会在 Github 上有相应的 issue 以及解决方法或修复措施,本文中也列出了遇到的一个这种类型的错误,详见 四、错误排查 章节中的 其他错误 一节。

二、准备工作

创建一个 CRA v2.1.1 项目

我们的配置方案是基于 CRA v2.1.1 脚手架项目进行改造的,因此首先我们要先创建一个 CRA 项目,详见官方文档:Create React App。

但是这样创建出来的项目默认是最新版本的 CRA 项目,我们在上文中已经说明,我们的配置方案是要求特定版本的 CRA 项目的,那么如何创建特定的 CRA v2.1.1 版本项目?

CRA 项目版本的核心其实就是 react-scripts 的版本,我们可以先创建一个最新版本的脚手架项目,然后更改为 v2.1.1 版本,具体如下:

  1. 创建一个最新版本的 CRA 项目,参见官方文档:Create React App;
  2. 删除 node_modules 文件夹,如果有 package-lock.json 文件或 yarn.lock 文件,也要一并删除,否则重新安装 node_modules 依赖包仍然会被锁定为原来的版本;
  3. 修改 package.json 文件,重新指定 react-scripts 的版本:

    "dependencies": {- "react": "^16.7.0",+ "react": "^16.6.3",- "react-dom": "^16.7.0",+ "react-dom": "^16.6.3",- "react-scripts": "2.1.3"+ "react-scripts": "2.1.1"
    }
  4. 执行 yarn installnpm install 重新安装项目依赖。

至此,我们已经创建了一个 CRA v2.1.1 项目,这将作为我们进行多页面入口编译改造的基础。

react-app-rewired 的用法

首先要学习 react-app-rewired 的用法,参照官方文档:How to rewire your create-react-app project。
主要是三点:

  1. 安装 react-app-rewired
  2. 创建一个 config-overrides.js 文件
  3. 修改 package.json 文件中的脚本命令

查看 CRA 项目原有的配置文件

上面我们提到在进行多页面配置之前,需要对脚手架原有的配置文件具有一定了解,那么如何查看原有的配置文件?

  • 方法1:将使用 CRA 脚手架命令生成的项目拷贝一份,执行 npm run eject 暴露配置文件,eject 之后文件组织结构如下:

    my-app
    ├── config
    │   ├── jest
    │   ├── env.js
    │   ├── paths.js
    │   ├── webpack.config.dev.js
    │   ├── webpack.config.prod.js
    │   └── webpackDevServer.config.js
    ├── node_modules
    ├── public
    ├── scripts
    │   ├── build.js
    │   ├── start.js
    │   └── test.js
    ├── package.json
    ├── README.md
    └── src

    其中 config 文件夹下就是脚手架原有的配置文件。

  • 方法2:使用 CRA 脚手架命令生成项目,在 my-app/node_modules/react-scripts/config 路径下可以看到原有的配置文件
  • 方法3:在 config-overrides.js 文件中将 webpack 配置对象输出在控制台,查看其结构

推荐使用第 1 种方式,便于我们在配置过程中查看和操作,第 3 种方式作为一种辅助手段,主要是用于改造过程中的调试和验证配置对象的改造结果的。

项目文件组织结构

在开始进行多入口配置之前,需要先明确项目的文件组织结构,这关系到我们如何准确获取所有的入口文件,这里不再详述,请参见React-CRA 多页面配置(npm run eject)中的项目文件组织结构一节。

三、具体方案

  1. 安装 react-app-rewired,创建 config-overrides.js 文件,修改 package.json 文件中的脚本命令。详见官方文档 How to rewire your create-react-app project。

    执行 yarn start 命令,查看 http://localhost:3000,确保安装 react-app-rewired 操作没有问题。

  2. 修改文件组织结构。这里不再详述,参见上文 项目文件组织结构 一节。
    CRA项目原文件组织结构为:

      my-app├── README.md├── node_modules├── package.json├── config-overrides.js // 安装 react-app-rewired 时创建的├── .gitignore├── public│   ├── favicon.ico│   ├── index.html│   └── manifest.json└── src├── App.css├── App.js├── App.test.js├── index.css├── index.js├── logo.svg└── serviceWorker.js

    修改为多页面入口编译的文件组织结构:

      // 本方案示例项目有两个页面 index.html & admin.html// 这里给出的文件组织结构是配置完成后的完整结构, 有些文件(如 src/setupProxy.js)的具体作用后面会给出说明my-app├── README.md├── node_modules├── package.json├── config-overrides.js // 安装 react-app-rewired 时创建的├── .gitignore├── public│   ├── favicon.ico│   ├── index.html // 作为所有页面的 html 模板文件│   └── manifest.json└── src├── index.js // 空白文件, 为了避免构建报错, 详见下文├── setupProxy.js // proxy 设置, 详见下文(在当前操作步骤中可以缺失)├── index // index.html 页面对应的文件夹│   ├── App.less│   ├── App.js│   ├── App.test.js│   ├── index.less // 使用 less 编写样式文件│   ├── index.js│   ├── logo.svg│   └── serviceWorker.js└── admin // admin.html 页面对应的文件夹├── App.less├── App.js├── App.test.js├── index.less // 使用 less 编写样式文件├── index.js├── logo.svg└── serviceWorker.js

    执行 yarn start 命令,查看 http://localhost:3000/index.html 和 http://localhost:3000/admin.html,确保修改文件组织结构操作没有问题。

    这个示例项目是以 my-app/public/index.html 作为所有页面的 html 模板文件的,当然也可以分别指定不同的 html 模板文件,这是根据项目需要和项目文件组织结构决定的。在这个示例项目中,由于作为模板的 html 文件只需要有个根元素即可,因此将其作为所有入口的 html 模板文件。这样的话,每个页面的 <title></title> 就需要在各自页面中分别指定,一般可以在页面挂载之后进行操作,比如:

      class App extends Component {componentDidMount() {document.title = 'xxx';}render() {return (...);}}
  3. 修改 config-overrides.js 文件,进行具体配置。实际上我们之后所有的操作都是在这个文件中进行的。
    我们的测试方案是一个使用了 Ant Design、Redux、Less、Echarts 的多页面项目,需要达到以下要求:

    • 指定页面的多入口文件路径以及入口文件对应的 html 模板
    • 实现 antd 组件的按需加载
    • 增加对 less 文件的支持
    • 更改输出的文件名
    • 增加对 html 文档中图片路径的处理
    • 更改代码拆分的配置
    • 设置别名路径

上述每一个功能的实现,都需要执行 yarn startyarn build 进行验证,确保操作成功后再进行下一项的配置。这里不再逐步说明配置的步骤,详见下面的代码及注释。

最终 config-overrides.js 文件内容如下:

  /* config-overrides.js *//** @Author: mzhang.eric * @Last Modified time: 2019-01-10 18:37:17* @Description: 使用 react-app-rewired 扩展和改造 CRA v2.1.1 项目, 基于 webpack v4.19.1  + react-app-rewired v1.6.2 版本*/const rewireLess = require('react-app-rewire-less');const { injectBabelPlugin, paths } = require('react-app-rewired');const HtmlWebpackPlugin = require('html-webpack-plugin');const path = require('path');const fs = require('fs');const globby = require('globby');const appDirectory = fs.realpathSync(process.cwd());const resolveApp = relativePath => path.resolve(appDirectory, relativePath);// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = function override(config, env) {// 使用 babel-plugin-import 按需加载组件config = injectBabelPlugin(['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],config,);// 增加 less 支持config = rewireLess.withLoaderOptions({// 解决报错: Inline JavaScript is not enabled. Is it set in your options?javascriptEnabled: true,})(config, env);// 入口文件路径// const entriesPath = globby.sync([resolveApp('src') + '/*/index.js']);const entriesPath = globby.sync([resolveApp('src') + '/*/index.js'], {cwd: process.cwd()});paths.entriesPath = entriesPath;// 获取指定路径下的入口文件function getEntries(){const entries = {};const files = paths.entriesPath;files.forEach(filePath => {let tmp = filePath.split('/');let name = tmp[tmp.length - 2];if(env === 'production'){entries[name] = [require.resolve('./node_modules/react-scripts/config/polyfills.js'),filePath,];} else {entries[name] = [require.resolve('./node_modules/react-scripts/config/polyfills.js'),require.resolve('react-dev-utils/webpackHotDevClient'),filePath,];}});return entries;}// 入口文件对象const entries = getEntries();// 配置 HtmlWebpackPlugin 插件, 指定入口文件生成对应的 html 文件let htmlPlugin;if(env === 'production'){htmlPlugin = Object.keys(entries).map(item => {return new HtmlWebpackPlugin({inject: true,template: paths.appHtml,filename: item + '.html',chunks: [item],minify: {removeComments: true,collapseWhitespace: true,removeRedundantAttributes: true,useShortDoctype: true,removeEmptyAttributes: true,removeStyleLinkTypeAttributes: true,keepClosingSlash: true,minifyJS: true,minifyCSS: true,minifyURLs: true,},});});} else {htmlPlugin = Object.keys(entries).map(item => {return new HtmlWebpackPlugin({inject: true,template: paths.appHtml,filename: item + '.html',chunks: [item],});});}if (env === 'production') {for (let i = 0; i < config.plugins.length; i++) {let item = config.plugins[i];// 更改输出的样式文件名if (item.constructor.toString().indexOf('class MiniCssExtractPlugin') > -1) {item.options.filename = 'static/css/[name].css?_v=[contenthash:8]';item.options.chunkFilename = 'static/css/[name].chunk.css?_v=[contenthash:8]';}// SWPrecacheWebpackPlugin: 使用 service workers 缓存项目依赖if(item.constructor.toString().indexOf('function GenerateSW') > -1){// 更改输出的文件名item.config.precacheManifestFilename = 'precache-manifest.js?_v=[manifestHash]';}}// 更改生产模式输出的文件名config.output.filename = 'static/js/[name].js?_v=[chunkhash:8]';config.output.chunkFilename = 'static/js/[name].chunk.js?_v=[chunkhash:8]';} else {// 更改开发模式输出的文件名config.output.filename = 'static/js/[name].js';config.output.chunkFilename = 'static/js/[name].chunk.js';}// 修改入口config.entry = entries;// 修改 HtmlWebpackPlugin 插件for (let i = 0; i < config.plugins.length; i++) {let item = config.plugins[i];if (item.constructor.toString().indexOf('class HtmlWebpackPlugin') > -1) {config.plugins.splice(i, 1);}}config.plugins.push(...htmlPlugin);// 分析打包内容// config.plugins.push(new BundleAnalyzerPlugin());// 设置别名路径config.resolve.alias = {...config.resolve.alias,'@src': paths.appSrc, // 在使用中有些 Eslint 规则会报错, 禁用这部分代码的 Eslint 检测即可};// 处理 html 文档中图片路径问题config.module.rules[2].oneOf.push({test: /\.html$/,loader: 'html-withimg-loader'});// 修改 build/static/media/ 路径下的文件名for (let i = 0; i < config.module.rules[2].oneOf.length; i++) {const item = config.module.rules[2].oneOf[i];if(!item.options || !item.options.name){ continue;}let str = item.options.name.toString();if(str.indexOf('static/media/[name].[hash:8].[ext]') > -1){item.options.name = 'static/media/[name].[ext]?_v=[hash:8]';}}// 修改代码拆分规则,详见 webpack 文档:https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunksconfig.optimization = {splitChunks: {// 将所有入口点共同使用到的、次数超过 2 次的模块,创建为一个名为 commons 的代码块// 这种配置方式可能会增大初始的捆绑包,比如有些公共模块在首页其实并未用到,但也会打包进来,会降低首页的加载性能// 建议将非必需模块使用 import() 的方式动态加载,提升页面的加载速度// cacheGroups: {//   commons: {//     name: 'commons',//     chunks: 'initial',//     minChunks: 2//   }// }// 将所有使用到的 node_modules 中的模块包打包为 vendors 代码块。(不推荐)// 这种方式可能会产生一个包含所有外部依赖包的较大代码块,建议只包含核心框架和工具函数代码,其他依赖项动态加载// cacheGroups: {//   commons: {//     test: /[\\/]node_modules[\\/]/,//     name: 'vendors',//     chunks: 'all'//   }// }cacheGroups: {// 通过正则匹配,将 react react-dom echarts-for-react 等公共模块拆分为 vendor// 这里仅作为示例,具体需要拆分哪些模块需要根据项目需要进行配置// 可以通过 BundleAnalyzerPlugin 帮助确定拆分哪些模块包vendor: {test: /[\\/]node_modules[\\/](react|react-dom|echarts-for-react)[\\/]/,name: 'vendor',chunks: 'all', // all, async, and initial},// 将 css|less 文件合并成一个文件, mini-css-extract-plugin 的用法请参见文档:https://www.npmjs.com/package/mini-css-extract-plugin// MiniCssExtractPlugin 会将动态 import 引入的模块的样式文件也分离出去,将这些样式文件合并成一个文件可以提高渲染速度// 其实如果可以不使用 mini-css-extract-plugin 这个插件,即不分离样式文件,可能更适合本方案,但是我没有找到方法去除这个插件styles: {            name: 'styles',test: /\.css|less$/,chunks: 'all',    // merge all the css chunk to one fileenforce: true}},},};return config;};

四、错误排查

这里对方案形成过程中遇到的错误进行记录,这些错误有些是配置过程中必定会出现的,是需要我们进行改造的,也有些错误可能是操作不当主观造成的。

客观错误

这类错误是进行多页面入口编译改造过程中必定会遇到的,有些是由于项目文件组织结构的改变造成的,也有些是为了扩展项目配置而使用了源 CRA 脚手架项目未提供的 npm 包造成的,前者会出现哪些错误我们是可以明确知道的,后者相对来说是不确切的,但大多都是版本不适用造成的。

  1. Could not find a required file.

    Could not find a required file.
    Name: index.js
    Searched in: C:xxxxxxmy-appsrc

    错误描述:通过 create-react-app 脚手架搭建的项目以 my-app/src/index.js 作为应用入口,当执行构建脚本时如果检测到缺失了这个必要文件,node 进程会退出。但是在我们进行多页面入口改造的时候,src 直接路径下没有 index.js 文件,根据我们的文件组织结构,index.js 文件存在于每个独立页面的子文件夹下,如 my-app/src/index/index.js my-app/src/admin/index.js
    解决方法:在 src 直接路径下创建一个空的 index.js 文件。

  2. Inline JavaScript is not enabled. Is it set in your options?

    // https://github.com/ant-design...
    .bezierEasingMixin();^ Inline JavaScript is not enabled. Is it set in your options?
    in C:xxxsrcmy-appnode_modulesantdesstylecolorbezierEasing.less (line 110, column 0)

    错误描述:less、less-loader 配置问题,提示需要允许行内 js 的执行,比如当我们在项目中使用 antd 组件时,如果引入的样式文件是 less 文件,构建时就会报上述错误。
    解决方法:在 config-overrides.js 文件中增加 less 文件支持时,设置 javascriptEnabled 为 true。

      module.exports = function override(config, env) {...// 增加 less 支持config = rewireLess.withLoaderOptions({// 解决报错: Inline JavaScript is not enabled. Is it set in your options?javascriptEnabled: true,})(config, env);...return config;};
  3. Failed to load resource: net::ERR_FILE_NOT_FOUND(build 版本)

    错误描述:执行 yarn buildnpm run build 构建生产版本时,构建出的页面未能正确加载样式和脚本文件,chrome 检查工具报路径错误。
    解决方法:修改 package.json 文件,指定 homepage 字段的值,本项目这里指定为相对路径。

      "homepage": "./",
  4. When specified, "proxy" in package.json must be a string.

    When specified, "proxy" in package.json must be a string.
    Instead, the type of "proxy" was "object".
    Either remove "proxy" from package.json, or make it a string.

    错误描述:我们在开发过程中一般会在 package.json 文件中配置 proxy 代理服务器,但是在 CRA 2.x 升级以后对 proxy 的设置做了修改,具体请参见官方升级文档:Move advanced proxy configuration to src/setupProxy.js
    解决方法:移除 package.json 文件中有关 proxy 的设置,使用 http-proxy-middleware,在 src 目录下创建 setupProxy.js 文件。详细方法请参见上述文档。

主观错误

这类错误应该是可以避免的,但是在配置过程中可能会由于开发人员的不当操作造成出错,最主要的就是安装了错误版本的 plugin 或 npm 包,我们上面已经说过,对于项目原本的配置中在 package.json 文件中已经列出的 plugin 和 npm 包,不要再重复进行安装,否则可能重新安装的 plugin 或 npm 包版本是不适用的,从而造成出错。

例如,CRA v2.1.1 脚手架项目原有的 html-webpack-plugin 版本是 v4.0.0-alpha.2,是不需要再另外进行安装的。如果此时开发人员自己执行了 yarn add html-webpack-plugin,从而将 html-webpack-plugin 的版本更换为了 v3.2.0,这就会造成构建报错:URIError: Failed to decode param '/%PUBLIC_URL%/favicon.ico' URIError: Failed to decode param '/%PUBLIC_URL%/manifest.json',其他主观错误类似。

  1. html-webpack-plugin 版本错误

    URIError: Failed to decode param '/%PUBLIC_URL%/favicon.ico'
    URIError: Failed to decode param '/%PUBLIC_URL%/manifest.json'

    错误描述:在执行 yarn start 构建命令时报错,页面空白。
    解决方法:html-webpack-plugin 版本错误,在本文的配置方案中,应当使用 "html-webpack-plugin": "4.0.0-alpha.2", 版本。

  2. TypeError: Cannot read property 'state' of undefined(页面报错)

    错误描述:编译构建过程没有报错,但页面报错:TypeError: Cannot read property 'state' of undefined。
    解决方法:redux 版本错误,在本文的配置方案中,应当使用 redux <=3.7.2 版本。

其他错误

我们在上文 版本的变动 一节的补充中已经对此有所提及,这类错误主要是由 node.js 工具包版本的升级造成的,这些错误基本都是不可预期的,也无法在这里全部涵盖,只能就当前遇到的问题进行简要记录,可能随着时间的推移,还会出现其他的类似问题,也可能这些错误已经在后续的版本中被修复了,因此请勿纠结于这里记录的错误,如果遇到了这类错误,就查阅资料进行修正,如果没有遇到,则无须理会。

  1. TypeError: Expected cwd to be of type string but received type undefined

    C:xxxmy-appnode_modulesdir-globindex.js:59
    throw new TypeError( Expected \cwd` to be of type `string` but received type `${typeof opts.cwd}``);
    TypeError: Expected cwd to be of type string but received type undefined

    错误描述:本文的写作开始于 2019-01-05,在 2019-01-11 重新审核本文方案的时候,遇到了这个错误,主要是由于 dir-glob 版本的升级造成的,我们在配置脚本中使用了 globby 的 sync 方法,dir-glob 版本升级之后,这个方法的调用会使得 dir-glob 抛出上述错误。详细信息参见:Broken build do to major change from 2.0 to 2.2 以及 globby will pass opts.cwd = undefined to dir-glob, which leads to TypeError.

    解决方法:这里给出的解决方法是限定于当前时间的,因为在本文编辑的时候(2019-01-11)这个 issue 还没有给出最终的解决方案,个人觉得可能会由 globby 进行修复。

    /* config-overrides.js */
    // 修改获取入口文件路径的代码
    // const entriesPath = globby.sync([resolveApp('src') + '/*/index.js']);
    const entriesPath = globby.sync([resolveApp('src') + '/*/index.js'], {cwd: process.cwd()});

五、package.json 信息

本文的多页面配置方案是基于 CRA 脚手架项目的,项目的依赖包信息会包含在两个 package.json 文件中,其中脚手架自带的配置信息位于 my-app/node_modules/react-scripts/package.json 文件中,而我们根据项目需要自己增加的配置信息在 my-app/package.json 文件中,这里将本方案项目配置信息附录如下:

  /* package.json */{"name": "my-app","version": "0.1.0","private": true,"dependencies": {"antd": "^3.12.1","babel-plugin-import": "^1.11.0","echarts": "^4.2.0-rc.2","echarts-for-react": "^2.0.15-beta.0","html-withimg-loader": "^0.1.16","http-proxy-middleware": "^0.19.1","react": "^16.6.3","react-app-rewire-less": "^2.1.3","react-app-rewired": "^1.6.2","react-dom": "^16.6.3","react-intl": "^2.7.2","react-lazyload": "^2.3.0","react-loadable": "^5.5.0","react-redux": "^6.0.0","react-scripts": "2.1.1","redux": "3.7.2","redux-promise-middleware": "^5.1.1","webpack-bundle-analyzer": "^3.0.3"},"scripts": {"start": "react-app-rewired start","build": "react-app-rewired build","test": "react-app-rewired test --env=jsdom","eject": "react-scripts eject"},"eslintConfig": {"extends": "react-app"},"browserslist": [">0.2%","not dead","not ie <= 11","not op_mini all"],"homepage": "./"}

React-CRA 多页面配置(react-app-rewired)相关推荐

  1. React路由404页面配置

    path路径使用' * '号,表示匹配不到路径时使用该路径 代码示例: App.js import { BrowserRouter, Routes, Route, Link } from 'react ...

  2. 一个基于 React 开发的PC端音乐App

    ?一个基于 React 开发的PC端音乐App. 同时支持 Mac 与 Windows 系统.下载地址 项目使用 electron 作为外壳,webpack 作为打包工具,核心技术包括 React + ...

  3. 配置React的Babel 6和Webpack 2环境

    Facebook的一帮子工程师在忙碌之余开发除了一套前段UI框架React.这个框架最大的有点就在于让UI的开发都基于组件,这样View都是根据props和state变化的. 项目地址:https:/ ...

  4. windows 下配置 react native 开发环境

    windows 下配置 react native 开发环境 安装nvm 由于react native 需要使用 NodeJs 4.0以上版本,为了方便切换NodeJs,首先我们需要安装nvm. 你可以 ...

  5. 一个使用react native实现的短视频APP

    黄豆仔短视频APP 一个使用react native实现的短视频APP.该项目是我没事搞着玩,用react native 写的.用了很多的库同时也修改了几个库: react-native-card-s ...

  6. 配置React项目的运行环境

    两种配置react项目运行环境的方法 第一种方法,一步步配置项目的运行环境: 1)下载node,在官方网站可以下载,安装步骤不难,差不多一步步意 点next就行: 2)运行cmd 输入node -v ...

  7. 前端快闪三:多环境灵活配置react

    大前端快闪:package.json文件知多少? 大前端快闪二:react开发模式 一键启动多个服务 你已经使用Create React App[1] 脚手架搭建了React应用,现在该部署了. 一般 ...

  8. 掘金后端 mysql优化_vue服务端渲染项目(ssr)仿掘金、后台页面是react spa、服务层nodejs、koa、mysql编写的一套多权限内容管理系统...

    kite 后台演示网站账户:kitetest 密码:q123456 (资源有点大,可能要加载一段时间) 备注:因为项目是一直在写的,周期比较长,发出来的目的,就是希望大家多提建议,或者意见 然后我再来 ...

  9. react 返回一个页面_Fiber 内部: 深入理解 React 的新 reconciliation 算法

    最近在看 React, 发现一篇深度好文, 忍不住就翻译了. React 是一个用于构建用户界面的库, 它的核心是跟踪组件状态变化并将它们更新到页面上. 在 React 中, 我们称这个过程为 rec ...

  10. react部署之页面空白

    react部署之页面空白 问题:create-react-app build打包后,页面出现空白. 可能一: 控制台报错,js等文件找不到(404) 文件路径问题,只需修改package.json文件 ...

最新文章

  1. linux proc/xx/maps文件分析
  2. 模板类的全特化、偏特化
  3. 如何修改服务器mac地址,如何修改服务器mac地址
  4. Vmware怎样使用nat和桥接方式解决虚拟机联网问题
  5. 2021年的10种突破性技术
  6. n1服务器系统和小钢炮,教你N1小钢炮系统设置中其他一些应用和服务器的设置的相关方法教程...
  7. Linux Bridge的IP NAT细节探析-填补又一坑的过程
  8. 千元机PK苹果iphone
  9. SpringBoot导入导出你会用吗?(EasyPoi)
  10. 如何在eNSP将多台计算机ping通?
  11. Qt下的国际化方法—翻译文件(.ts .qm文件)的使用
  12. 图——有向图、无向图、有向网、无向网的邻接矩阵表示
  13. Apple Watch必备!KUNER充电表带登场
  14. 最新!互联网大厂各职级薪资对应关系图(2020年初)
  15. 1037 在霍格沃茨找零钱
  16. Chess Tournament (巧用思维)
  17. 为什么说python入门很简单,但是在你这很难?
  18. JavaScript——将json数组填充进excel表并下载保存
  19. 黄海导航软件测试,中国地质调查局工作标准DD2004—03地质调查GPS测量规程1范围.DOC...
  20. 基于webrtc的p2p H265播放器实现一

热门文章

  1. MySQL主键、普通索引和唯一索引的区别、全文索引
  2. git回退到指定版本的两种方式:reset、revert
  3. 共情的力量-读书笔记02
  4. [译]Nginx和Lua
  5. 世界上最高效的笔记方法(改变你那老版的记笔记方法吧)
  6. 极米NEWZ8X和当贝F1C有什么区别 哪个好
  7. 一个女孩,自我陶醉的文章(转载)
  8. DFT Compiler极简示例1
  9. MSDN Library for vs 2010 下载和安装
  10. iOS开发7:自动旋转与调整大小