mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
build: ENG-06 support TS entries and preserve AMD globals
This commit is contained in:
1 parent
771482426f
commit
b53461da1c
23 files changed
+1046
-65
No files matched your search
@@ -42,6 +42,7 @@
|
||||
| [第三方来源清单](third-party.json) | 依赖解析、vendor 文件指纹、SDK/CDN 与许可来源缺口 |
|
||||
| [消费者与真实环境矩阵](environment-matrix.md) | 22 包的版本依据、能力/设备/样本、现有证据、验证任务及发布影响 |
|
||||
| [类型检查与迁移入口](typechecking.md) | 根/分包配置、当前/旧编译器、严格正反例和历史声明错误 |
|
||||
| [JS/TS 构建与开发](build-development.md) | 非交互选包、开发重建、资源夹具和 AMD 全局修复 |
|
||||
|
||||
## 维护规则
|
||||
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"task": "ENG-06",
|
||||
"sourceCommit": "77148242",
|
||||
"capturedAt": "2026-09-10T13:46:01.009Z",
|
||||
"runtime": {
|
||||
"node": "24.21.0",
|
||||
"yarn": "1.22.22",
|
||||
"vite": "7.3.6"
|
||||
},
|
||||
"scope": "Build and entrypoint validation, not package feature/device or npm publication approval",
|
||||
"sourceHashAlgorithm": "sha256-lf",
|
||||
"sources": {
|
||||
"scripts/build.js": "8df17bbe2d38b40f97695a29e4559ead5fe55dd2b031c2f4b09506ed09b6fbbc",
|
||||
"scripts/dev.js": "a611ebdea8bd3ffe811ecb3fa47796a038cf708bb72d30aee2bb12bc61c33c08",
|
||||
"scripts/projects.js": "76c0465e651b82d414027b491b962bb4751d3a2e86ea3b4b57908a6c29a3b038",
|
||||
"scripts/rebuild.js": "56b90edf29597550476c9d2c9ce3d79720d3bf421c4ee9e6a6890b77cca9615a",
|
||||
"scripts/utils.js": "4bf07ce5a1029df6360e402d128233e2ce9873316270473f6c5f23d88533a1ec",
|
||||
"refactor/fixtures/build/browser.html": "f23cf184f9280b13e6fc49ed81182030f56072f0abae0027592ba460434046ca",
|
||||
"refactor/fixtures/build/icon.svg": "794225a0e8d9464f748ece35b6fd3b49cf6175088881c4ce1ddd4c0c49ccc759",
|
||||
"refactor/fixtures/build/index.ts": "926ceac2f574f059ed43ecf734129111766023f1ec017d634dc750c2d5b37e84",
|
||||
"refactor/fixtures/build/shared.js": "d7b9fb6cdead2fb729501d24b6dd6c5e8a801b95e665069929e064f34e418056",
|
||||
"refactor/fixtures/build/style.less": "d706fd1267fac56cb207d41d1efe2b19c5b200c1ad346d9f11a9b4e1fad2d5b0",
|
||||
"refactor/fixtures/build/worker.ts": "2c98d00f6cc5efa557839b98fea27dc9004295910c52ae22f60437a2be7dd126"
|
||||
},
|
||||
"builds": {
|
||||
"before": "Original build all in isolated checkout at 77148242",
|
||||
"after": "Changed build all, then final explicit 21-package build with current root scripts",
|
||||
"libraries": 21,
|
||||
"formats": 63,
|
||||
"identical": 39,
|
||||
"amdReceiverOnly": 24,
|
||||
"reverseAmdPatchRestoresAllOriginalHashes": true,
|
||||
"artifacts": [
|
||||
{
|
||||
"file": "packages/artplayer/dist/artplayer.js",
|
||||
"before": "9ad044a601dafc24f449b690403fb1c343b40e99ffb31043272189fc3c1e7bfa",
|
||||
"after": "9ad044a601dafc24f449b690403fb1c343b40e99ffb31043272189fc3c1e7bfa"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer/dist/artplayer.legacy.js",
|
||||
"before": "71eebcca3192000c58e20f2e3cb76e86c05e33b5a1fab0add20436a5933a3e87",
|
||||
"after": "71eebcca3192000c58e20f2e3cb76e86c05e33b5a1fab0add20436a5933a3e87"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer/dist/artplayer.mjs",
|
||||
"before": "ac72f41624383ba853474161affb72b5887644449bf7cb18f6d18edeb2f6f997",
|
||||
"after": "ac72f41624383ba853474161affb72b5887644449bf7cb18f6d18edeb2f6f997"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ads/dist/artplayer-plugin-ads.js",
|
||||
"before": "ceb2d8a23a6735c161b31a4a427d8a757679aaf8a5a106ef40a6f047061f1df8",
|
||||
"after": "f01b375191b07e7f691927ed6f7258ee04b06aa1f83e5c91cea471326fa80086"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ads/dist/artplayer-plugin-ads.legacy.js",
|
||||
"before": "1e10c3a6b51de18e54cd02dd342ab4010fc466de6257659cf1d2e087642aa9a3",
|
||||
"after": "6259121de4a2e78ccd703fbc54f323a915f8bc0f6b2929df256e437519bcd439"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ads/dist/artplayer-plugin-ads.mjs",
|
||||
"before": "0919678423424047b28d9d803835d9ebc98f4477e04e58d497e8ed8c48b95008",
|
||||
"after": "0919678423424047b28d9d803835d9ebc98f4477e04e58d497e8ed8c48b95008"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ambilight/dist/artplayer-plugin-ambilight.js",
|
||||
"before": "8f32290c65a13b0a3026dee0045fef4125a9c9ac788ecb1675aef05f79172693",
|
||||
"after": "5442f8c414997dd38dd6b33e98af6679a1825b9ebabd2b81892b4607e3cef53e"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ambilight/dist/artplayer-plugin-ambilight.legacy.js",
|
||||
"before": "8f32290c65a13b0a3026dee0045fef4125a9c9ac788ecb1675aef05f79172693",
|
||||
"after": "5442f8c414997dd38dd6b33e98af6679a1825b9ebabd2b81892b4607e3cef53e"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-ambilight/dist/artplayer-plugin-ambilight.mjs",
|
||||
"before": "77486db6d24f50420c952de5b37d226e404089730c7c1c6be226c836f4e85f9c",
|
||||
"after": "77486db6d24f50420c952de5b37d226e404089730c7c1c6be226c836f4e85f9c"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-asr/dist/artplayer-plugin-asr.js",
|
||||
"before": "7f975b131a9ea207f88a157aafec778bc4906230500db9b30f5bbfbf327b251d",
|
||||
"after": "7f975b131a9ea207f88a157aafec778bc4906230500db9b30f5bbfbf327b251d"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-asr/dist/artplayer-plugin-asr.legacy.js",
|
||||
"before": "8b9f07ce97a8ce2e4f29e41e79257be530fd7a76558369d34c3d7497ea606c33",
|
||||
"after": "8b9f07ce97a8ce2e4f29e41e79257be530fd7a76558369d34c3d7497ea606c33"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-asr/dist/artplayer-plugin-asr.mjs",
|
||||
"before": "f1c4274541e86544b65936ff470413cfc7001999ebc193969f95c123be48cd61",
|
||||
"after": "f1c4274541e86544b65936ff470413cfc7001999ebc193969f95c123be48cd61"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-audio-track/dist/artplayer-plugin-audio-track.js",
|
||||
"before": "473f39f1d750f0722cca7e857c12c3c978ebe3c3b2352e325f1248318e508683",
|
||||
"after": "844662fa5fc7d70dd6fa3a8ba54614626b730c519411166d711ff89f2a301cb9"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-audio-track/dist/artplayer-plugin-audio-track.legacy.js",
|
||||
"before": "d8dc74bce76112d7430c98e3165605e32fde5d3c603be4b496eac58f574576cb",
|
||||
"after": "fff9eac4fe4b11116401247270d253e3946c19904aa2a5d3968e5e96140b715d"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-audio-track/dist/artplayer-plugin-audio-track.mjs",
|
||||
"before": "4ac599bc5a1a6ecb0cb1942d4269528bfb2cd9d047f988de61fe671a77ad14cd",
|
||||
"after": "4ac599bc5a1a6ecb0cb1942d4269528bfb2cd9d047f988de61fe671a77ad14cd"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-auto-thumbnail/dist/artplayer-plugin-auto-thumbnail.js",
|
||||
"before": "ce1f1472bf02b836dd85b92eadf2f00786c02cde11a20ac2801136a0f675d12a",
|
||||
"after": "65f946f98bc2581685d011e467c0c74def72cae32599a832fb380710c471d85b"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-auto-thumbnail/dist/artplayer-plugin-auto-thumbnail.legacy.js",
|
||||
"before": "3561e51e0a5f294b56641bf0884a24a4a9e326582d2e99416a04f9526c7d0cc0",
|
||||
"after": "e21e897c78ac73164ccdbcc9963fe6a57caf6de6d40350595e93ebd2ac50efa2"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-auto-thumbnail/dist/artplayer-plugin-auto-thumbnail.mjs",
|
||||
"before": "99da4748422bad54663c669d78963589a64c7cb02102e3544439fec7570a7f8b",
|
||||
"after": "99da4748422bad54663c669d78963589a64c7cb02102e3544439fec7570a7f8b"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.js",
|
||||
"before": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
|
||||
"after": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.legacy.js",
|
||||
"before": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0",
|
||||
"after": "c2aaee11bf1db765433b01d9f8dd3978e41fa4d39655db00ebd03fc0be3e35e0"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chapter/dist/artplayer-plugin-chapter.mjs",
|
||||
"before": "61342a069b84e0731d44a2464d0dfe637d1514d0037c740371fc866c516d2209",
|
||||
"after": "61342a069b84e0731d44a2464d0dfe637d1514d0037c740371fc866c516d2209"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chromecast/dist/artplayer-plugin-chromecast.js",
|
||||
"before": "4959661fc7f22eee3d32363bb0392a486c44499ec4a9c608ccfea55de29aaac6",
|
||||
"after": "76e28ad12ee3c87d25197062182b5a889b3ad4f62c0121e66e9efaa93a879bd4"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chromecast/dist/artplayer-plugin-chromecast.legacy.js",
|
||||
"before": "e2ba7aebec099884bb806f3caf77f9ff739ff9f236aefdfd0a4e69a8295c9d01",
|
||||
"after": "e489537ae2f30ba5e037da81cc479211a03e8a4fa035848c38c29668ab813ffe"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-chromecast/dist/artplayer-plugin-chromecast.mjs",
|
||||
"before": "b6d4e445a78f00fae53a35d239e62cc4a1448086d76058d69d8f9634a5754768",
|
||||
"after": "b6d4e445a78f00fae53a35d239e62cc4a1448086d76058d69d8f9634a5754768"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.js",
|
||||
"before": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f",
|
||||
"after": "7c8749288711ef97e80b6f9f00981170aa73f62a8ae25d6d663749a4aef62a8f"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.legacy.js",
|
||||
"before": "62db96685c48b8573f0480cead6ac934b1d0382b9fdd0046d17d15d2549c56dc",
|
||||
"after": "62db96685c48b8573f0480cead6ac934b1d0382b9fdd0046d17d15d2549c56dc"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku/dist/artplayer-plugin-danmuku.mjs",
|
||||
"before": "083d7de2f9a0314955dc83cdeedbc46c36728f7c9a0943ada8c3229edf9264ce",
|
||||
"after": "083d7de2f9a0314955dc83cdeedbc46c36728f7c9a0943ada8c3229edf9264ce"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku-mask/dist/artplayer-plugin-danmuku-mask.js",
|
||||
"before": "07cebbfbf77f8ec4b2df6a77d7d7300345b86f2993e220ff14e1aae530e4fb31",
|
||||
"after": "605c19124d062eafbd64ecde5a18b76f39f2a5ea01525a26ac37b919a4005472"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku-mask/dist/artplayer-plugin-danmuku-mask.legacy.js",
|
||||
"before": "a678a3c0f6d3920bee3b66af9943b3612935028bff61c96677b8eaf8ef7cc8f0",
|
||||
"after": "7c87e073fce448756e2c52b5580118f163d43ccd03bb46e76e2f3b44f07d5d68"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-danmuku-mask/dist/artplayer-plugin-danmuku-mask.mjs",
|
||||
"before": "48f7a449dc9555ab4060a578902b5431701f81b2f093a7cb0526042a8c417400",
|
||||
"after": "48f7a449dc9555ab4060a578902b5431701f81b2f093a7cb0526042a8c417400"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-dash-control/dist/artplayer-plugin-dash-control.js",
|
||||
"before": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5",
|
||||
"after": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-dash-control/dist/artplayer-plugin-dash-control.legacy.js",
|
||||
"before": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5",
|
||||
"after": "248aa1162ffb2480965f8e12d766ba6b7d2abfc2d80e65e8a6e8db6bdfa750c5"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-dash-control/dist/artplayer-plugin-dash-control.mjs",
|
||||
"before": "2cc039698627a6baaa5da1cc50cc5db5230ae5d31152b1217dda62e38c67aa3e",
|
||||
"after": "2cc039698627a6baaa5da1cc50cc5db5230ae5d31152b1217dda62e38c67aa3e"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.js",
|
||||
"before": "261d4ae84579c569ade1b1e7e91d51e3bd00c6efbea8c51a48b8283e0f4f3496",
|
||||
"after": "d7e58901c4e1c01e66b8b6c7a1553587b860a0f363fe13e9d9ea2d0cbcfcfa40"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.legacy.js",
|
||||
"before": "8e36b658196dece391add21c249b735f3abfe4082fc968d3dbbbb1ae58a77b31",
|
||||
"after": "eaf42b32ae4e3c4817fc7bb2c0fafbb851879d6b3298e4c24699c20a5dcdada9"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-document-pip/dist/artplayer-plugin-document-pip.mjs",
|
||||
"before": "22b432b5fc958f6f838b83fdfcc7e5ab7144137111b1f8cf081eb2e21afd8382",
|
||||
"after": "22b432b5fc958f6f838b83fdfcc7e5ab7144137111b1f8cf081eb2e21afd8382"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.js",
|
||||
"before": "7a6ce18a0b16f61f6149e0ea77efbb6e0503f997d39afe84271b59e366759e6d",
|
||||
"after": "7a6ce18a0b16f61f6149e0ea77efbb6e0503f997d39afe84271b59e366759e6d"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.legacy.js",
|
||||
"before": "893a3de27f9ed02b4b61f03732aec03bfcaf50d02c9beb15cc8a5767ef9121a0",
|
||||
"after": "893a3de27f9ed02b4b61f03732aec03bfcaf50d02c9beb15cc8a5767ef9121a0"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-hls-control/dist/artplayer-plugin-hls-control.mjs",
|
||||
"before": "85c4de4940e031d835b4de3ccf68af449d10aec4f630c89ecaf62f5503348931",
|
||||
"after": "85c4de4940e031d835b4de3ccf68af449d10aec4f630c89ecaf62f5503348931"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.js",
|
||||
"before": "271d5284e5246fbd04575526510b3e381e5e60d414c030acecce92fcf2e9b10a",
|
||||
"after": "7e50bf3478ca36d22986f7149e9b237ad970dcd49e0c524ca2d538be223e87d5"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.legacy.js",
|
||||
"before": "0726c96bf0df2aab2662ac8973bb7676a0ca7f8e4cb806aa44cb3ec9de296e64",
|
||||
"after": "3825e3412db4359105a5fae132ace8ee39a592ea26f95f55920ac4c6201941d2"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-jassub/dist/artplayer-plugin-jassub.mjs",
|
||||
"before": "31e4be88838ddd786f1f2180d2662792ac3b2bcce00b7ccac977b59b9d659716",
|
||||
"after": "31e4be88838ddd786f1f2180d2662792ac3b2bcce00b7ccac977b59b9d659716"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.js",
|
||||
"before": "c1cb0b511da88347165cc855185de9450a44835bb34bb802281ccdb854ef603c",
|
||||
"after": "742769de0c560cb7f01b40fc1a25b38420409211c85487a98f4053dbf824d89b"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.legacy.js",
|
||||
"before": "0b17644827e5b199afe8293093c44bfda571821014ff5b087c7c918c630dcc18",
|
||||
"after": "af3de6fa30b074940b12fcfce8ada04af0c0baa9cc0a8d083493c4e47a28ead3"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-multiple-subtitles/dist/artplayer-plugin-multiple-subtitles.mjs",
|
||||
"before": "e867c64303299a53d2bf6af62cc1e59044f1c7355aeb55e45b15ab2703448cb0",
|
||||
"after": "e867c64303299a53d2bf6af62cc1e59044f1c7355aeb55e45b15ab2703448cb0"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.js",
|
||||
"before": "72842ae0b4a44e44a080f88783c0c9bcd0b572fa0e946d817b2c36d960a08bfe",
|
||||
"after": "72842ae0b4a44e44a080f88783c0c9bcd0b572fa0e946d817b2c36d960a08bfe"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.legacy.js",
|
||||
"before": "4b88cec8d12844d639cc7703f88703136a4fe586781d9939bf2e3a0c93b42b60",
|
||||
"after": "4b88cec8d12844d639cc7703f88703136a4fe586781d9939bf2e3a0c93b42b60"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.mjs",
|
||||
"before": "91fbe929a9d8d780f1656b53697fb0fe400b9375db79370866ec2f4c5313e727",
|
||||
"after": "91fbe929a9d8d780f1656b53697fb0fe400b9375db79370866ec2f4c5313e727"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js",
|
||||
"before": "2d8e22cbd191bdac5a6c711b641590c2f8a90ba1aae185dd0e02a00baf000f8d",
|
||||
"after": "2d8e22cbd191bdac5a6c711b641590c2f8a90ba1aae185dd0e02a00baf000f8d"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js",
|
||||
"before": "ecbd0abe12c537687fb058de552c328c71ced71d911e454d0e37887192e9a291",
|
||||
"after": "ecbd0abe12c537687fb058de552c328c71ced71d911e454d0e37887192e9a291"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs",
|
||||
"before": "413af5e4f28d47c659521332042a8347da357b17af39cf08c89ce3347897c618",
|
||||
"after": "413af5e4f28d47c659521332042a8347da357b17af39cf08c89ce3347897c618"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-canvas/dist/artplayer-proxy-canvas.js",
|
||||
"before": "ef489570e13f402f1a60eb256ce3900a0021a3d05699c2ba15adfaaeff184d4c",
|
||||
"after": "b93386ae0d8b6a69c2b30a0e479a20a58e037b1068b28cf4a444b37b66495adb"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-canvas/dist/artplayer-proxy-canvas.legacy.js",
|
||||
"before": "7d25f21170c06d067aeaa1c8e79b15f2c0130a27cff1b410532d6c4ef4d2d45f",
|
||||
"after": "69341bcbd0916273cae0366d5590ac9d8607b22718ed97a84e844585021e1cd9"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-canvas/dist/artplayer-proxy-canvas.mjs",
|
||||
"before": "4bb4a881787770093652a3262fc214a2529a1c514ef49affaf152b8abf0f4dc6",
|
||||
"after": "4bb4a881787770093652a3262fc214a2529a1c514ef49affaf152b8abf0f4dc6"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-mediabunny/dist/artplayer-proxy-mediabunny.js",
|
||||
"before": "376a0fffbac289e71717795532d6fce9f3531f87cc025dfd7694952d44479037",
|
||||
"after": "988ed40e19294345d25347ad37681f329c1580ae2f2c1157f6d5a9589fdfbd7c"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-mediabunny/dist/artplayer-proxy-mediabunny.legacy.js",
|
||||
"before": "8a91401e634fa4fe75ea68d6dd17e0793948584a67bcfab8edfe0c574920b0e7",
|
||||
"after": "5f30c1bdcf5bca8f314b119b3e349254d5aa164d7a7cba9b53b5f6e09cd56fcd"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-proxy-mediabunny/dist/artplayer-proxy-mediabunny.mjs",
|
||||
"before": "5b151b82b4054706d3c7c5c610ffd8ce9f39ef56d8393867b524891331fef8c0",
|
||||
"after": "5b151b82b4054706d3c7c5c610ffd8ce9f39ef56d8393867b524891331fef8c0"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-iframe/dist/artplayer-tool-iframe.js",
|
||||
"before": "2ec257c8055a9448d12af3fecf1fae8ba58c06f47e85072d02c386cd258b0c86",
|
||||
"after": "9419306aadf112689f98db679750afb84fd32cf4e0fbee328bd5bd3126872639"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-iframe/dist/artplayer-tool-iframe.legacy.js",
|
||||
"before": "c0755d79f316cda71f045da86749648f95faf47c09180d525fb04bb753576d5f",
|
||||
"after": "778530d4ccf9f7d9abb5fcf0ae6cbd68044220eab27291b74eca6d5a168c625c"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-iframe/dist/artplayer-tool-iframe.mjs",
|
||||
"before": "cbcdb0516dd5f17ca2572a6b3e363ea63b0cfd9733f3e47689c02088f23f29b9",
|
||||
"after": "cbcdb0516dd5f17ca2572a6b3e363ea63b0cfd9733f3e47689c02088f23f29b9"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-thumbnail/dist/artplayer-tool-thumbnail.js",
|
||||
"before": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98",
|
||||
"after": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-thumbnail/dist/artplayer-tool-thumbnail.legacy.js",
|
||||
"before": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98",
|
||||
"after": "f77419cc62eeaa45c0413f4b04d169f78178fd539443cbf7b1e5db4ad4c95c98"
|
||||
},
|
||||
{
|
||||
"file": "packages/artplayer-tool-thumbnail/dist/artplayer-tool-thumbnail.mjs",
|
||||
"before": "4d46df8cccdc92d18efc6f12abedf85e8881737023f4ead28697c8b1e85eead1",
|
||||
"after": "4d46df8cccdc92d18efc6f12abedf85e8881737023f4ead28697c8b1e85eead1"
|
||||
}
|
||||
],
|
||||
"i18n": {
|
||||
"files": 22,
|
||||
"identicalToCheckout": true
|
||||
}
|
||||
},
|
||||
"browser": {
|
||||
"surface": "Codex in-app browser",
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36",
|
||||
"evidenceMethod": "Observed via real UI actions and DOM snapshots; results transcribed into this report",
|
||||
"amd": {
|
||||
"repeatedRuns": 3,
|
||||
"results": [
|
||||
{
|
||||
"name": "artplayer",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-ads",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-ads",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-ambilight",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-ambilight",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-asr",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-asr",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-audio-track",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-audio-track",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-auto-thumbnail",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-auto-thumbnail",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-chapter",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-chapter",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-chromecast",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-chromecast",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-danmuku",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-danmuku",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-danmuku-mask",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-danmuku-mask",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-dash-control",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-dash-control",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-document-pip",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-document-pip",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-hls-control",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-hls-control",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-jassub",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-jassub",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-multiple-subtitles",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-multiple-subtitles",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-vast",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-vast",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-vtt-thumbnail",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-plugin-vtt-thumbnail",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-proxy-canvas",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-proxy-canvas",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-proxy-mediabunny",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-proxy-mediabunny",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-tool-iframe",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-tool-iframe",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-tool-thumbnail",
|
||||
"extension": ".js",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "artplayer-tool-thumbnail",
|
||||
"extension": ".legacy.js",
|
||||
"passed": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"worker": {
|
||||
"passed": true,
|
||||
"reply": 42,
|
||||
"css": true,
|
||||
"svg": true,
|
||||
"initialValue": 42,
|
||||
"afterJsDependencyChange": 43,
|
||||
"afterSyntaxErrorRecovery": 42
|
||||
},
|
||||
"existingDemo": {
|
||||
"url": "http://localhost:8082/?libs=./uncompiled/artplayer/index.js&example=index",
|
||||
"script": "./uncompiled/artplayer/index.js",
|
||||
"media": "http://localhost:8082/assets/sample/video.mp4",
|
||||
"width": 640,
|
||||
"duration": 90.046009,
|
||||
"observedPlayingTime": 13.678864,
|
||||
"pausedAfterClick": true,
|
||||
"monacoLoaded": true,
|
||||
"existingAdvertisingScriptsPresent": true
|
||||
},
|
||||
"finalErrorsAndWarnings": []
|
||||
},
|
||||
"cli": {
|
||||
"interactiveBuild": "Real TTY prompts selection + Enter built artplayer all 3 formats",
|
||||
"namedDev": "artplayer and TS build probe on 8082 with --no-open",
|
||||
"invalidInput": "Unknown package, no TTY arguments and ambiguous JS/TS entry rejected before dist cleanup"
|
||||
},
|
||||
"tests": {
|
||||
"ciCheck": "passed",
|
||||
"node": 21,
|
||||
"baseline": 22,
|
||||
"failed": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"limitations": [
|
||||
"No original dist files rewritten in main checkout; candidate artifacts produced in isolated checkout",
|
||||
"Node VM exploratory import errors in DOM-dependent bundles were resolved by using the real browser, not by declaring VM support",
|
||||
"Development watch covers selected package src; external files still require restart",
|
||||
"Production package TypeScript migration remains zero"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
# 已实现的 JS/TS 构建与开发入口
|
||||
|
||||
ENG-06 保留原来的 Vite 7.3.6、Terser、三种库产物及路径,增加选包参数和 TS 入口;未切换 bundler 或运行时依赖。固定工具链仍为 Node 24.21.0 / Yarn 1.22.22。
|
||||
|
||||
```sh
|
||||
yarn build # TTY 中原交互选择
|
||||
yarn build artplayer # 一个包,无交互
|
||||
yarn build artplayer artplayer-plugin-chapter
|
||||
yarn build all # 全部 21 库,文档站仍用自身 build
|
||||
yarn dev artplayer --no-open # 8082,方便内置浏览器/自动化
|
||||
yarn dev # 原交互选择并打开浏览器
|
||||
yarn build --help
|
||||
yarn dev --help
|
||||
```
|
||||
|
||||
JS 包使用 src/index.js,TS 包使用 src/index.ts;必须恰有一个入口,同时存在时明确报错,避免残留 JS 遮盖新 TS。没有 TTY 且没有包参数时退出失败,不在 CI 中等待选择。未知名称、路径字符串、错误 all 组合在清理产物或启动服务前拒绝。dev 只接受一个包;build 可按提供顺序构建多个包,重复名称去重。
|
||||
|
||||
## 实现地图
|
||||
|
||||
| 文件 | 职责与维护点 |
|
||||
| --- | --- |
|
||||
| scripts/projects.js | 库包清单、CLI 选包、旧 prompts 入口、JS/TS 入口唯一性;utils.js 继续转出 getProjects,保留原脚本调用 |
|
||||
| scripts/build.js | 三格式顺序构建、受限 dist 清理、banner、复制 docs/compiled;main=.js/es2020、legacy=.legacy.js/es2015、ESM=.mjs/es2020 |
|
||||
| scripts/dev.js | 8082 服务、docs/uncompiled/包名/index.js、首次成功打开浏览器、源目录监听及错误后的继续开发 |
|
||||
| scripts/rebuild.js | 合并构建期间的通知并串行重建,避免多个构建同时清空同一输出目录;失败后下一次请求仍可运行 |
|
||||
| scripts/utils.js | 共享 Vite 资源/worker/output 配置与历史全局名称;AMD 补丁依据实际 UMD 全局参数,不假定压缩变量名 |
|
||||
| types/assets.d.ts | Less inline、SVG URL 与 SVG raw 的字符串类型;特定 worker 类型边界随拥有该 worker 的包配置 |
|
||||
| refactor/fixtures/build/ | 同时使用 TS、相邻 JS、Less、SVG raw、TS inline worker 的独立构建夹具;不属于发布包 |
|
||||
| refactor/scripts/build.test.mjs | 真实 CLI 产物、错误不误清理、CJS/global/AMD/ESM、队列错误恢复;浏览器 worker/全库 AMD 使用 browser.html |
|
||||
|
||||
Vite 支持 TS 转译,但不替代类型检查,源码检查继续运行 yarn typecheck。[Vite 7 的 TS 说明](https://v7.vite.dev/guide/features#typescript) 对此有明确区分。此任务没有将生产 JS 改名为 TS,也没有生成新公开声明;ENG-07 与包迁移任务继续负责声明和 tarball 验收。
|
||||
|
||||
dev 仍监听所选包的 src 目录,包外共享文件/tsconfig/依赖变化需要重启;不宣称已做完整依赖图热更新。错误会打印并保留监听,修复后重建;--no-open 仅禁止自动启动外部浏览器,访问地址不变。实际验证中源码修改和错误恢复后手动刷新页面确认了新结果。
|
||||
|
||||
## 本次发现的 AMD 构建缺陷
|
||||
|
||||
BUILD-AMD-01:旧插件在压缩 UMD 中把参数 t 写死为全局对象。但构建夹具的包装为 function(e,t),此时 t 是工厂;旧补丁生成 t.artplayerPluginBuildProbe=t(),AMD 返回虽可用,全局导出却不存在。补丁现在读取外层包装的第一个参数。只有实际 outputOptions.format=umd 时处理,避免将内联 worker 的 ES 输出当作 UMD。
|
||||
|
||||
不识别的 UMD/AMD 包装现在明确构建失败,避免升级打包工具后悄悄丢失全局接口。新夹具回归要求 AMD 工厂返回与对应全局为同一对象。两轮 21 库/63 产物比较:39 完全相同,24 个 UMD/legacy 只修正上述接收者,逆向替换该位置即可还原旧 SHA-256。全部 42 个 UMD/legacy 在内置浏览器中验证 AMD 工厂一次执行、返回与全局一致。
|
||||
|
||||
这修复的是构建路径。旧 npm 内容不变,根目录原有 dist 未手工改写;本次在隔离 checkout 中通过正常脚本生成候选,发布阶段必须用新工具重新生成并验证实际要发布的产物。AMD 入口通过不等于广告、模型、Cast、codec 等完整功能已验证。
|
||||
|
||||
## 重跑浏览器夹具
|
||||
|
||||
在用于验证的隔离 checkout 正常构建 21 库;复制 refactor/fixtures/build 下内容到临时包的 src,包名 artplayer-plugin-build-probe、版本 1.0.0。该包仅用于测试,不添加到真实 workspace 范围或发布列表。将 browser.html 复制到 docs/build-probes.html,将实际 21 库包名 JSON 数组写到 docs/build-packages.json。
|
||||
|
||||
运行 yarn dev artplayer-plugin-build-probe --no-open,打开 http://localhost:8082/build-probes.html。两个按钮分别验证真实 worker 往返及 42 个 AMD/global 入口,DOM 中的 JSON 是实际报告;每个 iframe 在加载后移除,worker 在结束后 terminate。Node 测试只能检查 worker 工厂存在,不能用它代替这次真实往返。
|
||||
|
||||
首页现有示例另用 `http://localhost:8082/?libs=./uncompiled/artplayer/index.js&example=index` 验证 JS 开发构建、Monaco 加载、媒体 metadata、播放和暂停;该首页包含既有广告脚本,本任务没有改变它们。完整编辑器功能、移动与 SDK 用例仍由 SITE/EX/包集成任务负责。
|
||||
|
||||
本次证据见 [构建与浏览器记录](baselines/build-validation.json) 和 [变更记录](changes/2026-09-10-ENG-06-build-development.md)。测试数量与入口通过不代表生产源码迁移完成。
|
||||
@@ -0,0 +1,15 @@
|
||||
# ENG-06:JS/TS 构建与非交互开发
|
||||
|
||||
日期 2026-09-10;起点 77148242;分支 codex/compatible-modernization。
|
||||
|
||||
build/dev 已共用入口解析与选包,保留交互、输出路径、三格式和目标语法,新增包参数与 dev --no-open。选包/入口错误先失败,dev 重建串行化并可从源码错误恢复。工具职责与完整运行步骤见 [维护说明](../build-development.md)。
|
||||
|
||||
新增真实构建夹具和三个 Node 测试,覆盖 TS+JS+Less+SVG+inline worker、三格式消费者、错误输入不清理已有产物、合并通知和失败重试。夹具复现旧 AMD 补丁将工厂参数误当全局的问题 BUILD-AMD-01;现按包装实际参数修复,未知格式拒绝构建。现有 API/global/CJS/ESM 路径未变,修正范围仅原先丢失的 AMD 全局赋值。
|
||||
|
||||
隔离 checkout 使用相同依赖和正常脚本完成改动前后各 21 库/63 产物构建。39 字节相同;24 只改 AMD 接收者,逆变换后的全部哈希回到旧结果。内置浏览器 Chrome/152 UA 验证 42 个实际 UMD/legacy AMD 入口,全部通过;TS 夹具的 Less/SVG、真实 worker 41->42 往返通过;修改 JS 依赖后值由 42->43,故意破坏 TS 后修复可重新构建并恢复 42。
|
||||
|
||||
现有首页的真实新 JS dev 构建、Monaco 加载、本地 MP4 metadata(640 宽、约 90.046 秒)、播放推进(13.678864 秒)及暂停已验。最终浏览器 error/warn 为空。开始时旧标签失效和 inventory 查询失败,直接新建内置标签后恢复;没有依赖 Chrome 连接。初始 Node VM 全库导入缺少部分 DOM/global API 的 8 个错误不作为包失败或通过,已改在实际浏览器检查全部 42 项。
|
||||
|
||||
完整 ci:check 通过 lint、类型及 21 Node +22 基线测试,共 43 项;原交互选择在真实 TTY 按 Enter 构建核心成功。最终按多个包参数重建的 63 产物与已验证候选全同;另生成的 22 个 i18n 文件与此前 checkout 字节相同。检查结果和产物指纹保存于 [验证数据](../baselines/build-validation.json)。未更改生产包版本、公开声明或根分发产物;没有把构建验证扩写为完整 SDK/真机或 npm 发布验收。
|
||||
|
||||
独立提交 ENG-06,可单独撤销工具改动;后续用新工具生成候选,禁止拿本轮验证替代实际发布 tarball。下一项 ENG-03 统一已有公共行为/单元夹具,再接 ENG-05 浏览器自动化和 chapter 的特有行为/源码迁移。
|
||||
@@ -0,0 +1,66 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Build compatibility probes</title>
|
||||
</head>
|
||||
<body>
|
||||
<button id="worker">Run TypeScript worker probe</button>
|
||||
<button id="amd">Run library AMD probes</button>
|
||||
<pre id="result">Ready</pre>
|
||||
<script src="/uncompiled/artplayer-plugin-build-probe/index.js"></script>
|
||||
<script>
|
||||
const result = document.querySelector('#result');
|
||||
document.querySelector('#worker').onclick = async () => {
|
||||
let worker;
|
||||
try {
|
||||
const probe = artplayerPluginBuildProbe({ label: 'browser' });
|
||||
worker = probe.createWorker();
|
||||
const reply = await new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => reject(new Error('Worker response timed out')), 5000);
|
||||
worker.onmessage = event => { clearTimeout(timeout); resolve(event.data); };
|
||||
worker.onerror = event => { clearTimeout(timeout); reject(new Error(event.message)); };
|
||||
worker.postMessage(41);
|
||||
});
|
||||
if (reply !== 42 || !probe.css.includes('#123abc') || !probe.svg.includes('<svg')) throw new Error('Resource result mismatch');
|
||||
result.textContent = JSON.stringify({ status: 'passed', userAgent: navigator.userAgent, value: probe.value, label: probe.label, workerReply: reply, css: true, svg: true }, null, 2);
|
||||
} catch (error) { result.textContent = JSON.stringify({ status: 'failed', error: String(error) }); }
|
||||
finally { if (worker) worker.terminate(); }
|
||||
};
|
||||
document.querySelector('#amd').onclick = async () => {
|
||||
const reports = [];
|
||||
try {
|
||||
const packages = await (await fetch('/build-packages.json')).json();
|
||||
if (packages.length !== 21 || new Set(packages).size !== 21 || !packages.includes('artplayer')) throw new Error('Incomplete library inventory');
|
||||
for (const name of packages) {
|
||||
for (const extension of ['.js', '.legacy.js']) {
|
||||
const frame = document.createElement('iframe');
|
||||
frame.hidden = true;
|
||||
document.body.append(frame);
|
||||
try {
|
||||
const scope = frame.contentWindow;
|
||||
let exported;
|
||||
let calls = 0;
|
||||
scope.define = Object.assign(factory => { calls++; exported = factory(); }, { amd: true });
|
||||
const script = frame.contentDocument.createElement('script');
|
||||
const file = `/compiled/${name}${extension}`;
|
||||
await new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => reject(new Error(`Load timeout: ${file}`)), 10000);
|
||||
script.onload = () => { clearTimeout(timeout); resolve(); };
|
||||
script.onerror = () => { clearTimeout(timeout); reject(new Error(`Load failed: ${file}`)); };
|
||||
script.src = file;
|
||||
frame.contentDocument.body.append(script);
|
||||
});
|
||||
const global = name === 'artplayer' || name.startsWith('artplayer-tool-')
|
||||
? name.replace(/(^|-)([a-z])/g, (_, prefix, letter) => letter.toUpperCase())
|
||||
: name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
||||
reports.push({ name, extension, passed: calls === 1 && exported !== undefined && exported === scope[global] });
|
||||
} finally { frame.remove(); }
|
||||
}
|
||||
}
|
||||
result.textContent = JSON.stringify({ status: reports.every(item => item.passed) ? 'passed' : 'failed', userAgent: navigator.userAgent, reports }, null, 2);
|
||||
} catch (error) { result.textContent = JSON.stringify({ status: 'failed', reports, error: String(error) }); }
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><path d="M0 0h10v10H0z"/></svg>
|
||||
|
After Width: | Height: | Size: 92 B |
@@ -0,0 +1,18 @@
|
||||
import css from './style.less?inline'
|
||||
import svg from './icon.svg?raw'
|
||||
import InlineWorker from './worker.ts?worker&inline'
|
||||
import { add } from './shared.js'
|
||||
|
||||
interface Options {
|
||||
label?: string
|
||||
}
|
||||
|
||||
export default function buildProbe(options: Options = {}) {
|
||||
return {
|
||||
label: options.label ?? 'default',
|
||||
value: add(20, 22),
|
||||
css,
|
||||
svg,
|
||||
createWorker: () => new InlineWorker(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const add = (left, right) => left + right
|
||||
@@ -0,0 +1,2 @@
|
||||
@accent: #123abc;
|
||||
.build-probe { color: @accent; }
|
||||
@@ -0,0 +1,3 @@
|
||||
self.onmessage = (event: MessageEvent<number>) => {
|
||||
self.postMessage(event.data + 1)
|
||||
}
|
||||
+3
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
|
||||
|
||||
状态:todo 188 / doing 0 / blocked 0 / done 26 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
状态:todo 187 / doing 0 / blocked 0 / done 27 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
|
||||
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
| ENG-03 | workspace<br>建立公共行为与单元测试入口 | ENG-02, BASE-03 | 保留现有 node:test,测试目录/夹具/统一入口 | 已有 19 项回归保留,旧版与候选可用同一夹具运行 | M | todo |
|
||||
| ENG-04 | workspace<br>建立类型测试基础 | ENG-02, BASE-05 | 根与分包 tsconfig、显式 TS 依赖、正反例测试 | 核心/试点与迁移模块严格检查,未迁移第三方/包历史问题独立台账;明确最低/当前 TS 和各环境类型;复用 BASE-05 的四种消费模式,不以 skipLibCheck 掩盖 BASE-TYPE-01/03 | M | done |
|
||||
| ENG-05 | workspace<br>建立真实浏览器测试服务 | ENG-03, BASE-04, BASE-08 | Playwright projects、本地 Range/失败媒体服务;复用 docs 页面/样本的状态隔离、错误采集与候选资源映射 | Chromium/Firefox/WebKit 的基础播放 smoke 和报告可执行;以媒体状态断言判定通过,区分轻量用例与真实编辑器交互 | M | todo |
|
||||
| ENG-06 | workspace<br>支持按包非交互与 JS/TS 构建 | ENG-02, BASE-05 | build/dev 入口解析、指定包参数、原交互保留 | 三种产物、Less/SVG/worker 和本地 8082 demo 正常;保持 BASE-05 的 AMD 同时写入全局行为及 i18n/legacy 入口 | H | todo |
|
||||
| ENG-06 | workspace<br>支持按包非交互与 JS/TS 构建 | ENG-02, BASE-05 | build/dev 入口解析、指定包参数、原交互保留 | 三种产物、Less/SVG/worker 和本地 8082 demo 正常;保持 BASE-05 的 AMD 同时写入全局行为及 i18n/legacy 入口 | H | done |
|
||||
| ENG-07 | workspace<br>建立 tarball 消费与产物检查 | ENG-04, ENG-06 | 隔离 npm 消费 fixtures、API/声明/入口差分 | 不借 workspace 源码通过,能识别缺文件与默认导出变化 | H | todo |
|
||||
| ENG-08 | workspace<br>增加覆盖率、资源与性能报告 | ENG-03, ENG-05, BASE-06 | 覆盖率基线、资源清理断言、性能报告与阈值 | 关键生命周期分支有门槛,报告不靠无意义断言堆数量;将 BASE-06 的同环境多组配对、计时/压缩审查阈值与资源异常分开接入候选,不把历史现象冻结成正常要求 | M | todo |
|
||||
| ENG-09 | workspace<br>建立全包依赖影响和文档检查 | ENG-07, DOC-04 | 共享核心/构建影响映射、文档及每任务完成提交的 Git 审计接入;契约-支持版本-测试 ID-命令-候选/报告-任务的覆盖索引 | 核心变化触发必需生态检查;原有 DOC-01 至 04 基线例外明确,后续 done 任务不能缺失独立 commit;计划/已执行/缺证据分开,识别缺少验证归属的公开契约 | M | todo |
|
||||
@@ -429,3 +429,4 @@
|
||||
- ENG-PM-01: [记录](changes/2026-09-10-ENG-PM-01-yarn-toolchain.md) [记录](baselines/yarn-validation.json)
|
||||
- ENG-02: [记录](changes/2026-09-10-ENG-02-readonly-ci.md) [记录](baselines/ci-validation.json)
|
||||
- ENG-04: [记录](changes/2026-09-10-ENG-04-typechecking.md) [记录](typechecking.md)
|
||||
- ENG-06: [记录](changes/2026-09-10-ENG-06-build-development.md) [记录](build-development.md) [记录](baselines/build-validation.json)
|
||||
@@ -1,5 +1,11 @@
|
||||
# 进度与证据
|
||||
|
||||
## 当前实施:ENG-06 JS/TS 构建与开发完成
|
||||
|
||||
正常 build/dev 支持指定包与唯一 JS/TS 入口,dev 可禁止自动打开浏览器并串行重建。构建夹具复现并修复 AMD 全局参数错误;63 产物中 39 字节相同、24 仅该修复;内置浏览器 42 个 AMD 入口、TS worker/资源及首页真实播放通过。见 [ENG-06](changes/2026-09-10-ENG-06-build-development.md)。
|
||||
|
||||
当前 214 项,27 完成、187 待办。43 项 Node/基线测试通过,生产源码 TS 迁移仍为零;工具链代码已有实际修改。ENG-04 提交 77148242,本任务独立提交。下一项 ENG-03 公共行为/单元入口,再接 ENG-05 浏览器自动化与 chapter 特有测试和源码迁移。
|
||||
|
||||
## 当前实施:ENG-04 类型检查基础完成
|
||||
|
||||
根/核心/chapter 配置和 yarn typecheck 已接入 CI。TS 5.9.3 三种消费模式与 TS 4.3.5 旧解析通过,NodeNext ESM 七项历史诊断单独记录;40 项 Node/基线测试通过。见 [ENG-04](changes/2026-09-10-ENG-04-typechecking.md)。当前 214 项,26 完成、188 待办;工具代码已有实施,生产源码 TS 迁移仍为零。BASE-08 提交 09902b8b,本任务独立提交。下一项 ENG-06 构建 TS 与非交互入口,再完成测试服务和 chapter 源码迁移。
|
||||
|
||||
@@ -4,7 +4,7 @@ BASE-07 将先前基线发现和第三方来源缺口纳入同一份责任台账
|
||||
|
||||
## 如何读取状态
|
||||
|
||||
39 项目前均为 open。reproduced 表示已保存复现结果;source-observed 表示在源码、声明或产物中看到事实;unverified 表示来源、环境或行为仍需取证。证据等级与处理状态互相独立,不能把 39 项全部称为缺陷,也不能因建立了测试基线而自动接受旧缺陷。
|
||||
BASE-07 初始登记 39 项,目前仍为 open;ENG-06 新增并修复 BUILD-AMD-01,共 40 项。reproduced 表示已保存复现结果;source-observed 表示在源码、声明或产物中看到事实;unverified 表示来源、环境或行为仍需取证。证据等级与处理状态互相独立,不能把全部事项称为缺陷,也不能因建立了测试基线而自动接受旧缺陷。
|
||||
|
||||
其中 15 项来自生命周期、DOM/示例、消费者类型/分发和性能基线;其余包含发布来源、站点分发、素材来源、8 组内嵌资源和 12 个集成边界。每项都列出负责的任务 ID、证据路径、兼容处理路线与关闭条件。具体复现仍以原基线报告为准。
|
||||
|
||||
|
||||
@@ -43,3 +43,4 @@
|
||||
| SDK-10 | open / 待取证 | mediabunny 实际集成验证范围 | PKG-MB-01, PKG-MB-09 |
|
||||
| SDK-11 | open / 待取证 | asr-caller-service 实际集成验证范围 | PKG-ASR-01, PKG-ASR-05, EX-03 |
|
||||
| SDK-12 | open / 待取证 | option-validator 实际集成验证范围 | CORE-01, CORE-07 |
|
||||
| BUILD-AMD-01 | resolved / 已复现 | AMD 全局导出补丁误将固定参数 t 当作全局对象 | ENG-06 |
|
||||
+23
-1
@@ -2,7 +2,7 @@
|
||||
"schemaVersion": 1,
|
||||
"task": "BASE-07",
|
||||
"sourceCommit": "e01f39ff",
|
||||
"updatedAt": "2026-09-10T12:58:34.267Z",
|
||||
"updatedAt": "2026-09-10T13:46:01.011Z",
|
||||
"note": "Open means closure evidence is outstanding; source-observed and unverified are not reproduced runtime bugs. A source issue already mitigated in the workspace still requires candidate regression evidence. No accepted-with-scope item is implied by baseline task completion.",
|
||||
"items": [
|
||||
{
|
||||
@@ -608,6 +608,28 @@
|
||||
],
|
||||
"compatibleResolution": "Bundled validation dependency; preserve validation/default/merge behavior and failure cleanup when typing constructor boundaries.",
|
||||
"closureCriteria": "固定 SDK/外部资源版本和环境;成功/失败/切换/销毁有真实证据,设备和网络限制逐项记录。"
|
||||
},
|
||||
{
|
||||
"id": "BUILD-AMD-01",
|
||||
"title": "AMD 全局导出补丁误将固定参数 t 当作全局对象",
|
||||
"confirmation": "reproduced",
|
||||
"status": "resolved",
|
||||
"owners": [
|
||||
"ENG-06"
|
||||
],
|
||||
"evidence": [
|
||||
"scripts/utils.js",
|
||||
"refactor/scripts/build.test.mjs",
|
||||
"refactor/baselines/build-validation.json"
|
||||
],
|
||||
"compatibleResolution": "从实际 UMD 包装提取全局参数,保留 AMD 工厂返回和旧 global 名称;不识别的包装失败而非静默发布。",
|
||||
"closureCriteria": "正常构建的 TS 资源夹具和全部库 UMD/legacy AMD 返回与全局为同一对象;其余输出仅允许已解释变化。",
|
||||
"resolutionEvidence": [
|
||||
"refactor/changes/2026-09-10-ENG-06-build-development.md",
|
||||
"refactor/baselines/build-validation.json",
|
||||
"refactor/scripts/build.test.mjs"
|
||||
],
|
||||
"resolutionRationale": "构建逻辑修复已完成;63 产物中 24 仅修复接收者,42 浏览器 AMD 检查通过。未改变旧 npm 内容;正式发布仍须用新工具生成实际候选。"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { execFileSync, spawnSync } from 'node:child_process'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import vm from 'node:vm'
|
||||
import { getEntryFile, parseProjects } from '../../scripts/projects.js'
|
||||
import { createRebuildQueue } from '../../scripts/rebuild.js'
|
||||
import { refactorDir } from './releases.mjs'
|
||||
|
||||
const root = path.resolve(refactorDir, '..')
|
||||
test('Package CLI rejects ambiguous requests and never accepts inherited project names', () => {
|
||||
const projects = { artplayer: '.', 'artplayer-plugin-chapter': '.' }
|
||||
assert.deepEqual(parseProjects(['all'], projects, 'build').names, Object.keys(projects))
|
||||
assert.deepEqual(parseProjects(['artplayer', 'artplayer'], projects, 'build').names, ['artplayer'])
|
||||
assert.equal(parseProjects(['artplayer', '--no-open'], projects, 'dev').open, false)
|
||||
for (const args of [['all', 'artplayer'], ['constructor'], ['../artplayer'], ['--unknown']])
|
||||
assert.throws(() => parseProjects(args, projects, 'build'))
|
||||
assert.throws(() => parseProjects(Object.keys(projects), projects, 'dev'))
|
||||
assert.throws(() => parseProjects(['all'], projects, 'dev'))
|
||||
})
|
||||
|
||||
test('Rebuild queue serializes changes and retries after failure', async () => {
|
||||
let release
|
||||
let start
|
||||
let count = 0
|
||||
const started = new Promise(resolve => { start = resolve })
|
||||
const first = new Promise(resolve => { release = resolve })
|
||||
const rebuild = createRebuildQueue(async () => {
|
||||
count++
|
||||
if (count === 1) {
|
||||
start()
|
||||
await first
|
||||
}
|
||||
})
|
||||
const pending = rebuild()
|
||||
await started
|
||||
assert.equal(rebuild(), pending)
|
||||
assert.equal(rebuild(), pending)
|
||||
assert.equal(count, 1)
|
||||
release()
|
||||
await pending
|
||||
assert.equal(count, 2)
|
||||
let fail = true
|
||||
const retry = createRebuildQueue(async () => {
|
||||
if (fail) throw new Error('invalid source')
|
||||
})
|
||||
await assert.rejects(retry(), /invalid source/)
|
||||
fail = false
|
||||
await retry()
|
||||
})
|
||||
|
||||
test('Normal build CLI compiles TypeScript, JS, Less, SVG and inline worker into compatible formats', async () => {
|
||||
const parent = path.join(refactorDir, '.cache')
|
||||
fs.mkdirSync(parent, { recursive: true })
|
||||
const directory = fs.mkdtempSync(path.join(parent, 'build-check-'))
|
||||
const name = 'artplayer-plugin-build-probe'
|
||||
const project = path.join(directory, 'packages', name)
|
||||
const dist = path.join(project, 'dist')
|
||||
const run = args => spawnSync(process.execPath, [path.join(root, 'scripts/build.js'), ...args], { cwd: directory, encoding: 'utf8', timeout: 60000 })
|
||||
try {
|
||||
fs.mkdirSync(project, { recursive: true })
|
||||
fs.cpSync(path.join(refactorDir, 'fixtures/build'), path.join(project, 'src'), { recursive: true })
|
||||
fs.writeFileSync(path.join(project, 'package.json'), JSON.stringify({ name, version: '1.0.0' }))
|
||||
fs.mkdirSync(dist)
|
||||
fs.writeFileSync(path.join(dist, 'preserve.txt'), 'keep until a valid build starts')
|
||||
assert.equal(run(['nonexistent']).status, 1)
|
||||
assert.equal(run([]).status, 1)
|
||||
fs.writeFileSync(path.join(project, 'src/index.js'), 'export default 1')
|
||||
assert.throws(() => getEntryFile(project), /exactly one/)
|
||||
assert.equal(run([name]).status, 1)
|
||||
assert(fs.existsSync(path.join(dist, 'preserve.txt')))
|
||||
fs.unlinkSync(path.join(project, 'src/index.js'))
|
||||
execFileSync(process.execPath, [path.join(root, 'scripts/build.js'), name], { cwd: directory, env: { ...process.env, NODE_ENV: 'production' }, encoding: 'utf8', timeout: 60000 })
|
||||
assert.deepEqual(fs.readdirSync(dist).sort(), [`${name}.js`, `${name}.legacy.js`, `${name}.mjs`])
|
||||
function check(factory) {
|
||||
assert.equal(factory().label, 'default')
|
||||
const result = factory({ label: 'verified' })
|
||||
assert.equal(result.label, 'verified')
|
||||
assert.equal(result.value, 42)
|
||||
assert.match(result.css, /#123abc/)
|
||||
assert.match(result.svg, /<svg/)
|
||||
assert.equal(typeof result.createWorker, 'function')
|
||||
}
|
||||
for (const extension of ['.js', '.legacy.js']) {
|
||||
const code = fs.readFileSync(path.join(dist, name + extension), 'utf8')
|
||||
assert.equal(fs.readFileSync(path.join(directory, 'docs/compiled', name + extension), 'utf8'), code)
|
||||
const cjs = { exports: {}, module: { exports: {} } }
|
||||
vm.runInNewContext(code, cjs)
|
||||
check(cjs.module.exports)
|
||||
const global = {}
|
||||
vm.runInNewContext(code, global)
|
||||
check(global.artplayerPluginBuildProbe)
|
||||
let exported
|
||||
const amd = { define: Object.assign(factory => { exported = factory() }, { amd: true }) }
|
||||
vm.runInNewContext(code, amd)
|
||||
assert.equal(exported, amd.artplayerPluginBuildProbe)
|
||||
check(exported)
|
||||
}
|
||||
check((await import(pathToFileURL(path.join(dist, `${name}.mjs`)))).default)
|
||||
}
|
||||
finally {
|
||||
const relative = path.relative(parent, directory)
|
||||
assert(relative.startsWith('build-check-') && !relative.includes(path.sep))
|
||||
fs.rmSync(directory, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
+6
-2
@@ -547,11 +547,15 @@
|
||||
"ENG-02",
|
||||
"BASE-05"
|
||||
],
|
||||
"status": "todo",
|
||||
"status": "done",
|
||||
"risk": "H",
|
||||
"deliverable": "build/dev 入口解析、指定包参数、原交互保留",
|
||||
"acceptance": "三种产物、Less/SVG/worker 和本地 8082 demo 正常;保持 BASE-05 的 AMD 同时写入全局行为及 i18n/legacy 入口",
|
||||
"evidence": []
|
||||
"evidence": [
|
||||
"changes/2026-09-10-ENG-06-build-development.md",
|
||||
"build-development.md",
|
||||
"baselines/build-validation.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ENG-07",
|
||||
|
||||
+9
-18
@@ -2,8 +2,8 @@ import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import cpy from 'cpy'
|
||||
import prompts from 'prompts'
|
||||
import { build as viteBuild } from 'vite'
|
||||
import { getEntryFile, selectProjects } from './projects.js'
|
||||
import { getGlobalName, getProjects, getViteBuildConfig } from './utils.js'
|
||||
|
||||
const projects = getProjects()
|
||||
@@ -28,9 +28,11 @@ async function build(name, targetName, clean = false) {
|
||||
const projectDir = projects[name]
|
||||
const { version } = JSON.parse(fs.readFileSync(path.join(projectDir, 'package.json'), 'utf-8'))
|
||||
const distDir = path.join(projectDir, 'dist')
|
||||
const entryFile = path.join(projectDir, 'src/index.js')
|
||||
const entryFile = getEntryFile(projectDir)
|
||||
|
||||
if (clean && fs.existsSync(distDir)) {
|
||||
if (fs.realpathSync(distDir) !== path.join(fs.realpathSync(projectDir), 'dist'))
|
||||
throw new Error(`Refusing to clean redirected dist directory: ${distDir}`)
|
||||
fs.rmSync(distDir, { recursive: true, force: true })
|
||||
}
|
||||
|
||||
@@ -79,22 +81,11 @@ async function buildProject(name) {
|
||||
}
|
||||
|
||||
async function runBuild() {
|
||||
if (process.argv.includes('all')) {
|
||||
for (const name of Object.keys(projects)) {
|
||||
await buildProject(name)
|
||||
}
|
||||
console.log('✅ Finished building all packages!')
|
||||
}
|
||||
else {
|
||||
const { value } = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to build?',
|
||||
choices: Object.keys(projects).map(name => ({ title: name, value: name })),
|
||||
})
|
||||
if (value)
|
||||
await buildProject(value)
|
||||
}
|
||||
const { names } = await selectProjects(projects, 'build')
|
||||
for (const name of names)
|
||||
await buildProject(name)
|
||||
if (names.length)
|
||||
console.log(`✅ Finished building ${names.length} package(s)!`)
|
||||
}
|
||||
|
||||
runBuild().catch((error) => {
|
||||
|
||||
+17
-16
@@ -1,17 +1,18 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import prompts from 'prompts'
|
||||
import process from 'node:process'
|
||||
import servor from 'servor'
|
||||
import openBrowser from 'servor/utils/openBrowser.js'
|
||||
import { build as viteBuild } from 'vite'
|
||||
import { getEntryFile, selectProjects } from './projects.js'
|
||||
import { createRebuildQueue } from './rebuild.js'
|
||||
import { getGlobalName, getProjects, getViteBuildConfig } from './utils.js'
|
||||
|
||||
const projects = getProjects()
|
||||
|
||||
async function develop(name) {
|
||||
async function develop(name, open) {
|
||||
const projectPath = projects[name]
|
||||
const uncompiledPath = path.resolve(`docs/uncompiled/${name}`)
|
||||
const entryFile = path.join(projectPath, 'src/index.js')
|
||||
let browserOpened = false
|
||||
|
||||
const { url } = await servor({
|
||||
@@ -27,7 +28,7 @@ async function develop(name) {
|
||||
const startTime = Date.now()
|
||||
try {
|
||||
const config = getViteBuildConfig({
|
||||
entry: entryFile,
|
||||
entry: getEntryFile(projectPath),
|
||||
outDir: uncompiledPath,
|
||||
name: getGlobalName(name),
|
||||
format: 'iife',
|
||||
@@ -40,7 +41,7 @@ async function develop(name) {
|
||||
await viteBuild({ root: projectPath, ...config })
|
||||
console.log(`[${name}] ✅ Built in ${Date.now() - startTime}ms`)
|
||||
|
||||
if (!browserOpened) {
|
||||
if (open && !browserOpened) {
|
||||
browserOpened = true
|
||||
openBrowser(url)
|
||||
}
|
||||
@@ -50,7 +51,9 @@ async function develop(name) {
|
||||
}
|
||||
}
|
||||
|
||||
await buildBundle()
|
||||
const rebuild = createRebuildQueue(buildBundle)
|
||||
await rebuild()
|
||||
console.log(`[${name}] Demo: ${url}/?libs=./uncompiled/${name}/index.js`)
|
||||
|
||||
const srcPath = path.join(projectPath, 'src')
|
||||
console.log(`[${name}] 👀 Watching ${srcPath}...`)
|
||||
@@ -58,18 +61,16 @@ async function develop(name) {
|
||||
fs.watch(srcPath, { recursive: true }, async (_, filename) => {
|
||||
if (filename) {
|
||||
console.log(`[${name}] 📝 Changed: ${filename}`)
|
||||
await buildBundle()
|
||||
await rebuild()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const { value } = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to develop?',
|
||||
choices: Object.keys(projects).map(name => ({ title: name, value: name })),
|
||||
})
|
||||
if (value)
|
||||
await develop(value)
|
||||
})()
|
||||
const { names, open } = await selectProjects(projects, 'dev')
|
||||
if (names.length)
|
||||
await develop(names[0], open)
|
||||
})().catch((error) => {
|
||||
console.error('❌ Development server failed:', error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
@@ -0,0 +1,65 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import prompts from 'prompts'
|
||||
|
||||
export function getProjects(root = process.cwd()) {
|
||||
const packages = path.join(root, 'packages')
|
||||
return Object.fromEntries(fs.readdirSync(packages).sort()
|
||||
.filter(name => name !== 'artplayer-vitepress' && fs.existsSync(path.join(packages, name, 'package.json')))
|
||||
.map(name => [name, path.join(packages, name)]))
|
||||
}
|
||||
|
||||
export function getEntryFile(projectDir) {
|
||||
const entries = ['index.js', 'index.ts'].map(name => path.join(projectDir, 'src', name)).filter(file => fs.existsSync(file) && fs.statSync(file).isFile())
|
||||
if (entries.length !== 1)
|
||||
throw new Error(`${path.basename(projectDir)} must have exactly one src/index.js or src/index.ts; found ${entries.length}`)
|
||||
return entries[0]
|
||||
}
|
||||
|
||||
export function parseProjects(args, projects, command) {
|
||||
const names = []
|
||||
let open = true
|
||||
for (const arg of args) {
|
||||
if (arg === '--no-open' && command === 'dev')
|
||||
open = false
|
||||
else if (arg === '--help')
|
||||
return { help: true, names: [], open }
|
||||
else if (arg !== '--')
|
||||
names.push(arg)
|
||||
}
|
||||
if (names.includes('all')) {
|
||||
if (command !== 'build' || names.length !== 1)
|
||||
throw new Error('Use build all on its own; dev accepts one package')
|
||||
return { names: Object.keys(projects), open }
|
||||
}
|
||||
for (const name of names) {
|
||||
if (!Object.hasOwn(projects, name))
|
||||
throw new Error(`Unknown package: ${name}. Use yarn ${command} --help`)
|
||||
}
|
||||
if (command === 'dev' && names.length > 1)
|
||||
throw new Error('dev accepts one package')
|
||||
return { names: [...new Set(names)], open }
|
||||
}
|
||||
|
||||
export async function selectProjects(projects, command) {
|
||||
const selection = parseProjects(process.argv.slice(2), projects, command)
|
||||
if (selection.help) {
|
||||
console.log(command === 'build' ? 'Usage: yarn build [all | package ...]' : 'Usage: yarn dev [package] [--no-open]')
|
||||
return selection
|
||||
}
|
||||
if (!selection.names.length) {
|
||||
if (!process.stdin.isTTY)
|
||||
throw new Error(`Select a package explicitly in non-interactive mode: yarn ${command} artplayer`)
|
||||
const { value } = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: `Which project do you want to ${command === 'build' ? 'build' : 'develop'}?`,
|
||||
choices: Object.keys(projects).map(name => ({ title: name, value: name })),
|
||||
})
|
||||
selection.names = value ? [value] : []
|
||||
}
|
||||
for (const name of selection.names)
|
||||
getEntryFile(projects[name])
|
||||
return selection
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export function createRebuildQueue(build) {
|
||||
let pending = false
|
||||
let active
|
||||
return () => {
|
||||
pending = true
|
||||
if (!active) {
|
||||
active = Promise.resolve().then(async () => {
|
||||
while (pending) {
|
||||
pending = false
|
||||
await build()
|
||||
}
|
||||
}).finally(() => { active = undefined })
|
||||
}
|
||||
return active
|
||||
}
|
||||
}
|
||||
+13
-25
@@ -1,20 +1,4 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { glob } from 'glob'
|
||||
|
||||
export function getProjects() {
|
||||
return glob
|
||||
.sync('packages/*')
|
||||
.sort()
|
||||
.filter(item => !item.endsWith('artplayer-vitepress'))
|
||||
.filter(item => fs.existsSync(path.join(item, 'package.json')))
|
||||
.reduce((result, item) => {
|
||||
const name = item.split(/\/|\\/g).pop()
|
||||
result[name] = path.resolve(process.cwd(), item)
|
||||
return result
|
||||
}, {})
|
||||
}
|
||||
export { getProjects } from './projects.js'
|
||||
|
||||
// Convert kebab-case to PascalCase: artplayer-plugin-ads -> ArtplayerPluginAds
|
||||
export function toPascalCase(name) {
|
||||
@@ -71,7 +55,7 @@ export function getViteBuildConfig(options) {
|
||||
plugins: banner
|
||||
? [{
|
||||
name: 'add-banner-and-global',
|
||||
generateBundle(_, bundle) {
|
||||
generateBundle(outputOptions, bundle) {
|
||||
for (const chunk of Object.values(bundle)) {
|
||||
if (chunk.type === 'chunk') {
|
||||
// Remove any inline worker banners (inside template literals)
|
||||
@@ -83,14 +67,18 @@ export function getViteBuildConfig(options) {
|
||||
}
|
||||
// For UMD format, modify the wrapper to always expose global
|
||||
// even when AMD loader is present (fix for RequireJS environments)
|
||||
if (format === 'umd') {
|
||||
// Match both original and minified UMD patterns:
|
||||
// Original: typeof define === 'function' && define.amd ? define(factory) :
|
||||
// Minified: "function"===typeof define&&define.amd?define(e):
|
||||
// Change to: ... ? (global.Name = factory(), define(function() { return global.Name; })) :
|
||||
if (outputOptions.format === 'umd') {
|
||||
const wrapper = code.replace(/^\/\*![\s\S]*?\*\/\s*/, '').match(/^[!(\s]*function\s*\(\s*([\w$]+)\s*,\s*([\w$]+)\s*\)/)
|
||||
if (!wrapper)
|
||||
throw new Error(`Unrecognized UMD wrapper for ${name}`)
|
||||
const global = wrapper[1]
|
||||
const amd = /["']function["']\s*===?\s*typeof define\s*&&\s*define\.amd\s*\?\s*define\(([\w$]+)\)\s*:/
|
||||
if (!amd.test(code))
|
||||
throw new Error(`Unrecognized AMD branch for ${name}`)
|
||||
// Keep AMD and the global export identical regardless of minified parameter names.
|
||||
code = code.replace(
|
||||
/["']function["']\s*===?\s*typeof define\s*&&\s*define\.amd\s*\?\s*define\((\w+)\)\s*:/,
|
||||
`"function"==typeof define&&define.amd?(t.${name}=$1(),define(function(){return t.${name}})):`,
|
||||
amd,
|
||||
`"function"==typeof define&&define.amd?(${global}.${name}=$1(),define(function(){return ${global}.${name}})):`,
|
||||
)
|
||||
}
|
||||
chunk.code = code
|
||||
|
||||
Vendored
+5
@@ -7,3 +7,8 @@ declare module '*.svg' {
|
||||
const svg: string
|
||||
export default svg
|
||||
}
|
||||
|
||||
declare module '*.svg?raw' {
|
||||
const svg: string
|
||||
export default svg
|
||||
}
|
||||
Reference in new issue
Block a user