react v16.12 源碼閱讀環境搭建

搭建後的代碼(Keep updated):

https://github.com/lirongfei123/read-reactjavascript

歡迎將源碼閱讀遇到的問題提到issuejava

環境搭建思路:

搭建一個webpack的demo, 對react的引用直接訪問其源碼
關鍵源碼

而後經過webpack的sourceMap查看react的源碼
效果以下:
node

步驟

Fork源碼

https://github.com/facebook/react
而後執行yarn(yarn 命令會自動執行packages裏面的全部依賴安裝)
若是太慢, 能夠用阿里的源: react

yarn config set registry 'https://registry.npm.taobao.org'

理解官方rollup打包

關鍵文件說明:

scripts/rollup/bundles.js

這個文件用來告訴打包器, 要打包出多少種版本, 這裏由於我們在web下閱讀源碼, 只須要用到UMD_DEV, 能夠把其餘的場景註釋掉, 這裏我直接替換變量


而後執行npm run buildwebpack

scripts/rollup/build.js

這個是真正的打包文件, 這裏咱們須要將rollup打包的一些特殊設置找出來, 而後轉化爲webpack的配置git

  1. 打包會替換一些動態內容, 好比: 報錯信息, 只會在dev環境存在, prod不存在
    1. 這個主要是經過babel動態替換, 因此咱們須要將babel插件提取出來
    2. 能夠經過getBabelConfig獲取, 建議看下這個函數,  引用了那幾個本機插件便可, 主要引用了scripts/babel下面兩個, 以及scripts/error-codes中一個
    3. 實際真正須要的是兩個plugin
    4. 因此只須要將這兩個插件引用到webpack的babel裏面便可
  2. 替換一些不一樣環境的文件, 好比: react-native 和 react 中用到的一些東西, 確定是不同的, 可是接口同樣, 就會根據打包相似動態替換
    1. 這個主要是經過動態替換模塊的源路徑實現的
    2. 這個能夠經過getForks來獲取
    3. 這裏我已經提取出來, 並經過一個簡單的webpack配置進行處理(見: webpack/replace.js)這裏須要將umd相關的東西刪除, 具體緣由未知
    4. 主要是這些文件
  3. 替換一些打包變量, 基本都設置爲debug模式便可, 根據scripts/jest/setupEnvironment.js 進行設置

構建webpack, 閱讀環境

基本和平時的項目同樣, 區別在於react的代碼從源碼直接引用, 詳細查看webpack/webpack.config.js
這裏簡單貼下源碼github

const path = require('path');
const webpack = require('webpack');
const __debug= true;
const replacePlugin = require('./replace');
module.exports = {
    entry: {
        main: './src/index.js',
    },
    output: {
        path: path.join(__dirname, 'build'),
        filename: '[name].js'
    },
    resolve: {
        modules: [
            path.join(__dirname, '../packages'),
            'node_modules',
        ]
    },
    module: {
        rules: [
            {
                loader: "babel-loader",
                options: {
                    babelrc: false,
                    presets: [
                        [
                            "@babel/preset-env",
                            {
                                targets: {
                                    esmodules: true,
                                    browsers: "> 0.25%, not dead"
                                },
                                debug: __debug,
                                modules: 'umd',
                                forceAllTransforms: !__debug,
                                useBuiltIns: false
                            }
                        ],
                        [
                            "@babel/preset-react",
                            {
                                development: false
                            }
                        ],
                        '@babel/preset-flow'
                    ],
                    plugins: [
                        require('../scripts/error-codes/transform-error-messages'),
                        // Wrap warning() calls in a __DEV__ check so they are stripped from production.
                        require('../scripts/babel/wrap-warning-with-env-check'),
                        '@babel/plugin-proposal-class-properties',
                        '@babel/plugin-proposal-object-rest-spread'
                    ]
                }
            },
        ]
    },
    mode: 'development',
    plugins: [
        new webpack.DefinePlugin({
            __DEV__: 'true',
            __PROFILE__: 'true',
            __UMD__: 'true',
            __EXPERIMENTAL__: true,
            'process.env.NODE_ENV': "'development'"
        }),
        new replacePlugin()
    ],
    devServer: {
        port: 3100
    }
}

 

而後npm start便可開始

在ReactDOM.render前面加個debugger便可進入全部的react源碼, 並能夠實時修改web

相關文章
相關標籤/搜索