成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用 dpdm 定位 JavaScript/TypeScript 中的循環(huán)依賴

BLUE / 3069人閱讀

摘要:在寫大型項(xiàng)目的時(shí)候一不小心就會(huì)踩到直接循環(huán)依賴的坑里面所謂直接循環(huán)依賴是指在模塊工廠函數(shù)中對(duì)其它依賴于自己的模塊的成員有直接調(diào)用的情況比如假設(shè)有兩個(gè)模塊和其中的內(nèi)容如下的內(nèi)容如下下面這一行導(dǎo)致了直接循環(huán)依賴這時(shí)執(zhí)行會(huì)報(bào)的錯(cuò)誤這是因?yàn)槟K的工

在寫大型項(xiàng)目的時(shí)候, 一不小心就會(huì)踩到直接循環(huán)依賴的坑里面, 所謂直接循環(huán)依賴, 是指在模塊工廠函數(shù)中, 對(duì)其它依賴于自己的模塊的成員有直接調(diào)用的情況. 比如:

假設(shè)有兩個(gè)模塊 a.jsb.js, 其中 a.js 的內(nèi)容如下:

const b = require("./b")

exports.hello_a = function hello_a() {
  return "a"
}

exports.hello_from_b = function hello_from_b() {
  return b.hello_b()
}

b.js 的內(nèi)容如下:

const a = require("./a")

// 下面這一行導(dǎo)致了直接循環(huán)依賴
exports.hello_from_a = a.hello_a()

exports.hello_b = function hello_b() {
  return "b"
}

這時(shí), 執(zhí)行 a.js, 會(huì)報(bào) TypeError: a.hello_a is not a function 的錯(cuò)誤, 這是因?yàn)槟K a.js 的工廠函數(shù)還在執(zhí)行, 并且 hello_a 函數(shù)的聲明尚未被執(zhí)行, 而 b.js 就直接調(diào)用了 a.hello_a, 所以這個(gè)變量當(dāng)成不存在, 也就報(bào)錯(cuò)了, 如果這不是一個(gè)函數(shù)而是一個(gè)變量, 則不會(huì)報(bào)錯(cuò), 只是獲取到的值為 undefined, 這種情況會(huì)更難定位問題.

雖然現(xiàn)在有一個(gè)項(xiàng)目叫 madge 可以用來定位循環(huán)依賴, 但是這個(gè)倉庫在處理 TypeScript 的時(shí)候的輸出簡(jiǎn)直就是個(gè)玄學(xué)問題, 會(huì)常常莫名其妙的忽略掉了不應(yīng)該被忽略掉的文件, 這個(gè)問題后面我會(huì)舉例說明.

所以我花了一天的時(shí)間來造了一個(gè)輪子: dpdm, 專門用來檢測(cè) JavaScriptTypeScript 項(xiàng)目中的循環(huán)依賴, 其目前可以檢測(cè)下面這四種情況:

CommonJSrequire(...) 函數(shù)調(diào)用

ESM 的靜態(tài) import ... from ... 語句

ESM 的動(dòng)態(tài) import(...) 函數(shù)調(diào)用

ESM 的靜態(tài) export ... from ... 語句

能滿足大多數(shù)情況的需要, 因?yàn)楝F(xiàn)在極少有人有用 AMDSystem 了.

使用方式

安裝: dpdm 可以在命令行或者 js 項(xiàng)目中使用, 如果想在命令行使用(推薦), 則建議全局安裝, 否則安裝到你的項(xiàng)目中即可

# 全局安裝
npm i -g dpdm # 或者用 yarn: yarn global add dpdm

# 項(xiàng)目目錄中安裝
npm i dpdm # 或者用 yarn: yarn add dpdm

在命令行中使用: 直接使用命令 dpdm [可選參數(shù)] <入口文件> 即可, 輸出示例:

默認(rèn)情況下會(huì)輸出依賴樹(tree), 循環(huán)依賴列表(circular), 以及警示信息(warning), 你可以使用參數(shù)關(guān)閉掉其中任意項(xiàng), 比如 dpdm --tree false --warning false ./src/index.ts 來關(guān)閉依賴樹和警示信息(僅展示循環(huán)依賴表).

可以使用 --output 來輸出結(jié)果到 json 文件中

默認(rèn)情況下忽略了 node_modules 中的內(nèi)容, 可以使用 --exclude "" 來取消忽略

使用 --help 查看完整的幫助文檔:

dpdm --help
dpdm [] entry...

