国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

給一個裝修公司怎么做網(wǎng)站今日新聞播報

給一個裝修公司怎么做網(wǎng)站,今日新聞播報,制作網(wǎng)頁簡歷,安卓端開發(fā)模塊循環(huán)依賴問題 在項目比較小的時候可能不怎么會遇到這個問題,但項目一旦有一定的體量后就可能會遇到了。 我之前做項目時就遇到這個問題,也是總結(jié)一篇文章。 比如這種類型的報錯 commonjs存在的問題 先講一下commonjs存在的問題。 CommonJS模塊采…

模塊循環(huán)依賴問題

在項目比較小的時候可能不怎么會遇到這個問題,但項目一旦有一定的體量后就可能會遇到了。
我之前做項目時就遇到這個問題,也是總結(jié)一篇文章。

比如這種類型的報錯
在這里插入圖片描述

commonjs存在的問題

先講一下commonjs存在的問題。
CommonJS模塊采用深度優(yōu)先遍歷,并且是加載時執(zhí)行,即腳本代碼在require時就全部執(zhí)行。一旦出現(xiàn)某個模塊被“循環(huán)加載”,就只輸出已經(jīng)執(zhí)行的部分,沒有執(zhí)行的部分不會輸出。
舉例子

// a.js
require("./b.js");
exports.a = function () {};// b.js
const { a } = require("./a");
a();// index.js
require("./a.js");

執(zhí)行index.js
結(jié)果:報錯a is not function
執(zhí)行流程
1 導(dǎo)入a.js

require("a.js")
// 此時moduleCache
moduleCache = {moduleA : {}
}

2 執(zhí)行a.js為moduleA添加屬性,發(fā)現(xiàn)第一行導(dǎo)入b.js,模塊a還沒執(zhí)行完,執(zhí)行b.js

require("./b.js");
// 此時moduleCache
moduleCache = {moduleA : {},moduleB : {}
}

3 執(zhí)行b.js,發(fā)現(xiàn)導(dǎo)入a.js,此時moduleCache有moduleA,不會重復(fù)執(zhí)行模塊a的代碼,會直接用moduleCache中模塊a已經(jīng)導(dǎo)出的內(nèi)容。

const { a } = require("./a");
等價于
const {a} = moduleCache.moduleA

因為此時模塊a的內(nèi)容還未完全執(zhí)行完,所以解構(gòu)的變量a是undefined,還不是function,所以報錯。

webpack打包結(jié)果分析

// a.js
import "./b.js";
export const A = () => {};// b.js
import { A } from "./a.js";
A();// index.js
import "./a";

webpack打包結(jié)果

(() => {"use strict";var __webpack_modules__ = {"./src/a.js": (__unused_webpack_module,__webpack_exports__,__webpack_require__) => {__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__, {A: () => A,});var _b_js__WEBPACK_IMPORTED_MODULE_0__ =__webpack_require__("./src/b.js");var A = function A() {};},"./src/b.js": (__unused_webpack_module,__webpack_exports__,__webpack_require__) => {__webpack_require__.r(__webpack_exports__);var _a_js__WEBPACK_IMPORTED_MODULE_0__ =__webpack_require__("./src/a.js");(0, _a_js__WEBPACK_IMPORTED_MODULE_0__.A)();},};var __webpack_module_cache__ = {};function __webpack_require__(moduleId) {var cachedModule = __webpack_module_cache__[moduleId];if (cachedModule !== undefined) {return cachedModule.exports;}var module = (__webpack_module_cache__[moduleId] = {exports: {},});__webpack_modules__[moduleId](module, module.exports, __webpack_require__);return module.exports;}(() => {__webpack_require__.d = (exports, definition) => {for (var key in definition) {if (__webpack_require__.o(definition, key) &&!__webpack_require__.o(exports, key)) {Object.defineProperty(exports, key, {enumerable: true,get: definition[key],});}}};})();(() => {__webpack_require__.o = (obj, prop) =>Object.prototype.hasOwnProperty.call(obj, prop);})();(() => {__webpack_require__.r = (exports) => {if (typeof Symbol !== "undefined" && Symbol.toStringTag) {Object.defineProperty(exports, Symbol.toStringTag, {value: "Module",});}Object.defineProperty(exports, "__esModule", { value: true });};})();var __webpack_exports__ = {};__webpack_require__.r(__webpack_exports__);var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/a.js");
})();

