搭建 React 17 原始碼本地除錯環境
阿新 • • 發佈:2022-04-11
通過這種方式只能除錯編譯之後的程式碼,不能實現原汁原味的原始碼除錯體驗。查閱一些社群的實現,記錄下步驟,方便後續查閱。
也可以直接 clone 配置好的倉庫:https://github.com/shanejix/react-source-code-debug
步驟
- 使用 create-react-app 腳手架建立專案
npx create-react-app react-source-code-debug
- 彈射 create-react-app 腳手架內部配置
yarn run eject
- 克隆 react 官方原始碼 (在專案的根目錄下進行克隆)
git clone --branch v17.0.2 --depth=1 https://github.com/facebook/react.git src/react
- 通過 alias ,連結本地原始碼
// 檔案位置: react-source-code-debug/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 || {}), + // FIXME: REACT SOURCE CODE DEBUG + 'react': path.resolve(__dirname, '../src/react/packages/react'), + 'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'), + 'shared': path.resolve(__dirname, '../src/react/packages/shared'), + 'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'), + // 'scheduler': path.resolve(__dirname, '../src/react/packages/scheduler'), }, }
- 修改環境變數
// 檔案位置: react-source-code-debug/config/env.js // FIXME: REACT SOURCE CODE DEBUG const stringified = { + __DEV__: true, + __PROFILE__: true, + __UMD__: true, + __EXPERIMENTAL__: true, 'process.env': Object.keys(raw).reduce((env, key) => { env[key] = JSON.stringify(raw[key]); return env; }, {}), };
- 在根目錄建立
eslintrc.json
檔案,內容如下
{
"extends": "react-app",
"globals": {
"__DEV__": true,
"__PROFILE__": true,
"__UMD__": true,
"__EXPERIMENTAL__": true
}
}
- 修改 ReactFiberHostConfig.js 檔案
// 檔案位置: /react/packages/react-reconciler/src/ReactFiberHostConfig.js
- import invariant from 'shared/invariant';
- invariant(false, 'This module must be shimmed by a specific renderer.');
+ // FIXME: REACT SOURCE CODE DEBUG
+ export * from './forks/ReactFiberHostConfig.dom'
- 修改 ReactSharedInternals.js 檔案
// 檔案位置: /react/packages/shared/ReactSharedInternals.js
- import * as React from 'react';
- const ReactSharedInternals =
- React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
+ // FIXME: REACT SOURCE CODE DEBUG
+ import ReactSharedInternals from '../react/src/ReactSharedInternals';
+ export default ReactSharedInternals;
- 修改 invariant.js 檔案
// 檔案位置: /react/packages/shared/invariant.js
export default function invariant(condition, format, a, b, c, d, e, f) {
+ // FIXME: REACT SOURCE CODE DEBUG
+ if (condition) {
+ return;
+ }
throw new Error(
'Internal React error: invariant() is meant to be replaced at compile ' +
'time. There is no runtime version.',
);
}
- 關閉 eslint 擴充套件
// 檔案位置: react/.eslingrc.js [module.exports]
- extends: [
- 'fbjs',
- 'prettier'
- ]
- 解決 eslint 報錯
// 將 webpack 中 eslint 外掛給關掉,修改 src/config/webpack.config.js 檔案
// ...
// FIXME: REACT SOURCE CODE DEBUG
// !disableESLintPlugin &&
// new ESLintPlugin({
// // Plugin options
// extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
// formatter: require.resolve('react-dev-utils/eslintFormatter'),
// eslintPath: require.resolve('eslint'),
// failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
// context: paths.appSrc,
// cache: true,
// cacheLocation: path.resolve(
// paths.appNodeModules,
// '.cache/.eslintcache'
// ),
// // ESLint class options
// cwd: paths.appPath,
// resolvePluginsRelativeTo: __dirname,
// baseConfig: {
// extends: [require.resolve('eslint-config-react-app/base')],
// rules: {
// ...(!hasJsxRuntime && {
// 'react/react-in-jsx-scope': 'error',
// }),
// },
// },
// }),
- 告訴 babel 在轉換程式碼時忽略型別檢查
yarn add @babel/plugin-transform-flow-strip-types -D
// 檔案位置: react-source-code-debug/config/webpack.config.js [babel-loader]
plugins: [
// ...
// FIXME: REACT SOURCE CODE DEBUG
[require.resolve("@babel/plugin-transform-flow-strip-types")],
];
- 新增 eslint 配置
// 在 react 原始碼資料夾中新建 .eslintrc.json 並新增如下配置
{
"extends": "react-app",
"globals": {
"__DEV__": true,
"__PROFILE__": true,
"__UMD__": true,
"__EXPERIMENTAL__": true
}
}
- 修改
react
react-dom
引入方式
- // import React from 'react';
- // import ReactDOM from 'react-dom';
+ // FIXME: REACT SOURCE CODE DEBUG
+ import * as React from 'react';
+ import * as ReactDOM from 'react-dom';
- 解決 VSCode 中 flow 報錯
// 新建 .vscode/setting.js
{
"typescript.validate.enable": false,
"javascript.validate.enable": false
}
- 解決 DEV 報錯
// 刪除 node_modules 資料夾,執行 npm install / yarn
// 根目錄下
rm -fr node_modules && yarn
references
- https://github.com/neroneroffy/react-source-code-debug/blob/master/docs/setUpDebugEnv.md
- https://juejin.cn/post/7014775797596553230
作者:shanejix
出處:https://www.shanejix.com/posts/搭建 React 17 原始碼本地除錯環境/
版權:本作品採用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。
宣告:轉載請註明出處!