摘要:會有一探源碼的想法。理想的情況是直接引用源文件,也就是上倉庫中,目錄下的代碼,直接閱讀的代碼。所以需要配置打包成。坑概述至此,環境已經配的差不多了。不過這個環境配置過程中并非一帆風順。
前言
閱讀源碼時,有許多變量在程序運行過程中不斷的產生,其中存放著什么東西,一直是一個比較頭疼的問題。不停的推導增加了驗算的負擔,隨著代碼逐漸的深入,也會產生一定的記憶負擔。如果靠腦袋去記,簡單點的代碼還好。復雜的代碼。。。你懂的。
隨著react被廣泛使用,很多人會好奇react是怎么實現的。會有一探源碼的想法。如果直接閱讀react.development.js是很簡單,頁面引入就好了。但是react.development.js終于是經過編譯工具編譯過的代碼,很多的代碼看起來并不直觀。理想的情況是直接引用源文件,也就是github上react倉庫中,packages目錄下的代碼,直接閱讀es6的代碼。
但是es6代碼瀏覽器支持并不友好。所以需要配置webpack打包成es5。同時需要配上sourceMap。這樣,既可以讓源碼跑在瀏覽器環境,也可以直接讀es6的代碼,而且可以隨時打斷點,查看變量里保存的值。
那么,閑言少敘,開始本章的主題。
目錄結構 概述這是我目前用的一個簡單的目錄結構。此次調試的代碼為react 16.4.0
詳情node_modules 存放依賴的包
packages github上的packages文件夾直接拿來用
test-env 測試用的目錄
index.js #引用react、react-dom的啟動文件
index.less
tpl.html # html模板文件
webpack的配置 概要webpack的配置就是常規的babel,和一堆loader。為了提高打包速度,可以使用Happypack插件。如果覺得速度還不夠快,可以再引入DLLplugin。此處webpack的使用不是重點,在此只是簡單給出打包需要的基本配置
代碼如下:
const HtmlWebpackPlugin = require("html-webpack-plugin"); const path = require("path"); const webpack = require("webpack"); const os = require("os"); const HappyPack = require("happypack"); const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); module.exports = { mode: "development", entry: "./test-env/index.js", output: { path: __dirname + "/dist", filename: "index_bundle.js" }, module: { rules: [{ test: /.css$/, use: { loader: "happypack/loader?id=happyLess", } }, { test: /.less$/, use: { loader: "happypack/loader?id=happyLess", } }, { test: /.js$/, use: { loader: "happypack/loader?id=happyBabel", } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./test-env/tpl.html" }), new webpack.HotModuleReplacementPlugin(), new webpack.DefinePlugin({ __DEV__: true, NODE_ENV:JSON.stringify("development"), spyOnDev: false, spyOnDevAndProd: false, spyOnProd: false, __PROFILE__: true, }), new HappyPack({ //用id來標識 happypack處理那里類文件 id: "happyBabel", //如何處理 用法和loader 的配置一樣 loaders: [{ loader: "babel-loader?cacheDirectory=true", }], //共享進程池 threadPool: happyThreadPool, //允許 HappyPack 輸出日志 verbose: true, }), new HappyPack({ //用id來標識 happypack處理那里類文件 id: "happyLess", //如何處理 用法和loader 的配置一樣 loaders: ["style-loader","css-loader","less-loader"], //共享進程池 threadPool: happyThreadPool, //允許 HappyPack 輸出日志 verbose: true, }), ], devtool: "inline-source-map", // enum devServer: { contentBase: path.join(__dirname, "test-env"), port: 9000, hot: true, overlay: true }, resolve: { modules: [ "node_modules", path.resolve(__dirname, "packages"), path.resolve(__dirname, "packages/shared") ], alias: { "@packages": path.resolve(__dirname, "packages/"), } } };babel配置
{ "presets": ["env","react","stage-0"], }入口文件 概述
為了簡化項目流程,此處用了一個最簡單的tpl.html模板文件,通過webpackhtmlplugin引入了打包好后的帶sourcemap的js。
其中,js只是用react實現了一個簡單的Hello world并且用react-render渲染到頁面上。
import "./index.less"; import React, {Component} from "@packages/react"; import ReactDOM from "@packages/react-dom/index.js"; class Hello extends Component{ constructor(){ super(); console.log("hello world"); } render() { returnhello world} } ReactDOM.render(, document.getElementById("root"));
其中@packages是我在webpack中配置的路徑別名,對應packages目錄。
tpl.html坑 概述Document hello world;
至此,環境已經配的差不多了。只是實際運行的時候還是需要安裝一些包。此處忽略了裝包的過程。但是實際項目運行中控制臺還是報了一些錯。其中一個最糾結的地方
This module must be shimmed by a specific renderer.自環境配好后我遇到的第一個問題是這句話。起初以為是react的問題。糾結了好幾個小時候,才找到了問題的根源。
問題并不來react這個包既然問題不是react,那來自哪里呢。沒錯,來自react-dom,因為頁面上總共就引用了兩個包,非react則react-dom
問題解決思路通過錯誤信息處函數調用堆棧可以看出,該錯誤來源于一個ReactFiberHostConfig.js中。雖然不知道這里為什么會有這個,但是還是想去源倉庫找找答案。看了react官方實際使用了rollup去打包代碼。但是rollup里一大坨看不懂得代碼。那怎么辦呢。去搜索這個hostconfig.js是什么鬼。
貌似的答案react為了實現將同樣的結構,render到不同的平臺,使用了react-reconciler做了一個中間層。提供接口可以讓用戶自定義render的實現,并且給出了一個render-dom的示例。但是不管使用哪種render,都要提供一個hostconfig,源碼中這個react-reconciler文件夾中引用的config總是會拋出一段錯誤,但是實際上,正確的config已經在文件夾中給出,只要將拋錯這段代碼給替換成引用正確的config即可。
歸納總結錯誤調用棧 react-dom-》react-reconciler-》hostconfig error
解決
react-reconclier中src下的ReactFiberHostConfig中的報錯改為引用正確的config。貼上引用代碼
export * from "./forks/ReactFiberHostConfig.dom";完結撒花
至此已經可以在瀏覽器中調試es6版本的react代碼。不過這個環境配置過程中并非一帆風順。首先遇到錯首先以為是react的問題。糾結了好幾個晚上(下班后才開始想),網上查閱了很多資料,也沒想出所以然,最后發現是react-dom的問題,也糾結了好久,最終終于配起了這套環境。
喜歡的朋友點個贊哈。謝謝支持。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96666.html
摘要:閱讀本期周刊,你將快速入門,開啟甜蜜之旅。然則的原理負責發送以及處理消息,創建消息隊列并不斷從隊列中取出消息交給,則用于保存消息。 showImg(/img/bVCN99?w=900&h=385); 2016 年 8 月,Android 7.0 Nougat(牛軋糖)正式發布,那么問題來了,你 Marshmallow 了么(? -? ?) Cupcake、Donut、Gingerbre...
摘要:我們先來看下這個函數的一些神奇用法對于上述代碼,也就是函數來說返回值是。不管你第二個參數的函數返回值是幾維嵌套數組,函數都能幫你攤平到一維數組,并且每次遍歷后返回的數組中的元素個數代表了同一個節點需要復制幾次。這是我的 React 源碼解讀課的第一篇文章,首先來說說為啥要寫這個系列文章: 現在工作中基本都用 React 了,由此想了解下內部原理 市面上 Vue 的源碼解讀數不勝數,但是反觀...
摘要:第三篇腳手架依賴的核心庫的源碼解析。該篇是這個系列文章的第三篇主要是對的源碼進行分析講解。的源碼十分簡單但實現的功能卻是十分的強大。源碼概括源碼主要包含了兩部分公共方法和私有方法。 react作為當前十分流行的前端框架,相信很多前端er都有蠢蠢欲動的學習它的想法。工欲善其事,必先利其器。這篇文章就簡單的給大家介紹一下如何我快速的搭建一個react前端開發環境。主要針對于react小白,...
閱讀 1740·2021-11-25 09:43
閱讀 1785·2021-11-24 10:41
閱讀 3105·2021-09-27 13:36
閱讀 811·2019-08-30 15:53
閱讀 3567·2019-08-30 15:44
閱讀 866·2019-08-30 14:03
閱讀 2572·2019-08-29 16:38
閱讀 996·2019-08-29 13:23