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

資訊專欄INFORMATION COLUMN

嘗試造了個工具類庫,名為 Diana

zhichangterry / 370人閱讀

摘要:的另一種形式測試踩坑之路代碼覆蓋率單元測試的代碼覆蓋率統(tǒng)計,是衡量測試用例好壞的一個的方法。

項目地址: diana

文檔地址: http://muyunyun.cn/diana/

造輪子的意義

為啥已經(jīng)有如此多的前端工具類庫還要自己造輪子呢?個人認為有以下幾個觀點吧:

定制性強,能根據(jù)自己的需求為主導延伸開發(fā)。萬一一不小心還能幫到別人(比如 React 庫);

紙上得來終覺淺,很多流行的庫,只是照著它們的 API 進行使用,其實這些庫里蘊含著大量的知識、技巧,最好的辦法就是仿照它們來寫些小 demo,從而體會這些庫的精髓;

造輪子的過程中能讓自己體會到與平常業(yè)務開發(fā)不一樣的樂趣;比如和日常業(yè)務開發(fā)中很大的一個區(qū)別是會對測試用例具有比較嚴格的要求;而且寫文檔能力提升了。

就先瞎編到這里了。。。

拋開內(nèi)部方法(寫相應的專題效果可能會更好,所以這里先略過),下面分享一些開發(fā) diana 庫 時的一些心得:

項目目錄結(jié)構(gòu)
├── LICENSE                  開源協(xié)議
├── README-zh_en.md          英文說明文檔
├── README.md                中文說明文檔
├── coverage                 代碼覆蓋率文件
├── docs                     文檔目錄
│?? └── static-parts
│??     ├── index-end.html   靜態(tài)文檔目錄結(jié)尾文件
│??     └── index-start.html 靜態(tài)文檔目錄開頭文件
├── karma.conf.js            karma 配置文件
├── lib
│?? ├── diana.back.js        服務端引用入口
│?? └── diana.js             瀏覽器引用入口
├── package.json
├── script
│?? ├── build.js             構(gòu)建文件
│?? ├── check.js             結(jié)合 pre-commit 進行 eslint 校驗
│?? ├── tag-script.js        自動生成文檔的標簽
│?? ├── web-script.js        自動生成文檔
│?? ├── webpack.browser.js   瀏覽器端 webpack 配置文件
│?? └── webpack.node.js      服務器端 webpack 配置文件
├── snippets
├── src
│?? ├── browser              瀏覽器端方法
│?? ├── common               共用方法
│?? ├── node                 node 端方法
│?? └── util.js              庫內(nèi)通用方法
├── tag_database             文檔標簽
└── test                     測試文件
    ├── browserTest
    ├── commonTest
    ├── index.js
    └── nodeTest

目錄結(jié)構(gòu)也隨著方法的增多在不停迭代當中,建議直接到庫中查看最新的目錄結(jié)構(gòu)。

相應地,具體的方法會隨著時間迭代,所以首先推薦查看文檔,點擊如下圖的 ? 就能查看源碼。

讓模塊同時在 Node.js 與瀏覽器中運行

我們可以通過如下方法來判斷模塊當前是運行在 Node.js 還是瀏覽器中,然后使用不同的方式實現(xiàn)我們的功能。

// Only Node.JS has a process variable that is of [[Class]] process
const isNode = Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]"

但如果用戶使用了模塊打包工具,這樣做會導致 Node.js 與瀏覽器的實現(xiàn)方式都會被包含在最終的輸出文件中。針對這個問題,開源社區(qū)提出了在 package.json 中添加 browser 字段的提議,目前 webpack 和 rollup 都已經(jīng)支持這個字段了。

給 browser 字段提供一個文件路徑作為在瀏覽器端使用時的模塊入口,但需要注意的是,打包工具會優(yōu)先使用 browser 字段指定的文件路徑作為模塊入口,所以你的 main 字段 和 module 字段會被忽略,但是這會導致打包工具不會優(yōu)化你的代碼。詳細信息請參考這個問題。

在 diana 庫 為了在不同環(huán)境中使用適當?shù)奈募?,?package.json 中進行了如下聲明:

  "browser": "lib/diana.js",
  "main": "lib/diana.back.js", // 或者 "module": "lib/diana.back.js",

這樣一來,在 node 環(huán)境中,引用的是 lib/diana.back.js 文件,在瀏覽器環(huán)境中,引用的是 lib/diana.js 文件。然后就能愉快地在瀏覽器端和 node 端愉快地使用自己特有的 api 了。

