ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Bluebird 工具链实战指南:tools 目录下的测试、构建与代码规范工具

Bluebird 工具链实战指南:tools 目录下的测试、构建与代码规范工具 Bluebird 工具链实战指南tools 目录下的测试、构建与代码规范工具【免费下载链接】bluebird:bird: :zap: Bluebird is a full featured promise library with unmatched performance.项目地址: https://gitcode.com/gh_mirrors/bl/bluebird导读Bluebird 在 tools 目录下维护了一套可在命令行直接运行的开发工具涵盖测试执行test.js、库构建build.js与 JSHint 配置文件生成jshintrc_generator.js三大任务。本文将逐一剖析这三个工具的用法、命令行参数与底层源码实现帮助你在克隆仓库后快速上手测试、定制构建流程并理解 Bluebird 从src/多模块源码到发布产物的完整加工管线。tools 目录概览tools/目录是 Bluebird 项目自研的构建与测试工具集从 tools 的说明与目录结构看主要包含tools/test.js测试运行器驱动 Node 与浏览器环境下的全部 mocha 测试tools/build.js库构建器负责将src/下的模块源码编译为 release、debug、browser 等形态的产物tools/jshintrc_generator.js动态生成项目根目录的.jshintrc文件tools/job-runner/job-runner.js多进程任务调度器为构建与测试提供并行执行能力tools/ast_passes.js基于 AST 的源码变换断言移除/展开、内联展开、常量展开等tools/mocha_runner.js在子进程中运行 mocha 测试的封装tools/browser_test_generator.js 与 tools/browser_test_runner.js浏览器测试的编译与执行tools/saucelabs_runner.jsSauce Labs 云端浏览器测试通道tools/utils.js公共工具函数。三个可直接从命令行调用的入口工具构成了开发者日常最常用的三条命令下面逐一展开。一、test.js运行 Bluebird 的完整测试套件根据 tools/README.md 的说明test.js用于运行测试。Bluebird 的测试用例集中在 test/mocha 目录包含 2.1.22.3.4 等 Promises/A 规范测试、cancel、map、props、promisify、unhandled_rejections等数百个功能测试文件以及 test/browser 目录下的浏览器测试页面。基本用法在项目根目录直接运行node --expose-gc tools/test--expose-gc参数是为了让测试能够显式触发垃圾回收用于验证内存相关的行为。在支持 generator 的新版本 Node 中也可以直接运行node tools/test。仓库根目录 package.json 中同样把该命令注册为 npm scriptscripts: { test: node --expose-gc tools/test.js }因此你也可以使用npm test达到相同效果。指定测试范围--runtools/test.js通过optimist解析命令行参数tools/test.js。默认运行全部测试testName all通过--run可指定单个测试文件或 glob 模式node tools/test --runcancel.js node tools/test --runmap* node tools/test --run2.1.2其匹配逻辑tools/test.js为all或no开头匹配./test/mocha/*.js全部文件aplus仅匹配./test/mocha/[0-9].[0-9].[0-9].js即 Promises/A 规范测试包含*按 glob 相对test/mocha目录匹配其他名称自动将213之类的数字简写转换为2.1.3并拼接.js。--runno开头时如--runnodomain,usinggetTests会把这些名称作为排除项过滤掉tools/test.js。若没有任何文件匹配会抛出No test file matches错误。单个测试运行时options.singleTest会被置为truetools/test.js测试输出直接打印到终端便于定位失败点tools/mocha_runner.js 在测试失败时还会给出提示——用node tools/test --run文件名单独重跑该用例。覆盖率统计--cover--cover选项启用 istanbul 代码覆盖率统计tools/test.js可指定 reporternode tools/test --cover node tools/test --covertext-summary默认 reporter 为html覆盖率产物输出到coverage/目录。其工作流程是先用build产出 debug 构建再用istanbul instrument对js/debug目录插桩到js/instrumented排除assert.js、captured_trace.js随后在插桩代码之上运行全部测试tools/test.js。每个测试分组group的覆盖率数据会被写入coverage/coverage-groupN.json最后通过istanbul report汇总出平均覆盖率百分比tools/test.js并依据阈值映射出徽章颜色95% 以上为 brightgreen、85% 为 green、80% 为 yellowgreen、70% 为 yellow、60% 为 red见 tools/test.js。浏览器测试--browser / --saucelabs测试不仅可以在 Node 中运行也可以编译后在真实浏览器中执行node tools/test --runcancel.js --browser带--browser时tools/test.js 会调用 tools/browser_test_generator.js 将测试编译进 test/browser 页面并自动在本地启动静态服务器默认端口 9999可用--port修改随后用默认浏览器打开页面执行测试。文档特别提醒浏览器标签页必须保持激活状态因为部分测试对计时敏感Chrome 等浏览器在后台标签页会节流定时器导致测试误报失败。--saucelabs则改为通过 tools/saucelabs_runner.js 建立隧道把编译好的测试推送到 Sauce Labs 云端虚拟机执行从而覆盖 IE8 等本地无法运行的旧浏览器。其他参数一览从 tools/test.js 的参数解析可以确认以下全部选项布尔型标志取出现即 true语义传反值用no-前缀如--no-browser参数默认值说明--runStringall运行的测试范围可为文件名或相对test/mocha的 glob--cover[reporter]无 /html用 istanbul 统计覆盖率输出到coverage/--browserfalse编译测试供浏览器执行--portNumber9999浏览器测试时本地服务器端口--execute-browser-tests随--browser为true是否实际执行编译后的浏览器测试--open-browsertrue是否自动打开默认浏览器--fake-timerstrue在 Node 中运行时是否使用模拟定时器--js-hinttrue是否在测试前对src/运行 JSHint--saucelabsfalse使用 Sauce Labs 云端浏览器执行测试--nw/--nw-path—使用 NW.jsnode-webkit环境执行浏览器测试其中--fake-timers的实现值得一提tools/mocha_runner.js 会替换全局的setTimeout/setInterval/clearTimeout/clearInterval用currentTime累加 10ms 的虚拟时钟驱动回调避免测试受真实时间影响而变慢或抖动。源码级实现分组并行与进程隔离tools/test.js的调度设计有两个值得注意的点多进程并行combineTests把测试文件按jobRunner.CHILD_PROCESSES数量轮询分组tools/test.js每组在独立子进程中通过 tools/mocha_runner.js 执行并在终端以表格形式实时汇报每个用例的成败utils.tableLogger。进程隔离清单needsFreshProcess检测到regress、using、domain、multiple-copies、unhandled_rejections、nodeify、getNewLibraryCopy、long_stack_traces等测试名时会为它们单独分配一个进程tools/test.js因为这些用例依赖全局状态如全局 Promise 替换、domain 环境、未处理拒绝行为必须隔离执行才能保证正确性。此外mocha_runner在每个子进程中都会加载js/debug/bluebird.js覆盖率模式则加载js/instrumented/bluebird.js并注入全局Promise同时启用cancellation、longStackTraces等配置tools/mocha_runner.js保证测试运行在与文档一致的配置形态上。二、build.js构建 release / debug / browser 产物tools/README.md 说明build.js用于构建库支持自定义构建。Bluebird 的构建体系非常独特src/下是 30 多个手写的 ES5 风格模块构建器通过 tools/ast_passes.js 对源码做编译期变换删除断言、内联展开、常量替换、__DEBUG__/__BROWSER__开关替换等再拼装成单一文件产物。基本用法最完整的构建命令见 docs/docs/contribute.md 的 Building 章节node tools/build --debug --release --browser --minifybuild.js被直接执行时会校验当前工作目录必须是 bluebird 项目根目录目录名须以bluebird开头见 tools/build.js避免误删。构建产物目录定义在 tools/build.js产物目录说明release 构建js/release/去除全部断言、__DEBUG__false的生产版本即package.json中main指向的文件debug 构建js/debug/__DEBUG__true保留断言的调试版本提供更友好的错误提示browser 构建js/browser/bluebird.js/bluebird.min.js经 browserify 打包为浏览器可用、__BROWSER__true的版本standalone: Promise全局暴露命令行参数布尔标志同样遵循出现即 true、no-前缀取反的约定参考 docs/docs/contribute.md--release构建 release 版本输出到js/release默认false--debug构建 debug 版本输出到js/debug默认false--browser编译浏览器版本输出js/browser/bluebird.js默认false--minify是否压缩浏览器版本为bluebird.min.js默认true仅--browser时有效--features...自定义构建只包含指定的可选特性模块此时会自动启用--browsertools/build.js--no-clean构建前不清空目标目录。仓库 package.json 的scripts中就有两条基于这些参数的官方构建命令generate-browser-full: node tools/build.js --no-clean --no-debug --release --browser --minify, generate-browser-core: node tools/build.js --featurescore --no-debug --release --zalgo --browser --minify其中--zalgo参数虽然出现在该命令中但由 docs/docs/contribute.md 可知它对应 zalgo 构建输出至js/zalgo目录。特性裁剪--features 的底层原理--featurescore之所以能产出只含核心功能的精简版关键在于 tools/build.js 定义的optionalModuleRequireMap——它标明了哪些src/模块是可选特性以及它们之间的依赖关系var optionalModuleRequireMap { race.js: true, call_get.js: true, generators.js: true, map.js: true, nodeify.js: true, promisify.js: true, props.js: true, reduce.js: true, settle.js: true, some.js: true, using.js: true, timers.js: true, filter.js: [map.js], any.js: [some.js], each.js: [reduce.js] };getSourcePaths(features)tools/build.js在给定--features时只保留名称匹配的可选模块其余可选模块如map.js、props.js、promisify.js会被剔除若未指定--features则全部包含。依赖关系如filter依赖map、any依赖some、each依赖reduce会被记录并在拼装时通过require(./xxx.js)(deps)注入tools/build.js构建出的浏览器文件头部还会以注释形式写明启用了哪些特性、禁用了哪些特性getBrowserBuildHeadertools/build.js。filter.js、any.js、each.js这类模块的依赖正是由该映射表维护的这也解释了为何裁剪特性时不会破坏模块间引用。三条构建管线从build(options)的入口tools/build.js可以看到构建的总体流程读取全部src/*.js源码 → 去除注释、替换__VERSION__→ 并行对每个文件执行 AST 变换 → 计算可选模块的依赖注入代码 → 按开关分别执行buildReleaseremoveAsserts删除断言→inlineExpansion→expandConstants并把__DEBUG__替换为falsetools/build.jsbuildDebugexpandAsserts把断言展开为运行时检查→inlineExpansion→expandConstants__DEBUG__替换为truetools/build.jsbuildBrowser先按 release 口径做源码变换、__BROWSER__替换为true再用 browserify 打包并排除async_hooks、timers等 Node 内建模块最后用 UglifyJS 生成.min.jstools/build.js。所有并行任务都通过jobRunner.run派发到多进程执行构建速度因此能随 CPU 核数扩展。另外构建器在promise.js末尾注入了一段隐藏类填充代码lastLineCodetools/build.js通过创建多种形态的 Promise 实例帮助 V8 稳定对象形状hidden class这正是 Bluebird 追求极致性能的实现细节之一。三、jshintrc_generator.js动态生成 .jshintrctools/README.md 给出的第三个工具是jshintrc_generator.js用于在项目根目录生成.jshintrc文件node tools/jshintrc_generator为什么需要动态生成Bluebird 的源码大量使用编译期常量如__DEBUG__、__BROWSER__、INLINE_SLICE等以及CONSTANT(...)宏定义的内部常量这些标识符对 JSHint 而言是未定义变量如果直接静态编写.jshintrc每当 src/constants.js 增减常量时配置都会失同步。生成器正是为解决这一问题而存在tools/jshintrc_generator.js 注释明确写道Since many globals are dynamic, this file is needed to generate jshintrc dynamically。实现原理tools/jshintrc_generator.js 的流程是读取src/constants.js用正则CONSTANT\(\s*([^,])提取全部常量名把这些常量名连同Symbol、Map、JSON、Promise、process、setImmediate、__DEBUG__、__BROWSER__等源码中使用的环境全局一起写入globals映射布尔值表示该全局是否允许被赋值读取项目根目录已有的.jshintrc合并globals字段后格式化写回。运行一次后JSHint 便能在globals层面识别所有内部常量tools/jshint.js 即可对src/目录执行 lintnode tools/jshint该 lint 步骤也默认集成在tools/test.js的流程中options.jsHint默认true可用--no-js-hint关闭由 tools/test.js 与测试并行执行最终结果统一汇报。四、辅助工具与联动关系除了上述三个命令行入口tools/目录中的辅助模块共同支撑起整套开发流程tools/job-runner/job-runner.js基于子进程池的任务调度器build.js与test.js的并行能力都源于它tools/ast_passes.js提供readConstants、removeAsserts、expandAsserts、inlineExpansion、expandConstants、removeComments等编译期变换是构建管线的核心tools/mocha_runner.js每个子进程内的 mocha 执行器含虚拟定时器与失败汇总tools/browser_test_generator.js / tools/browser_test_runner.js把 mocha 用例编译进浏览器页面并驱动执行tools/saucelabs_runner.jsSauce Labs 云端浏览器测试通道tools/utils.jsrun执行外部命令、tableLogger终端表格、getLicense、parseDeps、checkAscii等公共能力。从整体联动看一次完整的node tools/test会依次触发JSHint 静态检查默认开启→build({debug: true})生成 debug 构建 → 按需插桩覆盖率 → 多进程并行执行 mocha 用例 → 输出表格汇报与覆盖率总结。而一条npm run generate-browser-core则会走完特性裁剪 → AST 变换 → browserify 打包 → UglifyJS 压缩的完整链路产出js/browser/bluebird.core.js与bluebird.core.min.js。结语tools/README.md 虽然只有短短三行命令说明但其背后是 Bluebird 一整套工程化支撑test.js负责在多进程、多环境Node、浏览器、Sauce Labs下验证数百个规范与功能用例build.js通过 AST 变换与特性裁剪从同一套src/源码产出 release、debug、browser、core 等不同形态的产物jshintrc_generator.js则保证静态检查配置与源码常量始终保持同步。理解了这三个入口命令及其源码实现你就能在本地复现 Bluebird 的完整测试与构建流程也能为阅读或扩展其源码建立一条清晰的工具链脉络。【免费下载链接】bluebird:bird: :zap: Bluebird is a full featured promise library with unmatched performance.项目地址: https://gitcode.com/gh_mirrors/bl/bluebird创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表