Options:
  --version            Show version number                                                                     [boolean]
  --context            the context directory to shorten path, default is process.cwd()                          [string]
  --extensions, --ext  comma separated extensions to resolve          [string] [default: ".ts,.tsx,.mjs,.js,.jsx,.json"]
  --include            included filenames regexp in string                            [string] [default: ".m?[tj]sx?$"]
  --exclude            excluded filenames regexp in string                          [string] [default: "/node_modules/"]
  --output, -o         output json to file                                                                      [string]
  --tree               print tree to stdout                                                    [boolean] [default: true]
  --circular           print circular to stdout                                                [boolean] [default: true]
  --warning            print warning to stdout                                                 [boolean] [default: true]
  -h, --help           Show help                                                                               [boolean]

在代碼中使用: dpdm 提供了若干 API, 具體可以查看包中提供的 .d.ts 提供的定義, 或者到 GitHub 查看文檔:

比如:

import {
  parseCircular,
  parseDependencyTree,
  parseWarnings,
  prettyCircular,
  prettyTree,
  prettyWarning,
} from "dpdm";

parseDependencyTree(["./src/**/*"] /* 入口, glob 匹配, 可以是數(shù)組 */, {
  /* 參數(shù)列表, 下面這些是默認(rèn)參數(shù) */
  context: process.cwd(), // 前綴, 用來簡(jiǎn)寫文件名
  extensions: ["", ".ts", ".tsx", ".mjs", ".js", ".jsx", ".json"], // 后綴
  include: /.m?[tj]sx?$/, // 需要解析的文件
  exclude: //node_modules//, // 需要忽略的文件
}).then((tree) => {
  console.log("Tree:");
  console.log(prettyTree(tree, Object.keys(tree)));
  console.log("");
  console.log("Circular:");
  console.log(prettyCircular(parseCircular(tree)));
  console.log("");
  console.log("Warning:");
  console.log(prettyWarning(parseWarnings(tree)));
});

提問題

項(xiàng)目在 GitHub 已開源, 地址是 https://github.com/acrazing/dpdm, 你可以到上面提 issue 或者提交 pr.

順便, 求贊~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105791.html

相關(guān)文章

  • ESLint 在中大型團(tuán)隊(duì)的應(yīng)用實(shí)踐

    摘要:自動(dòng)化接入和升級(jí)方案通過命令行工具提供一鍵接入升級(jí)能力,同時(shí)集成到團(tuán)隊(duì)腳手架中,大大降低了工程接入和維護(hù)的成本。原始代碼經(jīng)過解析器的解析,在管道中逐一經(jīng)過所有規(guī)則的檢查,最終檢測(cè)出所有不符合規(guī)范的代碼,并輸出為報(bào)告。 引言 代碼規(guī)范是軟件開發(fā)領(lǐng)域經(jīng)久不衰的話題,幾乎所有工程師在開發(fā)過程中都會(huì)遇到,并或多或少會(huì)思考過這一問題。隨著前端應(yīng)用的大型化和復(fù)雜化,越來越多的前端工程師和團(tuán)隊(duì)開始重...

    alogy 評(píng)論0 收藏0
  • jsweet中英文文檔,java代碼轉(zhuǎn)js代碼

    摘要:例如允許的對(duì)象默認(rèn)情況下,通過使用內(nèi)置宏將核心對(duì)象和方法映射到。例如這被轉(zhuǎn)換為以下代碼類可以定義構(gòu)造函數(shù),具有超類,并且可以像在中一樣實(shí)例化。因此,它不違反原則。用于聲明該對(duì)象可以用作構(gòu)造函數(shù)。 這個(gè)工具可以將java代碼轉(zhuǎn)為js代碼,從而可以使用java編寫前端代碼 如果排版看著費(fèi)勁可以下載下方html,打開html后使用google翻譯 JSweet語言規(guī)范版本:2.x(快照) 作...

    Near_Li 評(píng)論0 收藏0
  • jsweet中英文文檔,java代碼轉(zhuǎn)js代碼

    摘要:例如允許的對(duì)象默認(rèn)情況下,通過使用內(nèi)置宏將核心對(duì)象和方法映射到。例如這被轉(zhuǎn)換為以下代碼類可以定義構(gòu)造函數(shù),具有超類,并且可以像在中一樣實(shí)例化。因此,它不違反原則。用于聲明該對(duì)象可以用作構(gòu)造函數(shù)。 這個(gè)工具可以將java代碼轉(zhuǎn)為js代碼,從而可以使用java編寫前端代碼 如果排版看著費(fèi)勁可以下載下方html,打開html后使用google翻譯 JSweet語言規(guī)范版本:2.x(快照) 作...

    Mr_houzi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<