1. 程式人生 > >webpack + create-react-app 構建react專案

webpack + create-react-app 構建react專案

1.肯定參考facebook關於react官網咯 快速搭建 create-react-app

npm install -g create-react-app
//切記專案名稱不能大寫
create-react-app firstapp
cd firstapp
npm run start

這樣就有初始專案了

2. 檢視專案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 可用指令碼命令說明: (create-react-app官方文件都有)

  • 首先說明:通過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,那麼就不能恢復了(再次將配置隱藏);

 

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

  • 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方便

 

4、 擴充套件webpack配置(以 less為例)

4.1 方法一:將 webpack 配置暴露出來並進行修改

  • 暴露配置檔案:
$ 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
// 兩個檔案的修改內容相同,對應修改內容如下(三處需要進行修改)
......
{
    // 【1】修改檔案匹配正則
    test: /\.(css|less)$/, 
    use: [
        require.resolve('style-loader'),
        {
            loader: require.resolve('css-loader'),
            options: {
            // 【2】將原本數字 1  改為數字2
            importLoaders: 2,
        },
        },
        { .... },
        // 【3】新增新的載入配置物件
        {
            loader: require.resolve('less-loader'),
        }
    ],
}
......

4.2 方法二:使用 react-app-rewired 對 webpack 進行自定義配置(覆蓋或新增)

  • 安裝依賴包 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;
}
  • 安裝依賴包 react-app-rewire-less,通過該依賴包來實現對 less 的支援:
$ npm install react-app-rewire-less --save
說明: 這裡不再需要額外單獨安裝依賴包:less-loader  less
  • 修改 config-overrides.js 配置檔案,為 webpack 配置 less
const rewireLess = require('react-app-rewire-less');
module.exports = function override(config, env) {
  // 只需要一條配置資訊即可實現對less的支援
  config = rewireLess(config, env);
  // 下面註釋用於配置loader的引數
  // config = rewireLess.withLoaderOptions(someLoaderOptions)(config, env);
  return config;
}

 

5、 在 create-react-app 中使用Antd

5.1 一般使用方法(不推薦)

  • 搭建專案:
$ create-react-app demo
$ cd demo
$ npm run start
  • 引入 antd 依賴包:
$ npm install npm
  • 引入 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';9

5.2.2 方法三:通過 babel-plugin-import + react-app-rewired實現按需載入(官網推薦)

  1. react-app-rewired:的使用上文有過描述;主要用於在不暴露配置的情況下對webpack的配置進行擴充套件;
  2. babel-plugin-import 是一個用於按需載入元件程式碼和樣式的 babel 外掛
  • 安裝依賴包:babel-plugin-import
$ npm install babel-plugin-import --save-dev
  • 通過 react-app-rewired 對 webpack 配置進行擴充套件新增新的babel外掛,config-overrides.js 修改 ( 新增 ) 如下內容:
// 引入 react-app-rewired 新增 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;
};
  • 配置完後可直接匯入 antd 的元件,不再需要另外引入css樣式;
import { Button } from 'antd';9

5.3 通過 react-app-rewired 擴充套件 webpack 來實現 antd 自定義主題

主要通過利用了 less-loader 的 modifyVars 引數來進行主題配置

  • 安裝配置:react-app-rewired (上文已經詳細介紹過這裡就不再細說)
  • 安裝依賴包 react-app-rewire-less :實現對 less 的支援同時新增 modifyVars 載入引數設定
$ npm react-app-rewire-less --save-dev
  • 修改 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);
    // 配置loader引數
    config = rewireLess.withLoaderOptions({
        // 修改預設顏色 實現自定義主題
        modifyVars: { "@primary-color": "#1DA57A" },
   })(config, env);
   // antd 按需載入配置
    config = injectBabelPlugin(['import', 
        { libraryName: 'antd', libraryDirectory: 'es', style: true }], config);
    return config;
}

5.4 通過外掛 babel-plugin-transform-decorators-legacy 實現對修飾器的支援

5.4.1 通過暴露配置實現

  • 暴露配置
$ npm run eject
  • 安裝外掛:
$ npm install --save-dev babel-plugin-transform-decorators-legacy
  • 修改 package.json
"babel": {
  "presets": [
    "react-app"
  ],
  "plugins": [
    ["transform-decorators-legacy"]
  ]
},

5.4.2 使用外掛 react-app-rewired 對配置進行擴充套件實現對修飾器的支援

  • react-app-rewired 的使用詳見上文:
  • 安裝外掛:
$ npm install --save-dev babel-plugin-transform-decorators-legacy
  • 編寫 config-overrides.js 配置檔案
// 匯入新增babel外掛的函式
const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
  // do stuff with the webpack config...
  // 修飾器擴充套件 (新增babel外掛:transform-decorators-legacy )
  config = injectBabelPlugin('transform-decorators-legacy', config)
  return config;
};

6、 常見問題:

6.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"
  },
...
}