빈 번들 503 을 "에셋을 선언한 활성 확장이 있는데 결과가 비었다" 로 판정해, 스타일 규칙이 아직 없는 0바이트 CSS 만 선언된 기본 구성이 통째로 503 이 됐다. file_get_contents 는 0바이트에서 false 가 아니라 '' 를 돌려주므로 읽기 실패 분기도 타지 않는다. 선언 축 게터는 전부 file_exists 게이트라 부재를 셀 수 없어, 존재 게이트가 없는 getDeclaredAssetAbsolutePaths 를 통로로 두고 503 의 근거를 소실 축(findMissingDeclaredAssets)으로 옮긴다. 존재하되 비었으면 빈 200 이다. 곁들여: 실패 배너 항목명을 내부 구분 키에서 사용자 어휘로(engine-v1.64.7), 봇 화면이 없는 템플릿 CSS 를 링크하지 않도록 실재 게이트, 매니페스트 자산 선언 드리프트 4건 정정.
84 lines
4.1 KiB
YAML
84 lines
4.1 KiB
YAML
# audit:allow test-scenario-coverage[cross_product] reason: 입력 axis 의 완전 cross-product(11축)는 조합 폭발이라 대표 조합만 마킹한다. effects 축은 면제하지 않는다 — 모든 effect 가 테스트 마킹으로 도달해야 한다.
|
|
|
|
feature: 확장(모듈/플러그인) 프론트엔드 IIFE/CSS 서버측 번들 병합
|
|
|
|
description: |
|
|
활성 모듈/플러그인의 global 전략 프론트엔드 에셋을 타입별로 하나의 번들로
|
|
서버에서 병합해 서빙, 확장 수에 비례하던 HTTP 요청을 종류별 1건으로 줄인다.
|
|
각 확장 IIFE 자가등록 계약은 유지(priority 순 물리 병합 = 실행 순서).
|
|
|
|
핵심 동작:
|
|
- ExtensionBundleService 가 getOrderedGlobalAssetPaths(uasort priority) →
|
|
buildJsBundle(`\n;\n` join, sourceMappingURL 처리) → getBundleFilePath(캐시)
|
|
- PublicModule/PluginController::serveBundle{Js,Css} → fileResponse(ETag/304)
|
|
- blade bundleUrls → ModuleAssetLoader.loadBundle(module) → loadBundle(plugin)
|
|
- 확장 캐시 버전 bump 시 새 파일명 자동 무효화, ext-bundles:cleanup GC
|
|
- bundleUrls 부재 시 개별 로딩 폴백(회귀 안전)
|
|
|
|
axes:
|
|
ext_type: [module, plugin]
|
|
asset_kind: [js, css, both]
|
|
active_combo: [none, one, multiple]
|
|
strategy: [global, layout, lazy]
|
|
environment: [production, non_production]
|
|
version_state: [first_request, cache_hit, version_bumped]
|
|
source_map_state: [present, absent]
|
|
css_url_state: [no_url, absolute_url, relative_url]
|
|
file_state: [all_present, present_empty, one_missing]
|
|
priority_order: [ascending, gdpr_lowest]
|
|
bundle_urls_present: [present, absent_fallback]
|
|
|
|
exclusions:
|
|
- { strategy: layout, active_combo: none, reason: "layout/lazy 전략은 번들 대상 아님 — 개별 레이아웃 처리" }
|
|
- { active_combo: none, version_state: cache_hit, reason: "활성 에셋 0건이면 캐시 파일을 만들지 않음 (빈 경로)" }
|
|
|
|
effects:
|
|
- ordered_by_priority_ascending_only_no_name_hardcode
|
|
- non_global_strategy_excluded_from_bundle
|
|
- js_iife_joined_with_semicolon_newline_separator
|
|
- prod_strips_source_mapping_url
|
|
- dev_rewrites_source_mapping_url_to_asset_serving_path
|
|
- per_extension_fault_tolerance_skips_missing_file_keeps_rest
|
|
- css_with_relative_url_rewritten_not_excluded
|
|
- empty_bundle_returns_empty_path_and_empty_ok_response
|
|
- prod_writes_versioned_cache_file_and_reuses_on_same_version
|
|
- non_production_rebuilds_every_request_no_disk_cache
|
|
- cleanup_removes_stale_version_bundles_only
|
|
- clear_bundles_by_type_scopes_to_prefix
|
|
- plugin_bundle_gdpr_first_when_priority_lowest
|
|
- bundle_endpoint_serves_with_etag_and_304
|
|
- bundle_url_same_origin_only
|
|
- loadbundle_single_script_single_link_append
|
|
- loadbundle_dedup_guard_no_double_load
|
|
- loadbundle_null_urls_noop
|
|
- concat_iife_self_registration_preserved
|
|
- missing_bundle_urls_falls_back_to_individual_loading
|
|
- individual_iife_requests_absent_in_browser
|
|
- gdpr_interceptor_still_active_after_merge
|
|
- extension_handlers_registered_no_console_error
|
|
- bundle_empty_with_declared_assets_returns_503
|
|
- asset_declaration_count_reads_manifest_not_built_files
|
|
- bundle_decision_is_shared_across_extension_types
|
|
- bundle_disk_write_failure_falls_back_to_memory
|
|
- bundle_script_static_miss_falls_back_to_api
|
|
- empty_result_with_present_empty_artifacts_returns_200
|
|
- empty_result_with_missing_declared_artifact_returns_503
|
|
- missing_artifact_paths_are_logged
|
|
- bundle_css_failure_banner_uses_user_vocabulary
|
|
|
|
test_files:
|
|
- tests/Unit/Services/ExtensionBundleServiceTest.php
|
|
- tests/Unit/Extension/AbstractModuleDeclaredAssetsTest.php
|
|
- tests/Unit/Extension/AbstractPluginDeclaredAssetsTest.php
|
|
- tests/Unit/Extension/BundledManifestAssetDeclarationTest.php
|
|
- tests/Feature/Api/Public/ExtensionBundleServingTest.php
|
|
- resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts
|
|
- tests/Playwright/specs/extension-bundle-loading.spec.ts
|
|
|
|
validation:
|
|
audit_rules:
|
|
- extension-bundle-url-same-origin
|
|
- extension-bundle-concat-separator
|
|
- extension-bundle-asset-path-getter
|
|
- clears-template-caches-no-file-delete
|