React源碼解讀-本地開發環境搭建

React源碼解讀-本地開發環境搭建

前幾天有小夥伴和我聊天,談到如今前端面試愈來愈難,動不動就是xxx原理,有沒有看過xx源碼之類的問題,前端

以後就問我應該怎麼來學習如今主流框架的源碼,因而有了這一篇文章.react

說到使用react那很簡單 react 和reactdom 兩個文件引入一下就ok,可是這兩個文件是通過編譯打包,咱們沒法在裏面進行斷點調試或者console調試,webpack

因此想學習框架源碼,第一步就要在本地運行源碼這樣才能在內部進行各類輸出調試。git

好了閒話不說,直接開始正題github

React源碼獲取

在這裏我選擇用的的版本是16.10.0 ,web

獲取方式固然是react的git倉庫面試

建立測試項目

  • 在本地經過create-react-app建立測試項目
  • 建立完項目以後要修改源碼以及webopack配置,須要 將‘旺旺大禮包’給解出來npm

    npm run eject
  • 項目目錄下會多出一個config文件

reject目錄

將建立的項目替換爲下載的源碼文件

  • 將下載16.10.0的項目源碼丟到src目錄下

源碼目錄

  • 更改配置文件 ==/config/webpack.config.js== 在運行項目的時候編譯咱們導入的源碼爲
resolve:{

        ...,

        alias: {

        // 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 || {}),

        'react': path.resolve(__dirname, '../src/react/packages/react'),

        'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),

        'legacy-events': path.resolve(__dirname, '../src/react/packages/legacy-events'),

        'shared': path.resolve(__dirname, '../src/react/packages/shared'),

        'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'),

      },

    }
錯誤處理

替換完成後,由於版本和編譯的緣由會遇到各類錯誤,react-native

具體的錯誤類型與解決方式,在這裏作一個簡單的介紹babel

flow 檢測報錯

flow檢測錯誤

  • 因爲react的源碼中採用了flow這個東東作類型檢查,

因此咱們須要安裝 ==@babel/plugin-transform-flow-strip-types== 這個插件忽略類型檢測

  • 插件安裝
npm install @babel/plugin-transform-flow-strip-types -D
  • 插件配置
//在webpack.config.js的babel-loader中添加配置

    {

        test: /\.(js|mjs|jsx|ts|tsx)$/,

        include: paths.appSrc,

        loader: require.resolve('babel-loader'),

        options: {

        customize: require.resolve(

          'babel-preset-react-app/webpack-overrides'

        ),



        plugins: [

          ...,

          [require.resolve('@babel/plugin-transform-flow-strip-types')]

          // 配置忽略flow類型檢測

        ],

        ...

    }

HostConfig配置錯誤

報錯提示

  • 修改文件 ==src/react/packages/react-reconciler/src/ReactFiberHostConfig.js==, 根據環境去導出HostConfig。
//添加如下代碼

export * from './forks/ReactFiberHostConfig.dom';

部分全局變量報錯

報錯提示

  • 修改 ==/config/env.js== 中的stringifed對象增長屬性
const stringified = {

    'process.env': Object.keys(raw).reduce((env, key) => {

      env[key] = JSON.stringify(raw[key]);

      return env;

    }, {}),

    "__DEV__": true,

    "__PROFILE__": true,

    "__UMD__": true

  };

hasOwnProperty ReactSharedInternals.js錯誤

錯誤提示

  • 修改文件 ==src/react/packages/shared/ReactSharedInternals.js。==
// react此時未export內容,直接從ReactSharedInternals拿值

// import React from 'react';

// 此時React爲undefined

// const ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;

import ReactSharedInternals from '../react/src/ReactSharedInternals';

invariant() 函數報錯

inval函數報錯

  • ==src/react/packages/shared/invariant.js== 文件下 invariant 函數的錯誤處理
  • 修改以下:
export default function invariant(condition, format, a, b, c, d, e, f) {

  if(condition) return ;

  throw new Error(

    'Internal React error: invariant() is meant to be replaced at compile ' +

      'time. There is no runtime version.',

  );

}

到此爲止如今運行的react項目採用的使咱們下載導入的react16.10.0的源碼,咱們就能夠在源碼裏進行輸出的錯誤調試

好比我在react/index.js源碼 進行輸出測試

'use strict';

const React = require('./src/React');

console.log('源碼測試',React)

// TODO: decide on the top-level export form.

// This is hacky but makes it work with both Rollup and Jest.

module.exports = React.default || React;

結果

嫌棄本地測試環境配置太麻煩的話,各位小主能夠直接從個人git項目上下拉我配置好的開發項目

npm install

npm start

GIT

ReactSourceCodeAnalyze:

https://github.com/fchangjun/ReactSourceCodeAnalyze.git


若是感受這篇文章有用,請各位小主關注公衆號,隨手轉發一下下.

公衆號

相關文章
相關標籤/搜索