随着前端技术的发展,React已经成为构建现代Web应用的重要工具之一。为了简化React项目的搭建过程,Facebook推出了Create React App (CRA) 脚手架。CRA使得开发者能够通过一行命令快速创建一个现代化的React应用,而无需关心复杂的配置细节。本文将详细介绍如何使用CRA创建项目,并进行一些常见的配置优化,如集成CSS预处理器、配置路径别名和设置代理。
确保你的电脑已安装Node.js版本14以上,操作系统为Windows 7以上。
英文官网:Create React App(link:https://create-react-app.dev/)
中文官网:Create React App 中文文档(link:https://create-react-app.bootcss.com/)
Create React App 让你仅通过一行命令,即可构建现代化的 Web 应用。
本文档之后称之为cra
创建项目的方式:
需要保证电脑安装node版本在14以上,系统在win7以上
- # 方式1:使用npx
- $ npx create-react-app react-basic
- # 方式2:使用npm
- $ npm init react-app react-basic
- # 方式3:使用yarn
- $ yarn create react-app react-basic
如果需要使用ts开发项目,创建项目时可以通过--template typescript指定模版
- $ npx create-react-app myapp --template typescript
如果出现如下内容,即代表项目创建成功
- Success! Created react-basic at /Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic
- Inside that directory, you can run several commands:
-
- npm start
- Starts the development server.
-
- npm run build
- Bundles the app into static files for production.
-
- npm test
- Starts the test runner.
-
- npm run eject
- Removes this tool and copies build dependencies, configuration files
- and scripts into the app directory. If you do this, you can’t go back!
-
- We suggest that you begin by typing:
-
- cd react-basic
- npm start
-
- Happy hacking!
项目创建完毕生成目录结构如下:
- react-basic
- ├── README.md
- ├── node_modules
- ├── package.json
- ├── .gitignore
- ├── public
- │ ├── favicon.ico
- │ ├── index.html
- │ ├── logo192.png
- │ ├── logo512.png
- │ ├── manifest.json
- │ └── robots.txt
- └── src
- ├── App.css
- ├── App.js
- ├── App.test.js
- ├── index.css
- ├── index.js
- ├── logo.svg
- ├── reportWebVitals.js // 做性能测试
- └── setupTests.js // 测试
src/reportWebVitals.js
- const reportWebVitals = onPerfEntry => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry); // 衡量视觉稳定性。为了提供一个好的用户体验,CLS应该小于0.1
- getFID(onPerfEntry); // 衡量可交互性。为了提供一个好的用户体验,FID应该在100毫秒内。
- getFCP(onPerfEntry); // 首次内容绘制
- getLCP(onPerfEntry); // 衡量加载性能。为了提供一个好的用户体验,LCP应该在2.5秒内
- getTTFB(onPerfEntry); // 到第一个字节的时间
- });
- }
- };
- export default reportWebVitals;
react官方文档已经给了我们性能提升的方案:https://zh-hans.reactjs.org/docs/optimizing-performance.html
打开package.json,发现可运行命令如下:
- "scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
- },
start指令用于启动开发者服务器
build指令用于打包项目
test指令用于测试
eject指令用于抽离配置文件
cra脚手架基于webpack,默认webpack的配置在 node_modules下的react-scripts 内部,但是一般情况下,传输代码时,不会上传 node_modules,那么久必须得抽离配置文件。
通过npm run eject或者cnpm run eject 或者yarn eject指令抽离配置文件
抽离配置文件过程中注意事项
- 1.确保项目的git仓库是最新的
- 2.如果不需要对于webpack进行配置,那么不需要抽离配置文件
- Copying files into /Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic
- Adding /config/env.js to the project
- Adding /config/getHttpsConfig.js to the project
- Adding /config/modules.js to the project
- Adding /config/paths.js to the project
- Adding /config/webpack.config.js to the project
- Adding /config/webpackDevServer.config.js to the project
- Adding /config/jest/babelTransform.js to the project
- Adding /config/jest/cssTransform.js to the project
- Adding /config/jest/fileTransform.js to the project
- Adding /scripts/build.js to the project
- Adding /scripts/start.js to the project
- Adding /scripts/test.js to the project
- Adding /config/webpack/persistentCache/createEnvironmentHash.js to the project
-
- Updating the dependencies
- Removing react-scripts from dependencies
- Adding @babel/core to dependencies
- Adding @pmmmwh/react-refresh-webpack-plugin to dependencies
- Adding @svgr/webpack to dependencies
- Adding babel-jest to dependencies
- Adding babel-loader to dependencies
- Adding babel-plugin-named-asset-import to dependencies
- Adding babel-preset-react-app to dependencies
- Adding bfj to dependencies
- Adding browserslist to dependencies
- Adding camelcase to dependencies
- Adding case-sensitive-paths-webpack-plugin to dependencies
- Adding css-loader to dependencies
- Adding css-minimizer-webpack-plugin to dependencies
- Adding dotenv to dependencies
- Adding dotenv-expand to dependencies
- Adding eslint to dependencies
- Adding eslint-config-react-app to dependencies
- Adding eslint-webpack-plugin to dependencies
- Adding file-loader to dependencies
- Adding fs-extra to dependencies
- Adding html-webpack-plugin to dependencies
- Adding identity-obj-proxy to dependencies
- Adding jest to dependencies
- Adding jest-resolve to dependencies
- Adding jest-watch-typeahead to dependencies
- Adding mini-css-extract-plugin to dependencies
- Adding postcss to dependencies
- Adding postcss-flexbugs-fixes to dependencies
- Adding postcss-loader to dependencies
- Adding postcss-normalize to dependencies
- Adding postcss-preset-env to dependencies
- Adding prompts to dependencies
- Adding react-app-polyfill to dependencies
- Adding react-dev-utils to dependencies
- Adding react-refresh to dependencies
- Adding resolve to dependencies
- Adding resolve-url-loader to dependencies
- Adding sass-loader to dependencies
- Adding semver to dependencies
- Adding source-map-loader to dependencies
- Adding style-loader to dependencies
- Adding tailwindcss to dependencies
- Adding terser-webpack-plugin to dependencies
- Adding webpack to dependencies
- Adding webpack-dev-server to dependencies
- Adding webpack-manifest-plugin to dependencies
- Adding workbox-webpack-plugin to dependencies
-
- Updating the scripts
- Replacing "react-scripts start" with "node scripts/start.js"
- Replacing "react-scripts build" with "node scripts/build.js"
- Replacing "react-scripts test" with "node scripts/test.js"
-
- Configuring package.json
- Adding Jest configuration
- Adding Babel preset
-
- Running npm install...
-
- up to date in 4s
-
- 203 packages are looking for funding
- run `npm fund` for details
- Ejected successfully!
- $ npm start
- $ npm build
- $ cnpm i less less-loader -D
- $ cnpm i node-sass -D
- $ cnpm i stylus stylus-loader -D
具体配置如下:
React-basic/config/webpack.config.js
- // style files regexes 可以搜索此关键字快速定位
- const cssRegex = /\.css$/;
- const cssModuleRegex = /\.module\.css$/;
- const sassRegex = /\.(scss|sass)$/;
- const sassModuleRegex = /\.module\.(scss|sass)$/;
- const lessRegex = /\.less$/;
- const lessModuleRegex = /\.module\.less$/;
- const stylusRegex = /\.stylus/;
- const stylusModuleRegex = /\.module\.stylus/;
-
- // "postcss" loader applies autoprefixer to our CSS.可以搜索此关键字快速定位
- // "css" loader resolves paths in CSS and adds assets as dependencies.
- // "style" loader turns CSS into JS modules that inject <style> tags.
- // In production, we use MiniCSSExtractPlugin to extract that CSS
- // to a file, but in development "style" loader enables hot editing
- // of CSS.
- // By default we support CSS Modules with the extension .module.css
- {
- test: cssRegex,
- exclude: cssModuleRegex,
- use: getStyleLoaders({
- importLoaders: 1,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'icss',
- },
- }),
- // Don't consider CSS imports dead code even if the
- // containing package claims to have no side effects.
- // Remove this when webpack adds a warning or an error for this.
- // See https://github.com/webpack/webpack/issues/6571
- sideEffects: true,
- },
- // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
- // using the extension .module.css
- {
- test: cssModuleRegex,
- use: getStyleLoaders({
- importLoaders: 1,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'local',
- getLocalIdent: getCSSModuleLocalIdent,
- },
- }),
- },
- // Opt-in support for SASS (using .scss or .sass extensions).
- // By default we support SASS Modules with the
- // extensions .module.scss or .module.sass
- {
- test: sassRegex,
- exclude: sassModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'icss',
- },
- },
- 'sass-loader'
- ),
- // Don't consider CSS imports dead code even if the
- // containing package claims to have no side effects.
- // Remove this when webpack adds a warning or an error for this.
- // See https://github.com/webpack/webpack/issues/6571
- sideEffects: true,
- },
- // Adds support for CSS Modules, but using SASS
- // using the extension .module.scss or .module.sass
- {
- test: sassModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'local',
- getLocalIdent: getCSSModuleLocalIdent,
- },
- },
- 'sass-loader'
- ),
- },
- {
- test: lessRegex,
- exclude: lessModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'icss',
- },
- },
- 'less-loader'
- ),
- // Don't consider CSS imports dead code even if the
- // containing package claims to have no side effects.
- // Remove this when webpack adds a warning or an error for this.
- // See https://github.com/webpack/webpack/issues/6571
- sideEffects: true,
- },
- // Adds support for CSS Modules, but using SASS
- // using the extension .module.scss or .module.sass
- {
- test: lessModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'local',
- getLocalIdent: getCSSModuleLocalIdent,
- },
- },
- 'less-loader'
- ),
- },
- {
- test: stylusRegex,
- exclude: stylusModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'icss',
- },
- },
- 'stylus-loader'
- ),
- // Don't consider CSS imports dead code even if the
- // containing package claims to have no side effects.
- // Remove this when webpack adds a warning or an error for this.
- // See https://github.com/webpack/webpack/issues/6571
- sideEffects: true,
- },
- // Adds support for CSS Modules, but using SASS
- // using the extension .module.scss or .module.sass
- {
- test: stylusModuleRegex,
- use: getStyleLoaders(
- {
- importLoaders: 3,
- sourceMap: isEnvProduction
- ? shouldUseSourceMap
- : isEnvDevelopment,
- modules: {
- mode: 'local',
- getLocalIdent: getCSSModuleLocalIdent,
- },
- },
- 'stylus-loader'
- ),
- },
vue项目中可以使用@代替src目录,那么react中抽离配置文件之后也可以实现此功能
react-basic/config/webpack.config.js
- alias: {
- '@': path.resolve('src'), // +++++++++++++
- // Support React Native Web 搜索此关键词快速定位
- // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
- 'react-native': 'react-native-web',
- // Allows for better profiling with ReactDevTools
- ...(isEnvProductionProfile && {
- 'react-dom$': 'react-dom/profiling',
- 'scheduler/tracing': 'scheduler/tracing-profiling',
- }),
- ...(modules.webpackAliases || {}),
- },
如果是ts项目,需要在tsconfig.json中加入如下配置
- {
- "compilerOptions": {
- "target": "es6", // ts代码以es5为标准
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "paths": {// ++++++++++
- "@/*": ["./src/*"]
- },
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noFallthroughCasesInSwitch": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx"
- },
- "include": [
- "src",
- "src/**/*" // ++++++++++
- ]
- }
-
src/index.js 测试
- import React from 'react';
- import ReactDOM from 'react-dom/client';
- import '@/index.css'; // ++++++
- import App from '@/App';// ++++++
- import reportWebVitals from '@/reportWebVitals';// ++++++
-
- const root = ReactDOM.createRoot(document.getElementById('root'));
- root.render(
- <React.StrictMode>
- <App />
- </React.StrictMode>
- );
-
- // If you want to start measuring performance in your app, pass a function
- // to log results (for example: reportWebVitals(console.log))
- // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
- reportWebVitals();
- 如果控制台报错如下,说明@别名没有配置成功
- Failed to compile.
-
- Module not found: Error: Can't resolve '@/index.css' in '/Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic/src'
- ERROR in ./src/index.js 6:0-21
- Module not found: Error: Can't resolve '@/index.css' in '/Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic/src'
-
- ERROR in ./src/index.js 7:0-24
- Module not found: Error: Can't resolve '@/App' in '/Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic/src'
-
- ERROR in ./src/index.js 8:0-48
- Module not found: Error: Can't resolve '@/reportWebVitals' in '/Users/wudaxun/Desktop/workspace/code/bk2207A/code/react-course/react-basic/src'
-
- webpack compiled with 3 errors
如果没有错误说明配置是成功的。
如果不抽离配置文件,但是也需要配置别名@
- $ cnpm i @craco/craco -D
项目根目录中创建 craco 的配置文件:craco.config.js
- const path = require('path')
- module.exports = {
- webpack: {
- alias: {
- '@': path.resolve(__dirname, 'src')
- }
- }
- }
重启服务器即可生效
即使不抽离配置文件,也是在此处配置代理
首先,http-proxy-middleware使用 npm 或 Yarn 安装:
- $ cnpm install http-proxy-middleware -S
- $ # or
- $ yarn add http-proxy-middleware -S
接下来,创建src/setupProxy.js并在其中放置以下内容:
- const { createProxyMiddleware } = require('http-proxy-middleware');
-
- module.exports = function(app) {
- // ...
- };
您现在可以根据需要注册代理了!这是使用上述内容的示例http-proxy-middleware:
- const { createProxyMiddleware } = require('http-proxy-middleware'); // 此处不使用import语法
-
- module.exports = function (app) {
- // http://121.89.205.189:3001/api/pro/list ==> /myapi/pro/list
- app.use('/myapi', createProxyMiddleware({
- target: 'http://121.89.205.189:3001/api',
- changeOrigin: true,
- pathRewrite: {
- '^/myapi': ''
- }
- })
- );
- }
注意:您不需要在任何地方导入此文件。当您启动开发服务器时,它会自动注册。
注意:此文件仅支持 Node 的 JavaScript 语法。确保只使用受支持的语言功能(即不支持 Flow、ES 模块等)。
注意:将路径传递给代理函数允许您在路径上使用通配符和/或模式匹配,这比快速路由匹配更灵活。
通过本文,我们详细介绍了如何使用Create React App (CRA) 脚手架创建React项目,并进行了以下配置优化:
这些配置优化不仅提高了开发效率,还提升了项目的可维护性和扩展性。希望本文对你有所帮助,祝你在React开发之旅中一切顺利!