news 2026/9/18 15:01:46

Prettier 构建脚本完全指南:从 yarn build 到 npm 发布的产物流水线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Prettier 构建脚本完全指南:从 yarn build 到 npm 发布的产物流水线

Prettier 构建脚本完全指南:从 yarn build 到 npm 发布的产物流水线

【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettier

Prettier 的发布包并非直接拷贝源码,而是通过scripts/build下的一套构建脚本,用 esbuild 将src目录下的源码与各语言解析器打包成面向 Node.js、浏览器与 Playground 的多格式产物。本文以仓库中的 scripts/build/README.md 为骨架,结合构建器、esbuild 插件与包配置源码,完整讲解构建命令、全部 CLI 标志、包与模块的划分、产物类型,以及体积分析、调试等进阶用法,读完即可独立执行并验证一次完整的 Prettier 构建。

前置要求与入口

根据 scripts/build/README.md,构建脚本要求Node.js 版本>= 16.16。需要注意的是,仓库根目录 package.json 中engines.node>=22,这是运行整个开发仓库的要求;而构建产物会通过PRODUCTION_MINIMAL_NODE_JS_VERSION(定义于 scripts/utilities/index.js,值为"14")重新写入发布包,保证打包后的dist产物可以在更低的 Node.js 版本上运行。

构建入口定义在根目录 package.json:

"build": "node ./scripts/build/build.js"

入口脚本 scripts/build/build.js 的顶层流程如下:

  1. 调用 scripts/build/parse-arguments.js 解析命令行标志;
  2. --package过滤出要构建的包(默认构建全部 4 个包);
  3. 若指定--clean,先删除dist目录;
  4. 依次遍历每个包的模块与文件,调用对应 builder 执行打包,并在终端输出DONE / FAIL / SKIPPED状态与耗时。

构建的核心是 esbuild:统一的构建器在 scripts/build/builders/javascript-module.js 中实现,它组装了replace-moduleevaluateprimitive-defineumdvisualizer等自定义 esbuild 插件(见 scripts/build/esbuild-plugins/ 目录)。

基础用法与--package标志

构建全部包

yarn build

不传任何标志时,会构建 scripts/build/packages/index.js 中注册的全部 4 个包:

包名配置源文件说明
prettierscripts/build/packages/prettier.js主包,含核心 API、CLI、文档模块与全部内置语言插件
@prettier/plugin-hermesscripts/build/packages/plugin-hermes.jsHermes 解析器插件
@prettier/plugin-oxcscripts/build/packages/plugin-oxc.jsOxc 解析器插件(WASM 版面向浏览器)
@prettier/plugin-yukuscripts/build/packages/plugin-yuku.jsYuku 解析器插件

只构建指定包

yarn build --package prettier yarn build --package prettier --package @prettier/plugin-oxc

--package可以重复出现,且多个取值必须唯一。在 scripts/build/parse-arguments.js 中,重复的包名会直接抛出'--package' should be unique.;而在 scripts/build/build.js,未知的包名会抛出Unknown package "..."。未指定时默认构建全部 4 个包。

--clean:清理输出目录

yarn build --clean

构建前删除dist目录(路径由 scripts/utilities/index.js 中的DIST_DIR定义为仓库根目录下的dist)。实现位于 scripts/build/build.js:若dist存在且是目录则递归删除,若存在但不是目录则报错。源码注释提示目前只清理了顶层dist目录,尚未细化到各包自己的子目录,因此多包开发时建议始终带上--clean,避免旧产物残留。

--playground:仅构建网站所需产物

yarn build --playground

该标志让构建只产出 website/ 在线 Playground 需要的文件,其余文件会打印SKIPPED状态跳过。实现上,每个文件在 scripts/build/packages/prettier.js 中被标记playground: true,例如standalone.mjs;scripts/build/build.js 会跳过未标记的文件。插件文件中则只有 ESM 格式产物被标记为 playground 所需(见 scripts/build/packages/prettier.js 的playground: output.format === "esm"),UMD 版本不会为此单独构建。

产物格式与模块划分

Prettier 的发布包按三种格式输出,扩展名定义于 scripts/build/packages/prettier.js:

扩展名格式用途
.mjsESMNode.js 环境与浏览器 ESM 引入
.cjsCommonJSNode.jsrequire(如src/index.cjs
.jsUMD浏览器<script>直接引入,挂在全局变量上

包内模块(modules)由 scripts/build/packages/prettier.js 组织为:Main(核心 API:index.js/index.cjs/standalone.js)、CLIbin/prettierinternal/legacy-cliinternal/experimental-cli及 worker)、Doc(文档构建 APIdoc)、各语言插件plugins/*)以及Meta filespackage.jsonREADME.mdLICENSETHIRD-PARTY-NOTICES.md)。

  • 面向 Node.js 的文件由createNodejsFileConfig生成(scripts/build/packages/config-helpers.js),根据入口是.cjs还是.js自动选择 CJS 或 ESM 输出。
  • 面向浏览器/通用环境的文件由createUniversalFileConfig生成(同文件第 101 行起),同时产出.mjs与 UMD.js两种格式,UMD 全局变量名由umdVariableName指定,例如核心 API 的prettier、文档模块的doc,插件则是prettierPlugins.<pluginName>(见 scripts/build/packages/prettier.js)。

构建指定文件:--file--save-as

--file

只构建一个或多个特定文件,路径相对于dist目录:

yarn build --file=esm/parser-babel.mjs
yarn build --file=standalone.js --file=parser-meriyah.js

在 scripts/build/parse-arguments.js 中,每个--file值都会与DIST_DIR拼接成绝对路径存入Set;scripts/build/build.js 逐文件比对,命中才执行构建。--file适合调试单个解析器或 API 入口,避免全量构建。

--save-as

把单个文件的产物保存到其他位置,只能与一个--file搭配使用

yarn build --file=parser-babel.js --save-as=babel-for-test.js

校验逻辑在 scripts/build/parse-arguments.js:文件数必须恰好为 1,且--save-as只能是相对路径(不能越出dist/prettier目录)。该仓库正是用此机制生成vendors/babel-code-frame-for-test.js等测试专用文件(见 scripts/build-babel-code-frame-for-test.js)。

体积分析:--print-size--compare-size--report

--print-size:打印产物体积

yarn build --print-size

每个文件构建完成后打印其字节数(经过pretty-bytes格式化),实现于 scripts/build/build.js。

--compare-size:与上一发布版本对比

yarn build --compare-size

将本次构建产物与node_modules/<包名>/中已安装的上一发布版本逐个对比,打印体积差值(变大显示黄色、变小显示绿色,新文件显示[NEW FILE])。实现位于 scripts/build/build.js。注意两个限制(见 scripts/build/parse-arguments.js):

  • 不能与--no-minify同时使用;
  • 不能与--save-as同时使用。

--report:可视化分析包体积

yarn build --report=all yarn build --report=stdout --report=text --report=html

--report可重复指定,三种 reporter 格式:

行为
html生成esbuild-visualizer交互式 HTML 报告,保存为<产物名>.report.html
text生成纯文本报告,保存为<产物名>.report.txt
stdout在控制台直接打印分析报告

--report=all等价于同时指定三种格式,但不能与其他--report混用(scripts/build/parse-arguments.js)。报告由 scripts/build/esbuild-plugins/visualizer.js 实现:它开启 esbuild 的metafile,在构建结束时调用esbuild.analyzeMetafile(text/stdout)或esbuild-visualizer(html),将体积分析文件写到产物旁。该功能对排查"哪个依赖把包撑大了"非常有效,例如某次引入新的解析器依赖后,可借此确认体积增长的来源。

调试用:--minify--no-minify

默认是否压缩由包配置决定(config.mjs/bundler.mjs中控制),这两个标志用于覆盖默认行为,仅供调试,官方建议与--file搭配使用:

yarn build --file=index.js --minify yarn build --file=parser-babel.js --no-minify

二者不能同时使用(scripts/build/parse-arguments.js)。--no-minify的产物便于在调试器中阅读打包后的代码,而--minify可用于验证压缩路径下的正确性。

包配置的源码级细节

prettier主包

scripts/build/packages/prettier.js 是整个构建系统的核心配置,它通过replaceModule对第三方依赖做源码级裁剪与替换,这是 Prettier 能把体积控制在合理范围的关键手段,典型手法包括:

  • 移除未用功能:将@babel/parser中未使用的 JSX 实体解码替换为const entity = undefined;,把espree的 token 翻译器直接删掉(options.tokens === true替换为false,见 scripts/build/packages/prettier.js);
  • 替换实现文件:将postcsssource-map相关模块替换为空实现类,避免打入source-map依赖(scripts/build/packages/prettier.js);
  • 注入垫片:为浏览器环境提供BufferstructuredClone等全局对象的兜底实现;
  • 移除调试代码:把@glimmer/syntax中的DEBUG分支替换为false,把 Angular 编译器里大量与格式化无关的访问器实例删除;
  • 安全加固:将@typescript-eslint/typescript-estree中读取process.cwd()、解析项目 tsconfig 的逻辑替换为占位符/空实现,既减小体积也避免打包产物泄露本地路径(scripts/build/packages/prettier.js)。

CLI 部分则把bin/prettier.cjs、传统 CLI(src/cli/index.js)与实验性 CLI(src/experimental-cli/)分别打包,并通过 external 与替换把@prettier/clijson5js-yamlsmol-toml等依赖裁剪为最小导出,详见 scripts/build/packages/prettier.js。

插件包

三个内置插件包(@prettier/plugin-hermes@prettier/plugin-oxc@prettier/plugin-yuku)各自定义sourceDirectorydistDirectory。其中 scripts/build/packages/plugin-oxc.js 比较特殊:浏览器版index.browser.mjs会先通过buildOxcWasmParser(scripts/build/hacks/build-oxc-wasm-parser.js)编译 Oxc 的 WASM 解析器,再以replaceModule注入产物,且仅该浏览器版被标记为playground: true

Meta 文件生成

package.jsonLICENSEREADME.mdTHIRD-PARTY-NOTICES.md由 scripts/build/packages/config-helpers.js 统一生成。其中发布版package.json(scripts/build/builders/package-json.js)只保留白名单字段,并把engines.node改写为>=14PRODUCTION_MINIMAL_NODE_JS_VERSION)、bin指向打包后的 CLI 文件、files字段按实际产物文件列表重写、附带publishConfigTHIRD-PARTY-NOTICES.md由 scripts/build/builders/dependencies-license.js 从依赖许可信息汇总生成,满足发布合规要求。

验证构建产物

构建完成后,所有产物输出到dist/目录,可按包结构验证:

yarn build --clean --package prettier ls dist/prettier

dist/prettier下应包含index.mjsindex.cjsstandalone.jsstandalone.mjsdoc.js/doc.mjsplugins/(各语言解析器)、internal/(CLI 相关)以及bin/prettierpackage.jsonTHIRD-PARTY-NOTICES.md等文件。仓库的发布流程 scripts/release/steps/generate-bundles.js 正是先调用本构建系统生成dist,再据此发布到 npm;测试侧则有 scripts/tools/bundle-test/ 对打包产物做冒烟验证。若要单独验证某个插件,可执行:

yarn build --package @prettier/plugin-oxc --print-size --report=stdout

该命令只构建 Oxc 插件包、打印体积并输出体积分析报告,是日常开发调试插件产物体积的推荐组合。

小结

Prettier 的构建脚本是一个基于 esbuild 的产物流水线:入口 scripts/build/build.js 负责调度与状态输出,scripts/build/parse-arguments.js 负责全部标志的校验,各包配置(scripts/build/packages/)声明模块、产物格式与依赖裁剪规则。掌握--package--clean--playground--file/--save-as--print-size/--compare-size/--report--minify/--no-minify这些标志的组合用法,即可按需完成全量发布构建、仅构建网站产物、单文件调试、依赖体积审计等不同任务。

【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettier

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 15:01:38

射频工程师述职报告:用数据复现与脚本化PPT构建技术信任

简介&#xff1a;一份射频工程师述职报告PPT&#xff0c;适合通信、雷达、微波领域工程师在撰写个人述职、转正答辩或年终汇报时参考。报告以某射频工程师的真实项目经历为线索&#xff0c;从教育背景、获奖经历、学生作品“模拟交通灯”和“简易自动入库小车”的设计&#xff…

作者头像 李华
网站建设 2026/9/18 15:00:16

让 iMessage 里的 Rene 改用 TaoToken,再处理 41 份 newsletter

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 15:00:02

Flink反压机制演进:从逐级反压到动态反压

1. 这不是教科书里的“反压”概念&#xff0c;而是Flink生产环境里每天都在发生的呼吸节奏你刚接手一个Flink实时作业&#xff0c;监控面板上背压&#xff08;Backpressure&#xff09;指标突然飙到95%&#xff0c;下游Kafka写入延迟从200ms跳到3.8秒&#xff0c;告警短信一条接…

作者头像 李华
网站建设 2026/9/18 14:58:34

人工鱼群算法优化电力系统稳定器参数:从原理到MATLAB实现

简介&#xff1a;该PDF为收录于CSDN下载频道的学术论文&#xff0c;面向电力系统稳定分析与智能算法应用方向的工程师和研究人员。研究聚焦电力系统稳定器&#xff08;PSS&#xff09;参数优化问题&#xff0c;针对传统相位补偿法和数学规划法在多机系统中难以兼顾全局最优的不…

作者头像 李华
网站建设 2026/9/18 14:57:24

GitHub热榜实战指南:从筛选项目到参与协作的完整流程

9 月 4 日早上&#xff0c;我照例把 GitHub 的热榜页面刷了一遍。这 24 小时的榜单里&#xff0c;AI 相关项目仍然占了大头&#xff0c;但明显能感觉到另一个趋势&#xff1a;越来越多面向普通用户的工具型项目、教学型仓库在往上冲&#xff0c;而不只是模型和框架。很多人刷热…

作者头像 李华
网站建设 2026/9/18 14:57:12

Spring AI MCP Sampling Server 从 OpenAI 切到 Anthropic:同一把 TaoToken Key

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华