一、 快速開始:
- 全域性安裝腳手架:
npm install -g create-react-app複製程式碼複製程式碼
- 通過腳手架搭建專案:
<專案名稱>複製程式碼複製程式碼
- 開始專案:
cd <專案名>npm run start複製程式碼複製程式碼
二、 檢視專案 package.json 資訊
2.1 package.json 一覽
{
......
"homepage": ".",
"dependencies": {
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
複製程式碼
2.2 可用指令碼命令說明:
首先說明:通過npm run 執行下面命令實際上是執行 node_modules/react-srcipt/script 下對應的指令碼檔案;
npm run start: 開始專案,執行專案後可通過 http://localhost:3000 訪問專案;
npm run build: 專案打包,在生產環境中編譯程式碼,並放在build目錄中;所有程式碼將被正確打包,並進行優化、壓縮同時使用hash重新命名檔案;執行該命令前需要在 package.json 中新增條配置"homepage": "."(上面配置檔案已給出), 同時build後的專案需要在伺服器下才能訪問;否則開啟的將是空白頁面;
npm run test: 互動監視模式下啟動測試執行程式;
npm run eject: 將隱藏的配置匯出;需要知道的是create-react-app腳手架本質上是使用react-scripts進行配置專案,所有配置檔案資訊都被隱藏起來(node_modules/react-scripts);當需要手動修改擴充套件webpack配置時有時就需要將隱藏的配置暴露出來;特別需要注意的是該操作是一個單向操作,一旦使用eject,那麼就不能恢復了(再次將配置隱藏);
四、 新增對 less 的支援
4.1 方法一:暴露配置並進行修改
- 暴露配置檔案:
npm run eject說明: 執行eject指令碼後,專案下會新增或對部分配置檔案進行修改;專案下 script 目錄存放著指令碼檔案, config 目錄下存放著配置檔案複製程式碼
- 下載安裝依賴:less-loader less
npm install less-loader less -dev複製程式碼
- 修改 config 目錄下的webpack配置檔案:
- 需同時修改下面的兩個檔案:
- 開發環境下的配置檔案:webpack.config.dev.js
- 生產環境下的配置檔案:webpack.config.prod.js
- 兩個檔案的修改內容相同,對應修改內容如下(三處需要進行修改)
複製程式碼
{
+ test: /\.(css|less)$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
+ importLoaders: 2,
},
},
{ .... },
+ {
+ loader: require.resolve('less-loader'),
+ }
],
}
複製程式碼複製程式碼
4.2 方法二: 使用 react-app-rewired 對 webpack 進行自定義配置(覆蓋或新增)
4.2.1 react-app-rewired 老版本配置方法
react-app-rewired 的使用
- 安裝 react-app-rewired 外掛
npm install react-app-rewired --save-dev
修改 package.json 中的指令碼命令:修改如下
"scripts": {
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test --env=jsdom",
+ "eject": "react-app-rewired eject"
}
複製程式碼
- 在專案根目錄下(和 package.json 同級)新建配置檔案 config-overrides.js ,並新增如下內容
module.exports = function override(config, env) { // 在這裡新增配置 return config;}複製程式碼
修改配置檔案 config-overrides.js 使得專案能夠支援 less
- 安裝依賴包 react-app-rewire-less,通過該依賴包來實現對 less 的支援:
# 說明: 這裡不再需要額外單獨安裝依賴包:less-loader lessnpm install react-app-rewire-less --save複製程式碼
- 修改 config-overrides.js 配置檔案
+ const rewireLess = require('react-app-rewire-less'); module.exports = function override(config, env) { + // 只需要一條配置資訊即可實現對less的支援 + config = rewireLess(config, env); return config; } 複製程式碼
4.2.2 react-app-rewired 新版本配置方法( >=2.1.0 )
react-app-rewired 的使用: 使用上和舊版本基本一樣只是在配置上需要額外通過 customize-cra 外掛來實現
- 安裝 react-app-rewired customize-cra 外掛
複製程式碼
- npm install react-app-rewired customize-cra --save-dev
- 修改 package.json 中的指令碼命令:修改如下
複製程式碼
"scripts": {
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test --env=jsdom",
+ "eject": "react-app-rewired eject"
}
複製程式碼
- 在專案根目錄下(和 package.json 同級)新建配置檔案 config-overrides.js ,並新增如下內容
複製程式碼
const { override } = require('customize-cra');module.exports = override();複製程式碼
修改配置檔案 config-overrides.js 使得專案能夠支援 less
- 安裝依賴: less less-loader
複製程式碼
- npm install less less-loader --save-dev
- 修改 config-overrides.js 配置檔案: addLessLoader
複製程式碼
+ const { override, addLessLoader } = require('customize-cra');
module.exports = override(
+ addLessLoader({
+ strictMath: true,
+ noIeCompat: true
+ })
);
複製程式碼
五、 在 create-react-app 中使用Antd
安裝 antd 依賴包:
npm install antd --save
複製程式碼
5.1 方法一: 直接匯入所有樣式, 並引用相應元件
引入 antd 元件之前需要先引入 antd 樣式( 在專案入口引入所有樣式 ):
import antd/dist/antd.css
複製程式碼
在專案中引入 antd 元件
import { Button } from 'antd';複製程式碼
5.2 方法二: 按需載入
- 上面引入元件和樣式的方式,會一次性載入所有樣式並引入元件中的所有相應模組;
- 這種引入方式將會影響到應用的網路效能;
- 相應的就需要改變引入元件和樣式的方式,實現樣式和元件的按需載入;
- 下面將介紹三種按需載入元件樣式的方法:
5.2.1 引入獨立的元件和樣式
import Button from 'antd/lib/button';i
mport 'antd/lib/button/style';
// 或者通過import antd/lib/button/style/css 進行載入樣式複製程式碼
5.2.2 通過暴露配置並使用 babel-plugin-import 外掛實現按需載入
babel-plugin-import 是一個用於按需載入元件程式碼和樣式的 babel 外掛
暴露配置
npm run eject
安裝外掛:
npm install babel-plugin-import --save-dev
複製程式碼
修改 package.json
"babel": {
"presets": [
"react-app"
],
"plugins": [
+ ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
]
},
複製程式碼
- 配置完後可直接匯入 antd 的元件,不再需要另外引入css樣式;
複製程式碼
- import { Button } from 'antd';
5.2.2 react-app-rewired + babel-plugin-import 實現按需載入(官網推薦)
react-app-rewired 老版本配置方法
- babel-plugin-import 是一個用於按需載入元件程式碼和樣式的 babel 外掛;
- react-app-rewired 的使用在第四節已經有了詳細的描述這裡不在贅述;
- 下文直接通過修改 config-overrides.js 配置來實現 antd 的按需載入
- 安裝依賴包:babel-plugin-import
- npm install babel-plugin-import --save-dev
- 修改配置檔案 config-overrides.js: 通過 injectBabelPlugin 外掛實現 babel 的新增
複製程式碼
+ const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
+ config = injectBabelPlugin(['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }], config);
return config;
};
複製程式碼
react-app-rewired 新版本配置方法( >=2.1.0 )
- 新版本可以直接通過 customize-cra 的 fixBabelImports 方法實現按需載入
複製程式碼
+const { override, addLessLoader, fixBabelImports } = require('customize-cra');
module.exports = override(
addLessLoader({
strictMath: true,
noIeCompat: true
}),
+ fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }),
);
複製程式碼
5.3 通過 react-app-rewired 擴充套件 webpack 來實現 antd 自定義主題
- 主要通過利用了 less-loader 的 modifyVars 引數來進行主題配置
- 下面是基於第四節中對 less 的配置的基礎上新增 modifyVars 引數來實現自定義主題的目的
5.3.1 react-app-rewired 老版本配置方法
- 修改 config-overrides.js 配置檔案
複製程式碼
const rewireLess = require('react-app-rewire-less');
const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
// 擴充套件 webpack ==> 支援less
config = rewireLess(config, env);
// 配置 less-loader 載入引數
+ config = rewireLess.withLoaderOptions({modifyVars: { "@primary-color": "#1DA57A" },})(config, env);
// antd 按需載入配置
config = injectBabelPlugin(['import',
{ libraryName: 'antd', libraryDirectory: 'es', style: true }], config);
return config;
}
複製程式碼
5.3.2 react-app-rewired 新版本配置方法( >=2.1.0 )
- addLessLoader 必須新增
javascriptEnabled: true
- fixBabelImports 實現對 antd 按需載入時需要設定
style: true
const { override, addLessLoader, fixBabelImports } = require('customize-cra');
module.exports = override(
addLessLoader({
strictMath: true,
noIeCompat: true,
+ javascriptEnabled: true,
+ modifyVars: { "@primary-color": "#1DA570" }
}),
+ fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: true }),
);
---------------------
複製程式碼
六、 實現對修飾器的支援: 實現對 babel 外掛的使用
安裝外掛
# 如果你的 Babel < 7.x 則安裝
babel-plugin-transform-decorators-legacy
npm install --save-dev babel-plugin-transform-decorators-legacy
# 如果你的 Babel >= 7.x 則應該安裝
@babel/plugin-proposal-decorators
npm install --save-dev @babel/plugin-proposal-decorators
複製程式碼
6.1 方法一: 暴露配置並進行修改
- 假設當前 Babel >= 7.x, 如果你的 Babel < 7.x 則需要將
["@babel/plugin-proposal-decorators", {"legacy": true}]
修改為["transform-decorators-legacy"]
暴露配置
npm run eject複製程式碼
修改 package.json"babel": {
"presets": [ "react-app" ],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{"legacy": true}
]
]
},複製程式碼
6.2 方法二: 使用 react-app-rewired 對 webpack 進行自定義配置(覆蓋或新增)
6.2.1 react-app-rewired 老版本配置方法
- react-app-rewired 的使用參考第四節:
- 修改 config-overrides.js 配置檔案
// 匯入新增babel外掛的函式
+const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
+ config = injectBabelPlugin(["@babel/plugin-proposal-decorators", {"legacy": true}], config)
return config;
};
複製程式碼
6.2.2 react-app-rewired 新版本配置方法( >=2.1.0 )
- react-app-rewired 的使用參考第四節:
- 修改 config-overrides.js 配置檔案:
- 下面給出了三種配置 babel 外掛的方法,
- addBabelPlugin 和 addBabelPlugins 用法類似
useBabelRc 是允許專案使用
- .babelrc 配置檔案進行配置
+const {
+ override, addLessLoader, fixBabelImports,
+ addBabelPlugin, addBabelPlugins, useBabelRc
+} = require('customize-cra');
module.exports = override(
addLessLoader({
strictMath: true,
noIeCompat: true,
javascriptEnabled: true,
modifyVars: { "@primary-color": "#1DA570" }
}),
fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: true }),
+ addBabelPlugin(["@babel/plugin-proposal-decorators", {"legacy": true}]),
+ // ...addBabelPlugins(
+ // ["@babel/plugin-proposal-decorators", {"legacy": true}]
+ // ),
+ // useBabelRc(),
);
複製程式碼複製程式碼
七、 eslint 配置
7.1 暴露配置並進行修改
- 執行指令碼 暴露配置檔案
npm run eject複製程式碼
- 通過修改 package.json 檔案新增對 eslint 的擴充套件配置
複製程式碼
...
"eslintConfig": {
// 預設繼承 腳手架自帶的 eslint 配置
"extends": "react-app",
// 在這裡擴充套件新增配置
"rules":{
// 設定規則,具體看官網使用者指南下的規則文件
"eqeqeq": "off"
}
}
複製程式碼
7.2 使用 react-app-rewired 對 webpack 進行自定義配置(覆蓋或新增)
7.2.1 react-app-rewired 老版本配置方法
- react-app-rewired 的使用參考第四節:
- 安裝依賴:
- npm install react-app-rewired react-app-rewire-eslint --save
- 修改 config-overrides.js 配置檔案
+ const rewireEslint = require('react-app-rewire-eslint');
module.exports = function override(config, env) {
+ config = rewireEslint(config, env);
return config;
}
複製程式碼
- 在根目錄下建立 .eslintrc 並自定義eslint配置
複製程式碼
{
"rules": {
// 設定規則,具體看官網使用者指南下的規則文件
"eqeqeq": "off"
}
}
複製程式碼複製程式碼
7.2.2 react-app-rewired 新版本配置方法( >=2.1.0 )
- react-app-rewired 的使用參考第四節:
- 修改 config-overrides.js 配置檔案: 通過 useEslintRc 啟用 .eslintrc 配置檔案
const { override, useEslintRc } = require('customize-cra');module.exports = override(+ useEslintRc(),);複製程式碼
- 在根目錄下建立 .eslintrc 並自定義eslint配置
複製程式碼
{
"rules": {
// 設定規則,具體看官網使用者指南下的規則文件
"eqeqeq": "off"
}
}
複製程式碼複製程式碼
const path = require('path')//配置vw// const postcssAspectRatioMini = require('postcss-aspect-ratio-mini');// const postcssPxToViewport = require('postcss-px-to-viewport');// const postcssWriteSvg = require('postcss-write-svg');// // const postcssCssnext = require('postcss-cssnext');// const postcssPresetEnv = require('postcss-preset-env');// const postcssViewportUnits = require('postcss-viewport-units');// const cssnano = require('cssnano');// module.exports = function override(config, env) {// config.resolve.alias = {// ...config.resolve.alias,// '@': path.resolve(__dirname, 'src'),// };// return config;// };// const rewireEslint = require("react-app-rewire-eslint");
使用 customize-cra 配置 const { useEslintRc, override , addWebpackAlias, addWebpackResolve, addPostcssPlugins} = require('customize-cra');// function overrideEslintOptions(options) {// // do stuff with the eslint options...// return options;// }module.exports = { webpack:override(
// 配置別名 addWebpackAlias({ ["@"]: path.resolve(__dirname, 'src'), }),
// 配置使用viewport (vw) 外掛 -- start addPostcssPlugins([require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009', }, stage: 3, }), require('postcss-aspect-ratio-mini')({}), require('postcss-px-to-viewport')({ viewportWidth: 750, // (Number) The width of the viewport. viewportHeight: 1334, // (Number) The height of the viewport. unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to. viewportUnit: 'vw', // (String) Expected units. selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px. minPixelValue: 1, // (Number) Set the minimum pixel value to replace. mediaQuery: false // (Boolean) Allow px to be converted in media queries. }), require('postcss-write-svg')({ utf8: false }), require('postcss-viewport-units')({}), require('cssnano')({ preset: "advanced", autoprefixer: false, "postcss-zindex": false })]),
// 配置使用viewport (vw) 外掛 -- start // 啟用eslint
//useEslintRc(), ), devServer: function(configFunction) { // Return the replacement function for create-react-app to use to generate the Webpack // Development Server config. "configFunction" is the function that would normally have // been used to generate the Webpack Development server config - you can use it to create // a starting configuration to then modify instead of having to create a config from scratch. return function(proxy, allowedHost) { // Create the default config by calling configFunction with the proxy/allowedHost parameters const config = configFunction(proxy, allowedHost); // Change the https certificate options to match your certificate, using the .env file to // set the file paths & passphrase. /* const fs = require('fs'); config.https = { key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'), cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'), ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'), passphrase: process.env.REACT_HTTPS_PASS }; */ /* config.proxy = { "/api": { "target": "http://lemonof.com:82", "pathRewrite": {"^/api" : ""} } } */ // Return your customised Webpack Development Server config. return config; }; },}複製程式碼
// 使用普通 react-app-rewire-postcs 配置viewport
const path = require('path')//配置vw// const postcssAspectRatioMini = require('postcss-aspect-ratio-mini');// const postcssPxToViewport = require('postcss-px-to-viewport');// const postcssWriteSvg = require('postcss-write-svg');// // const postcssCssnext = require('postcss-cssnext');// const postcssPresetEnv = require('postcss-preset-env');// const postcssViewportUnits = require('postcss-viewport-units');// const cssnano = require('cssnano');// module.exports = function override(config, env) {// config.resolve.alias = {// ...config.resolve.alias,// '@': path.resolve(__dirname, 'src'),// };// return config;// };// const rewireEslint = require("react-app-rewire-eslint");const { useEslintRc, override , addWebpackAlias, addWebpackResolve, addPostcssPlugins} = require('customize-cra');// function overrideEslintOptions(options) {// // do stuff with the eslint options...// return options;// }module.exports = { webpack: function(config, env) {
// 配置別名 config.resolve.alias = { ...config.resolve.alias, '@': path.resolve(__dirname, 'src'), };
// viewport(開始) ---start require('react-app-rewire-postcss')(config, { plugins: loader => [ require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009', }, stage: 3, }), require('postcss-aspect-ratio-mini')({}), require('postcss-px-to-viewport')({ viewportWidth: 750, // (Number) The width of the viewport. viewportHeight: 1334, // (Number) The height of the viewport. unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to. viewportUnit: 'vw', // (String) Expected units. selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px. minPixelValue: 1, // (Number) Set the minimum pixel value to replace. mediaQuery: false // (Boolean) Allow px to be converted in media queries. }), require('postcss-write-svg')({ utf8: false }), require('postcss-viewport-units')({}), require('cssnano')({ preset: "advanced", autoprefixer: false, "postcss-zindex": false }) ] });
// viewport(開始) ---end // config = rewireEslint(config, env, overrideEslintOptions); return config; }, devServer: function(configFunction) { // Return the replacement function for create-react-app to use to generate the Webpack // Development Server config. "configFunction" is the function that would normally have // been used to generate the Webpack Development server config - you can use it to create // a starting configuration to then modify instead of having to create a config from scratch. return function(proxy, allowedHost) { // Create the default config by calling configFunction with the proxy/allowedHost parameters const config = configFunction(proxy, allowedHost); // Change the https certificate options to match your certificate, using the .env file to // set the file paths & passphrase. /* const fs = require('fs'); config.https = { key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'), cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'), ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'), passphrase: process.env.REACT_HTTPS_PASS }; */ /* config.proxy = { "/api": { "target": "http://lemonof.com:82", "pathRewrite": {"^/api" : ""} } } */ // Return your customised Webpack Development Server config. return config; }; },}// webpack: function(config, env) {// config.resolve.alias = {// ...config.resolve.alias,// '@': path.resolve(__dirname, 'src'),// };// require('react-app-rewire-postcss')(config, {// plugins: loader => [// require('postcss-flexbugs-fixes'),// require('postcss-preset-env')({// autoprefixer: {// flexbox: 'no-2009',// },// stage: 3,// }),// require('postcss-aspect-ratio-mini')({}),// require('postcss-px-to-viewport')({// viewportWidth: 750, // (Number) The width of the viewport.// viewportHeight: 1334, // (Number) The height of the viewport.// unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.// viewportUnit: 'vw', // (String) Expected units.// selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.// minPixelValue: 1, // (Number) Set the minimum pixel value to replace.// mediaQuery: false // (Boolean) Allow px to be converted in media queries.// }),// require('postcss-write-svg')({// utf8: false// }),// require('postcss-viewport-units')({}),// require('cssnano')({// preset: "advanced",// autoprefixer: false,// "postcss-zindex": false// })// ]// });// // config = rewireEslint(config, env, overrideEslintOptions);// useEslintRc();// return config;// },複製程式碼