常見模塊規(guī)范比較

另外為了使 diana 庫 的打包文件兼容 node 端、以及瀏覽器端的引用,選擇了 UMD 規(guī)范進行打包,那么為什么要選擇 UMD 規(guī)范呢?讓我們看下以下幾種規(guī)范之間的異同:

CommonJS

CommonJs 是服務器端模塊的規(guī)范,Node.js 采用了這個規(guī)范。這些規(guī)范涵蓋了模塊、二進制、Buffer、字符集編碼、I/O流、進程環(huán)境、文件系統(tǒng)、套接字、單元測試、服務器網(wǎng)關(guān)接口、包管理等。

根據(jù) CommonJS 規(guī)范,一個多帶帶的文件就是一個模塊。加載模塊使用 require 方法,該方法讀取一個文件并執(zhí)行,最后返回文件內(nèi)部的 exports 對象。

CommonJS 加載模塊是同步的。像 Node.js 主要用于服務器的編程,加載的模塊文件一般都已經(jīng)存在本地硬盤,所以加載起來比較快,不用考慮異步加載的方式,所以 CommonJS 規(guī)范比較適用。但如果是瀏覽器環(huán)境,要從服務器加載模塊,這是就必須采用異步模式。所以就有了 AMD、CMD 解決方案。

AMD、CMD

AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)物。AMD 推崇提前執(zhí)行。

 // AMD 默認推薦的是
define(["./a", "./b"], function(a, b) {
  a.doSomething()
  b.doSomething()
  ...
})

CMD 是 SeaJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)物。CMD 推崇依賴就近。

// CMD
define(function(require, exports, module) {
  var a = require("./a")
  a.doSomething()
  var b = require("./b")
  b.doSomething()
  ...
})
UMD

UMD 是 AMD 和 CommonJS 的結(jié)合。因為 AMD 是以瀏覽器為出發(fā)點的異步加載模塊,CommonJS 是以服務器為出發(fā)點的同步加載模塊,所以人們想出了另一個更通用的模式 UMD,來解決跨平臺的問題。

diana 庫 選擇了以 umd 方式進行輸出,來看下 UMD 做了啥:

(function (root, factory) {
  if (typeof exports === "object" && typeof module === "object") { // UMD 先判斷是否支持 Node.js 的模塊(exports)是否存在,存在則使用 CommonJS 模式
    module.exports = factory()
  } else if (typeof define === "function" && define.amd) { // 接著判斷是否支持 AMD(define是否存在),存在則使用 AMD 方式加載模塊。
    define([], factory)
  } else if (typeof exports === "object") { // CommonJS 的另一種形式
    exports["diana"] = factory()
  } else
    root["diana"] = factory() // Window
})(this, function() {
  return module
})
測試踩坑之路 代碼覆蓋率

單元測試的代碼覆蓋率統(tǒng)計,是衡量測試用例好壞的一個的方法。但凡是線上用的庫,基本上都少不了高質(zhì)量的代碼覆蓋率的檢測。如下圖為 diana 庫的測試覆蓋率展示。

可以看到覆蓋率分為以下 4 種類型,

行覆蓋率(line coverage):是否每一行都執(zhí)行了?

函數(shù)覆蓋率(function coverage):是否每個函數(shù)都調(diào)用了?

分支覆蓋率(branch coverage):是否每個if代碼塊都執(zhí)行了?

語句覆蓋率(statement coverage):是否每個語句都執(zhí)行了?

番外:github 上顯示的覆蓋率是根據(jù)行覆蓋率來展示的。

mocha + istanbul

最初的版本, 僅僅用到 mocha 進行測試 *.test.js 文件,然后在 codecov 得到測試覆蓋率。

引人 karma

如果僅僅測試 es5、es6 的語法,其實用 mocha 就已經(jīng)夠用了,但是涉及到測試 Dom 操作的語法等就必須建立一個瀏覽器,在上面進行測試。karma 的作用其實就是自動幫我們建立一個測試用的瀏覽器環(huán)境。

為了讓瀏覽器支持 Common.js 規(guī)范,中間用了 karma + browserify,盡管測試用例都跑通了,但是最后的代碼覆蓋率的文件里只有各個方法的引用路徑。最后只能又回到 karma + webpack 來,這里又踩到一個坑,打包編譯JS代碼覆蓋率問題,踩了一些坑后,終于實現(xiàn)了可以查看編譯前代碼的覆蓋率。圖如下:

