create-react-app 是 React 官方為我們提供的一個(gè)單頁(yè)應(yīng)用腳手架,基于 webpack 配置了相關(guān)功能,babel、 圖片處理、熱加載、css 模塊化、css 預(yù)處理器轉(zhuǎn)換、代碼分隔、生產(chǎn)構(gòu)建、測(cè)試等。文檔在這 create-react-app。強(qiáng)烈建議去看一看。
建議使用 npx create-react-app myapp 本地安裝,而不是全局安裝,以便更好的管理項(xiàng)目。
前端部分
在一定程度上來(lái)說(shuō),官方提供的腳手架已經(jīng)接近完美了,接下來(lái),擴(kuò)展讓它更完美。
腳手架默認(rèn)把 webpack 等繁瑣復(fù)雜的配置給隱藏起來(lái)了,目的是讓開(kāi)發(fā)者專(zhuān)注于項(xiàng)目。但也提供了一個(gè)命令npm run eject來(lái)暴露相關(guān)配置,但這個(gè)行為是不可逆的。
我們要做的是錦上添花,在不暴露相關(guān)配置的情況下進(jìn)行。
修改默認(rèn)啟動(dòng)端口號(hào):3000
在實(shí)際中,比如有多個(gè)應(yīng)用,那么端口號(hào)沖突是很常見(jiàn)的,那么如何修改默認(rèn)端口號(hào)呢?
- 安裝
npm install --save-dev cross-env,保證兼容性,因?yàn)?window 不支持直接PORT=5000 node scripts/start.js - package.json 文件中啟動(dòng)命令前加入
cross-env PORT=設(shè)置的端口號(hào)
"scripts": {
"start": "cross-env PORT=5000 node scripts/start.js"
},
安裝庫(kù)
- axios
- react-router-dom
- redux、react-redux
- antd
- ...
修改打包后的資源路徑為相對(duì)路徑
在實(shí)際應(yīng)用中,打包后的資源需要使用相對(duì)路徑,只需在 package.json 中進(jìn)行如下配置:
{
"scripts": {
...
},
"homepage": "."
}
擴(kuò)展 webpack 配置
使用 react-app-rewired,安裝這個(gè)工具后,在項(xiàng)目根目錄中新建文件 config-overrides.js 文件。此時(shí)我們便可以在其中進(jìn)行各種 webpack 的配置了~
但是!react-app-rewired2.x 以后,不再支持 injectBabelPlugin 的方式,需要安裝 customize-cra。
具體的,ant design 官方文檔已經(jīng)給出了最新的解決方案。請(qǐng)前往詳覽。https://ant.design/docs/react/use-with-create-react-app-cn
這種方式就是我們推薦的方式。因?yàn)闊o(wú)需生成更多額外的文件,同時(shí)配置又趨于更簡(jiǎn)單可控的方式。
具體的操作步驟:
首先,安裝 react-app-rewired:
npm install react-app-rewired --save-dev
然后修改package.json文件如下:
/* 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",
}
接著,安裝 customize-cra:
npm install customize-cra --save-dev
然后在根目錄下添加 config-overrides.js文件,并進(jìn)行配置,配置可參考customize-cra 文檔:
- react 項(xiàng)目中我們最常用的組件庫(kù) antd,我們需要配置按需加載:
使用 babel-plugin-import,它是一個(gè)用于按需加載組件代碼和樣式的 babel 插件。
npm install babel-plugin-import --save-dev
配置 webpack:
/* config-overrides.js */
+ const { override, fixBabelImports } = require('customize-cra');
+ module.exports = override(
+ fixBabelImports('import', {
+ libraryName: 'antd',
+ libraryDirectory: 'es',
+ style: 'css',
+ }),
+ );
- antd 自定義主題
按照配置主題的要求,自定義主題需要用到 less 變量覆蓋功能。
安裝less和less-loader
npm install less less-loader --save-dev
配置 webpack:
/* config-overrides.js */
- const { override, fixBabelImports } = require('customize-cra');
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
- style: 'css',
+ style: true,
}),
+ addLessLoader({
+ javascriptEnabled: true,
+ modifyVars: { '@primary-color': '#1DA57A' },
+ }),
);
這里利用了less-loader的modifyVars來(lái)進(jìn)行主題配置。當(dāng)然這里的modifyVars的值也可以是一個(gè)theme文件。
- 打包后我們會(huì)發(fā)現(xiàn)靜態(tài)文件夾中會(huì)有很多的 css 和 js 的 map 文件,那么該怎么關(guān)閉sourcemap呢?
/* config-overrides.js */
const { override, fixBabelImports, addLessLoader } = require("customize-cra");
+ process.env.GENERATE_SOURCEMAP = "false";
module.exports = override(
fixBabelImports("import", {
libraryName: 'antd',
libraryDirectory: "es",
style: true,
}),
addLessLoader({
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
})
);
- 其他配置
const { override, fixBabelImports, addLessLoader, addWebpackAlias, useBabelRc, addDecoratorsLegacy, addWebpackPlugin } = require('customize-cra');
const path = require('path')
// 補(bǔ)充:對(duì)開(kāi)發(fā)友好,打包完成桌面提醒
const WebpackBuildNotifierPlugin = require('webpack-build-notifier');
// 關(guān)閉 sourcemap
process.env.GENERATE_SOURCEMAP = "false";
module.exports = override(
// 按需加載
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
// style: 'css' // 按需加載
style: true // antd 自定義主題 less
}),
// antd 自定義主題 less 變量覆蓋全局 依賴(lài) less、less-loader
addLessLoader({
javascriptEnabled: true,
modifyVars: {
'@primary-color': '#814a96'
}
}),
// 配置別名
addWebpackAlias({
'@': path.resolve(__dirname, 'src'),
'components': path.resolve(__dirname, 'src/components'),
'pages': path.resolve(__dirname, 'src/pages')
}),
// 允許使用.babelrc文件進(jìn)行Babel配置。
useBabelRc(),
// 裝飾器 依賴(lài) @babel/plugin-proposal-decorators
addDecoratorsLegacy(),
,
// 打包編譯完成提醒
addWebpackPlugin(new WebpackBuildNotifierPlugin({
title: "My Project Webpack Build",
logo: path.resolve("./img/favicon.png"),
suppressSuccess: true
}))
)
npm install @babel/plugin-proposal-decorators --save-dev
npm install webpack-build-notifier --save-dev
proxy 代理
前端跨域處理。
在 src 目錄下新建文件 setupProxy.js
安裝 http-proxy-middleware:
npm install http-proxy-middleware --save-dev
配置 setupProxy.js
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(
proxy('/api', {
target: 'http://xx.xx.xx.xx:8000/',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
})
)
}
兼容 IE9
使用 create-react-app 官方提供的 react-app-polyfill,然后在入口文件 index.js 中引入
npm install react-app-polyfill --save
import 'react-app-polyfill/ie9'
后端部分
在實(shí)際工作中,需求確定后,前后端往往是同步開(kāi)發(fā)的,對(duì)于接口的提供,后端沒(méi)那么及時(shí),但此時(shí)前端怎么在沒(méi)有后端接口的情況下,還能正常開(kāi)發(fā)呢,保證功能的正常。
答案是:mock 數(shù)據(jù)。
那么如何 mock 數(shù)據(jù)呢,方式很多,比如利用 easymock 在線模擬接口數(shù)據(jù),當(dāng)然最好的方式是自己搭建 node 服務(wù),模擬接口及數(shù)據(jù),更靈活,也能提升技術(shù),了解后端的一些知識(shí),更好的溝通與交流。
在 src 目錄下新建文件夾 server-node,然后在下面再建一個(gè) index.js 作為入口文件。
安裝庫(kù)
- koa
- koa-router
- koa-body
- ...
koa 相關(guān)知識(shí),請(qǐng)自行學(xué)習(xí)。
重啟,熱加載
和前端一樣,改了文件,會(huì)自動(dòng)重啟。
安裝 nodemon:
npm install nodemon --save-dev
配置 package.json
scripts: {
server: 'nodemon server-node/index.js'
}
大概就這些了,有更好的建議或配置的,也請(qǐng)多多指教~~