Mock build: a page that initialises on window.onload renders nothing

Đang mở
#1,594 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
48/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
javascript, typescript
Lĩnh vực
backend, devtools

Hướng nghiên cứu

Start by reading host/boot.js, especially replayAll and the boot-anyway fallback, then trace when replayed scripts run relative to the page’s DOMContentLoaded and load events. Reproduce with the minimal seed app and a mock build. Done means pages that register load handlers during script replay initialize correctly, including in the fallback path, without breaking scripts replayed before the real load event.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Symptom

A page that initialises on window.onload renders nothing in a mock build: no error, no failed request, a blank app. The app's own scripts do run - they just run after the load event, so the handler they assign never fires.

First consumer to hit it: sasjs/minimal-seed-app (the template sasjs create --template minimal downloads), whose src/scripts.js ended with window.onload = function () { ... }.

Repro

npx @sasjs/[email protected] create demo --template minimal
cd demo
npx sasjs compile -t mock && npx sasjs build -t mock   # after adding a mock target
npx http-server sasjsbuild/mock -p 3001

Headless chromium against http://localhost:3001 (the page never leaves the login screen; the app's sasjs object is never constructed):

events: ["DOMContentLoaded 263", "load 270"]
readyState: "complete"
window.onload: "function"        <- assigned by the replayed script
typeof sasjs: "undefined"        <- startApp() never ran

Cause

host/boot.js replays the page's script tags once the worker claims the page - necessarily after load, since that needs registration + activation. Its own header says the tags run "just later than the parser would have run them"; for load listeners they run after it, and an assignment to window.onload at that point is never called.

Why it matters beyond this app

window.onload (and addEventListener('load')) is an ordinary way to initialise a page, especially a classic-script app with no bundler - which is exactly the app shape a minimal seed app is. The failure is silent: nothing in the console, nothing in the network tab, so it reads as "the mock build is broken" rather than "your init hook was missed". data-early does not help - a handler that needs the worker cannot run early.

Suggested fix

In boot.js, after replayAll completes (and in the boot-anyway fallback), if the document has already finished loading, dispatch the event(s) the replayed scripts expect:

function fireIfMissed() {
  if (document.readyState !== 'complete') return
  // DOMContentLoaded and load have both already fired by now
  document.dispatchEvent(new Event('DOMContentLoaded'))
  window.dispatchEvent(new Event('load'))
}

Dispatching a synthetic load is safe here because the real one has already happened - no handler gets it twice, and a script replayed before the real load (a fast worker) still receives the genuine event.

An alternative, if a synthetic event is judged too blunt: warn when a replayed script assigns window.onload, naming the script, so the failure is visible. I would rather it worked.

Not filing this as a PR because the app-side workaround is cheap and the shape of the fix is a design call for the host: sasjs/minimal-seed-app now starts on DOMContentLoaded/immediately, which works in both directions. Other apps will keep hitting it.

Version

@sasjs/cli 6.27.3, Chromium 153 (headless), Linux. Found while adding a mockWeb target to the minimal seed app: https://github.com/sasjs/minimal-seed-app/pull/29

Ngôn ngữ chính
TypeScript
Star
41
Fork
6
Merge trung bình
3 giờ 46 phút
Pull request đã merge (30 ngày)
86

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của sasjs/cli

Tất cả issue của sasjs/cli

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.