每個模塊的代碼會被放到一個對象

var __webpack_modules__ = {[moduleId] : 模塊代碼
}
var __webpack_modules__ = {"./src/a.js": (__unused_webpack_module,__webpack_exports__,__webpack_require__) => {__webpack_require__.r(__webpack_exports__); // 標(biāo)記模塊為ES模塊__webpack_require__.d(__webpack_exports__, {A: () => A, // getter});var _b_js__WEBPACK_IMPORTED_MODULE_0__ =__webpack_require__("./src/b.js");var A = function A() {};},"./src/b.js": (__unused_webpack_module,__webpack_exports__,__webpack_require__) => {__webpack_require__.r(__webpack_exports__);var _a_js__WEBPACK_IMPORTED_MODULE_0__ =__webpack_require__("./src/a.js");(0, _a_js__WEBPACK_IMPORTED_MODULE_0__.A)();},};

webpack自定義require導(dǎo)入函數(shù)

function __webpack_require__(moduleId) {var cachedModule = __webpack_module_cache__[moduleId];if (cachedModule !== undefined) {return cachedModule.exports;}var module = (__webpack_module_cache__[moduleId] = {exports: {},});__webpack_modules__[moduleId](module, module.exports, __webpack_require__);return module.exports;
}

跟commonjs規(guī)范類似

  1. 查看緩存是否有模塊導(dǎo)出結(jié)果,如果模塊執(zhí)行過了,返回模塊導(dǎo)出結(jié)果
  2. 在執(zhí)行模塊代碼之前,先創(chuàng)建模塊導(dǎo)出對象module.exports
  3. 將模塊導(dǎo)出對象傳入執(zhí)行模塊代碼
__webpack_require__.d // 定義模塊導(dǎo)出屬性
__webpack_require__.o // 檢查模塊導(dǎo)出對象是否具有某個屬性
__webpack_require__.r // 標(biāo)記模塊為ES模塊

模塊代碼執(zhí)行前會先進行

  1. 將模塊導(dǎo)出對象標(biāo)記ES模塊
  2. 如果模塊有導(dǎo)出內(nèi)容,會將這些內(nèi)容定義到模塊導(dǎo)出對象

代碼執(zhí)行流程
模塊A執(zhí)行

__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {A: () => A, // 定義getter
});
var _b_js__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__("./src/b.js"); // 執(zhí)行到這里 會暫停a模塊代碼執(zhí)行,執(zhí)行b模塊var A = function A() {};

moduleA 定義了一個A屬性,A屬性是一個存取器屬性,有g(shù)etter,getter就是返回真正導(dǎo)出的A。
執(zhí)行b模塊時,()=>A,這里返回的A還是undefined。
執(zhí)行b模塊

__webpack_require__.r(__webpack_exports__);
var _a_js__WEBPACK_IMPORTED_MODULE_0__ =
__webpack_require__("./src/a.js");(0, _a_js__WEBPACK_IMPORTED_MODULE_0__.A)();

跟Commonjs的問題一樣,模塊A還沒有執(zhí)行完,A還沒有賦值,所以A這里是undefined,不能作為函數(shù)調(diào)用。
這里和commonjs還是有些區(qū)別
打包結(jié)果中模塊代碼執(zhí)行前會去先定義導(dǎo)出屬性,為屬性設(shè)置一個getter,因此在代碼模塊執(zhí)行前這些導(dǎo)出屬性就已經(jīng)在導(dǎo)出對象中有g(shù)etter。
這里因為配置babel,打包結(jié)果會把const轉(zhuǎn)成var,所以變量聲明提升了,如果是const就會變成變量在聲明前使用。

結(jié)論

項目會形成循環(huán)依賴實際開發(fā)中很難避免,有可能引入了某個模塊就會導(dǎo)致形成依賴鏈路。

形成循環(huán)依賴鏈路并不一定會報錯,但是在執(zhí)行到對應(yīng)模塊時,之前模塊因為導(dǎo)入其他包,模塊代碼還沒完全執(zhí)行完,內(nèi)容還沒完全導(dǎo)出,就有可能導(dǎo)致報錯。
其實導(dǎo)致報錯還好,因為可以提前在本地就感知到處理,但是如果你只是定義了一個變量,那么這個變量可能是在你還沒有賦值的時候,就引用了,所以其實模塊導(dǎo)出的變量并不是一定可信的。

其實在遇到函數(shù)調(diào)用報錯時可以通過把一些函數(shù)表達式改成函數(shù)聲明就好,因為打包結(jié)果模塊的執(zhí)行其實是執(zhí)行一個函數(shù),在執(zhí)行前會有函數(shù)聲明提升,但盡量不要用這種規(guī)范來處理,因為很可能會遇到更多坑。
其實有模塊循環(huán)依賴后還報錯,本身就是這條依賴鏈路有問題,應(yīng)該找到不合理的地方解決,而不是去規(guī)避。用函數(shù)聲明解決一些問題,反倒會留下一些坑,可能某些環(huán)境的值原本因為循環(huán)依賴導(dǎo)致引用時是undefined,但是碰巧你用函數(shù)聲明避免了一些報錯,導(dǎo)致埋了一個坑。

有一些工具可以分析項目中的循環(huán)鏈路,eslint也有相應(yīng)的配置。
至于如何找到循環(huán)依賴的不合理地方就憑經(jīng)驗吧,這里就不展開了,畢竟是個人觀點。

http://aloenet.com.cn/news/46564.html

相關(guān)文章:

  • 用手機制作ppt的軟件seo站長綜合查詢工具
  • 哪種語言做的網(wǎng)站好seo診斷站長
  • 福州綠光網(wǎng)站建設(shè)工作室seo sem是啥
  • led燈什么網(wǎng)站做推廣好百度小說排行榜2020
  • 網(wǎng)站空間 價格網(wǎng)站流量數(shù)據(jù)
  • 專業(yè)的網(wǎng)站建設(shè)商家免費網(wǎng)站建設(shè)平臺
  • 網(wǎng)站被劫持怎么辦百度官方版
  • j建設(shè)網(wǎng)站制作網(wǎng)站教學(xué)
  • 專門做服裝批發(fā)的網(wǎng)站有哪些自己怎么做網(wǎng)頁推廣
  • 企業(yè)網(wǎng)站怎么做連接seo搜索引擎優(yōu)化視頻
  • php做動漫網(wǎng)站google搜索優(yōu)化
  • 政府網(wǎng)站建設(shè)原則西安seo站內(nèi)優(yōu)化
  • 外國網(wǎng)站學(xué)習(xí)做任務(wù) 升級100大看免費行情的軟件
  • 蘭州易天網(wǎng)站建設(shè)公司有哪些cpm廣告聯(lián)盟平臺
  • 租服務(wù)器的網(wǎng)站seo兼職怎么收費
  • 淘寶里網(wǎng)站建設(shè)公司可以嗎地推十大推廣app平臺
  • 做網(wǎng)站怎么切圖網(wǎng)站seo收錄工具
  • 威客做的好的網(wǎng)站有哪些建網(wǎng)站哪個平臺好
  • 網(wǎng)站怎樣做平面設(shè)計圖百度貼吧入口
  • 做網(wǎng)站接私活百度推廣助手手機版
  • css做簡單網(wǎng)站seo是什么崗位
  • wordpress forum南通seo
  • 專業(yè)網(wǎng)站建設(shè)培訓(xùn)機構(gòu)seo是搜索引擎嗎
  • 網(wǎng)站用什么做關(guān)鍵詞安卓優(yōu)化大師舊版本下載
  • 合肥市住房和城鄉(xiāng)建設(shè)廳網(wǎng)站鄭州網(wǎng)站seo優(yōu)化公司
  • dz做網(wǎng)站網(wǎng)站宣傳的方法有哪些
  • 無錫網(wǎng)站制作的公司小紅書推廣怎么收費
  • 怎么開網(wǎng)站做網(wǎng)紅怎么提高百度搜索排名
  • 做視頻網(wǎng)站賺做視頻網(wǎng)站賺百度服務(wù)中心投訴
  • 大港油田建設(shè)官方網(wǎng)站谷歌google地圖