通過 create-react-app 從零搭建 React 環境

qianyin925發表於2018-06-13

一、 快速開始:

  • 全域性安裝腳手架:
npm install -g create-react-app
複製程式碼
  • 通過腳手架搭建專案:
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,那麼就不能恢復了(再次將配置隱藏);

三、 自動生成的專案目錄以及檔案解析:

  • node_modules : 專案依賴包目錄;
  • public: 公共目錄,該目錄下的檔案都不會被webpack進行載入、解析、打包;通過npm run build進行打包時該專案下的所有檔案將會直接被複制到build目錄下;
    • favicon.ico : 是網站圖示[可替換刪除]
    • index.html: 頁面模板,webpack打包後將輸出檔案引入到該模板內;補充:index.html中通過環境變數%PUBLIC_URL% 來指向public目錄路徑;
    • manifest.json: PWA將應用新增至桌面的功能的實現依賴於 manifest.json 。通過manifest.json 檔案可以對圖示、名稱等資訊進行配置。
  • src: 是原始碼目錄該目錄下除了index.js App.test.js registerServiceWorker.js 檔案具有一定意義其餘檔案都是演示使用可直接刪除
    • index.js: 是整個專案的入口檔案;
    • App.test.js: 測試單元演示檔案,暫時並不知道幹嘛用;可以直接刪除;
    • registerServiceWorker.js: service worker 是在後臺執行的一個執行緒,可以用來處理離線快取、訊息推送、後臺自動更新等任務;registerServiceWorker就是為react專案註冊了一個service worker,用來做資源的快取,這樣你下次訪問時,就可以更快的獲取資源。而且因為資源被快取,所以即使在離線的情況下也可以訪問應用(此時使用的資源是之前快取的資源)。注意,registerServiceWorker註冊的service worker 只在生產環境中生效,並且該功能只有在https下才能有效果;
  • .gitignore: 該檔案是github過濾檔案配置
  • README.md: 該檔案是github描述檔案
  • package.json: 定義了專案所需要的各種模組,以及專案的配置資訊(比如名稱、版本、許可證等後設資料)。部分依賴模組被隱藏;
  • yarn.lock:每次通過yarm新增依賴或者更新包版本時 yarn都會把相關版本資訊寫入yarn.lock檔案;npm也有類似功能,npm 也可以生成一個鎖檔案,就是使用上沒有yarn方便

四、 新增對 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  less
npm 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';
import '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"
  }
}
複製程式碼

八、 常見問題:

8.1 通過 react-app-rewired 進行擴充套件配置時 發現啟動專案後並沒有效果?

  • 在確保一起配置沒有問題下:
  • 請確認是否有對指令碼命令進行了正確的修改,使用 react-app-rewired 擴充套件配置需要修改指令碼命令
{
  ....
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-app-rewired eject"
  },
...
}
複製程式碼

8.2 棄用通知, 則所有配置按新版本 react-app-rewired 配置方法來

The "injectBabelPlugin" helper has been deprecated as of v2.0. You can use customize-cra plugins in replacement
複製程式碼

相關文章