Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/#575 스크립트를 로드하는 유틸 함수 구현 #576

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions frontend/src/features/youtube/remotes/loadIframeApi.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,24 @@
import { loadScript } from '@/shared/utils/loadScript';

// TODO: index.d.ts
declare global {
interface Window {
onYouTubeIframeAPIReady: () => void;
}
}

function load(cb: (err: Error) => void) {
const firstScript = document.getElementsByTagName('script')[0];
const script = document.createElement('script');

script.src = 'https://www.youtube.com/iframe_api';
script.async = true;
script.onerror = function () {
this.onload = null;
this.onerror = null;
cb(new Error(`Failed to load ${this.src}`));
};

if (firstScript) {
firstScript.parentNode?.insertBefore(script, firstScript);
} else {
document.head.appendChild(script);
}
}

function loadIFrameApi(): Promise<typeof YT> {
return new Promise((resolve, reject) => {
if (typeof window.YT === 'object') {
resolve(window.YT);
return;
}

load((error) => {
if (error) reject(error);
});
try {
loadScript('https://www.youtube.com/iframe_api');
} catch (error) {
reject(error);
}

window.onYouTubeIframeAPIReady = () => {
resolve(window.YT);
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/shared/utils/loadScript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const loadScript = (source: string): Promise<void> => {
const element = document.querySelector(`script[src="${source}"]`);

if (element) {
return Promise.resolve();
}

Comment on lines +2 to +7
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

같은 src로 동시에 여러번 loadScript를 호출하면 어떻게 되나요?

load중일 때에는 아직 element가 만들어지기 전이라서, 같은 script를 여러 개를 만들 것 같아요. flag를 두어서 중복생성하지 않도록 막아주는 게 좋을 것 같습니다

return new Promise((resolve) => {
const script = document.createElement('script');

script.async = true;
script.defer = true;
Comment on lines +11 to +12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

script.async = true; 만 있어도 될 것 같아요. (참고)

script.src = source;
script.onload = () => resolve();

Comment on lines +14 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
script.onload = () => resolve();
script.onerror = (error) => reject(error);

script 로드에 실패했을 때 에러 처리가 필요해 보입니다.

document.body.appendChild(script);
});
};
Loading