通過這幅圖我們能清晰地看到源代碼中測試用例跑過各行代碼的次數(shù)(左側(cè)的數(shù)字),以及測試用例沒有覆蓋到的代碼(圖中紅色所示)。然后我們就能改善相應的測試用例從而提高測試覆蓋率。

配置文件,核心部分如下:

module.exports = function(config) {
  config.set({
    files: ["test/index.js"], // 需載入瀏覽器的文件
    preprocessors: { // 預處理
      "test/index.js": ["webpack", "coverage"]
    },
    webpack: {
      module: {
        rules: [{
          test: /.js$/,
          use: { loader: "sourcemap-istanbul-instrumenter-loader" }, // 這里用 istanbul-instrumenter-loader 插件的 0.0.2 版本,其它版本有坑~
          exclude: [/node_modules/, /.spec.js$/],
        }],
      }
    },
    coverageReporter: {
      type: "lcov", // 貌似只能支持這種類型的讀取
      dir: "coverage/"
    },
    remapIstanbulReporter: { // 生成 coverage 文件
      reports: {
        "text-summary": null,
        json: "coverage/coverage.json",
        lcovonly: "coverage/lcov.info",
        html: "coverage/html/",
      }
    },
    reporters: ["progress", "karma-remap-istanbul"], // remap-isbanbul 也報了一個未找到 sourcemap 的 error,直接注釋了 remap-istanbul 包的 CoverageTransformer.js 文件的 169 行,以后有機會再搗鼓吧。(心累)
    ...
  })
}
總結(jié)

本文圍繞 diana 庫 對造輪子的意義,模塊兼容性,測試用例進行了思考總結(jié)。后續(xù)會對該庫流程自動化以及性能上做些分享。
該庫參考學習了很多優(yōu)秀的庫,感謝 underscore、outils、ec-do、30-seconds-of-code 等庫對我的幫助。

最后歡迎各位大佬在 issues 盡情吐槽。

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

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

相關(guān)文章

  • 結(jié)合自己造的輪子實踐按需加載

    摘要:原文地址為了探究按需加載的本質(zhì),選擇了對先前造的輪子進行實驗。下文就來揭開面紗,并動手改造項目,最終目標是用第二種寫法實現(xiàn)按需加載,減小打包體積。下面給出種可以按需加載的方案。 原文地址 為了探究按需加載的本質(zhì),選擇了對先前造的輪子 diana 進行實驗。 實驗一:全量引用 import * as _ from diana 打包體積結(jié)果如下: showImg(http://oqhtsc...

    Alfred 評論0 收藏0
  • 用JS 重新了個輪子,農(nóng)歷計算腳本,有詳細的注釋

    摘要:在重新造輪子之前,準備對性能優(yōu)化下。最重要的,只寫農(nóng)歷計算相關(guān)的計算,其他無功能,如果需要,通過本腳本。為除了閏月外的正常月份是大月還是小月,為天,為天。表示閏月是大月還是小月,僅當存在閏月的情況下有意義。 工作中有時需要農(nóng)歷計算,之前從網(wǎng)上找了個JS版本的(摘自wannianli.htm,網(wǎng)上導出都是),直接調(diào)用就可以了,非常方便。有優(yōu)點就有缺點,該版本文件有點大(20KB以上);有...

    zhigoo 評論0 收藏0
  • 不可錯過的Angular scrollbar library

    摘要:最近,工作中忙于開發(fā)一個,主要技術(shù)基于和。我希望這個滾動條長得好看,可自定義,輕量級,不要依賴于,能和一起用,且支持黑色主題,因為我們的是深色背景的。希望能幫到有需要的人。 最近,工作中忙于開發(fā)一個desktop apps,主要技術(shù)基于 electron 和 angular.js 。開發(fā)過程中,發(fā)現(xiàn)在 Windows 中滾動條巨丑無敵,作為一個設計出身的程序猿,我當然不能忍,于是我用下...

    Jioby 評論0 收藏0
  • 不可錯過的Angular scrollbar library

    摘要:最近,工作中忙于開發(fā)一個,主要技術(shù)基于和。我希望這個滾動條長得好看,可自定義,輕量級,不要依賴于,能和一起用,且支持黑色主題,因為我們的是深色背景的。希望能幫到有需要的人。 最近,工作中忙于開發(fā)一個desktop apps,主要技術(shù)基于 electron 和 angular.js 。開發(fā)過程中,發(fā)現(xiàn)在 Windows 中滾動條巨丑無敵,作為一個設計出身的程序猿,我當然不能忍,于是我用下...

    nemo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<