2024 01 23
2024-01-23¶
2024-01-23 코드리뷰¶
js 빌드/번들링¶
참고: https://github.com/joelonsw/TIL/blob/master/2023-kakao-1st/2023-12/2023-12-15.md
참고: https://velog.io/@ye-ji/%EB%B2%88%EB%93%A4%EB%A7%81%EA%B3%BC-%EB%B9%8C%EB%93%9C-%EC%8B%9C%EC%8A%A4%ED%85%9C
[번들러]
- 해결하고자 하는 문제
- 전역 범위를 갖는 수백개의 자바스크립트 파일 중복 선언
- 수백개에 달하는 자바스크립트 파일로 인한 느린 로딩
- 수동적인 웹개발 루틴 (파일/이미지 압출, css pre-processing 등)
- 번들러란...
- 웹 어플리케이션을 구성하는 모든 자원을 하나의 파일로 묶는 도구
- ex) webpack(리액트), rollup(옵트인 팝업)
- 모듈 번들러
- 모듈 : 특정 기능을 갖는 작은 코드 단위 (
JS,HTML,CSS,images,font)- 수십개의 파일을 하나의
JS파일로 압축/축소
- 수십개의 파일을 하나의
- 모듈 : 특정 기능을 갖는 작은 코드 단위 (
[옵트인 팝업에서 번들링]
- Rollup을 사용한 JS 모듈 번들러
// 트랜스파일링을 통해 호환성 확보 const babel = require('rollup-plugin-babel'); // 노드 모듈 어디에 있는지 const resolve = require('rollup-plugin-node-resolve'); import {version} from './package.json'; // 위 주석 const libraryBanner = `/* * Name: popup * Version: v${version} */ `; // IIFE: const IIFE_CONFIG = { // Entry Point input: 'src/index.js', // Output File output: [ { file: 'dist/popup.js', format: 'iife', name: 'Popup', globals: { Popup: 'Popup' }, banner: libraryBanner } ], plugins: [ // node_module 디렉토리 찾기 resolve({ browser: true, }), // ES5 syntax로 변경 babel({ presets: ['@babel/preset-env'] }) ], }; // UMD: const UMD_CONFIG = { input: 'src/index.js', output: [ { file: 'dist/popup.umd.js', format: 'umd', name: 'Popup', globals: { Popup: 'Popup' }, banner: libraryBanner } ], plugins: [ resolve({ browser: true, }), babel({ presets: ['@babel/preset-env'] }) ], }; module.exports = [ IIFE_CONFIG, UMD_CONFIG ];
-
IIFE (Immediately Invoked Function Expression)
- Self Executing Function으로 함수가 직접 바로 호출되어 Script 태그에서 쓰일 수 있도록 함.
- 모듈 시스템이라기 보다는 디자인 패턴에 가까움 (모듈 시스템 등장 전에 사용되던 패턴)
- 바로 정의되자 마자 호출되어 전역 스코프를 오염시키지 않도록 하는 목표
-
UMD (Universal Module Definition)
- 다양한 모듈 시스템인 AMD, CJS 등 올인원으로 사용할 수 있음
js 모듈 시스템¶
- JS가 브라우저 안의 언어였다보니... 밖으로도 빼보고, 안에서도 잘쓰이게 수정해보고, 모듈화해보고 등등의 시도들이 역사적으로 있었던 것 같음
- CJS: JS를 브라우저뿐만이 아니라 범용언어로 사용하고자 만들어진 그룹 (Node.js, 동기적인 특징으로 서버사이드에서 사용하기 용이)
- AMD: 브라우저 안에서의 동작을 중점을 둔 그룹임 (브라우저, 비동기적인 특징으로 클라이언트 사이드 개발에 용이)
- UMD: AMD, CommonJS 호환을 위해 해결. 브라우저/node 환경 둘 다 사용될 수 있도록
ShadowDOM을 활용한 독립된 스타일 적용¶
참고: https://github.com/joelonsw/TIL/blob/master/2023-kakao-1st/2023-11/2023-11-22.md
- 숨겨진 DOM 트리로써, 진짜 DOM에 붙음
- Shadow DOM이 독립적으로 컨트롤하도록 지원
Scala/Play에서 CorsAction 만들기¶
참고: https://github.com/joelonsw/TIL/blob/master/2023-kakao-1st/2023-12/2023-12-04.md
- 요약하자면...
- CORS의 해결책은 결국 서버에서 해당 Origin은 우리 서버랑 합의된 Origin 이니까~ 허용 헤더 끼워서 보내드릴게요! 라고 해줘야 함
Access-Control-Allow-Origin
- CORS의 해결책은 결국 서버에서 해당 Origin은 우리 서버랑 합의된 Origin 이니까~ 허용 헤더 끼워서 보내드릴게요! 라고 해줘야 함
- ActionBuilder 상속 받아서 CorsAction 만들기
- 브라우저는 타 Origin API를 찌를때 Origin 헤더를 http request에 포함
- Origin이 있다면 -> 이미 등록된 친구인지 검사
- Origin이 없다면 -> 같은 Origin에서 요청온 것이므로 그냥 API 처럼 동작 수행
override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = { request.headers.get("origin") match { case Some(origin) => if (corsAllowService.isAllowedOrigin(origin)) { block(request).map { result => result.withHeaders( HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> origin, HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "POST, GET, OPTIONS", HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent", HeaderNames.ACCESS_CONTROL_MAX_AGE -> Integer.toString(60 * 60 * 24) ) } } else { throw new ForbiddenException } case None => block(request) } }
- 브라우저는 타 Origin API를 찌를때 Origin 헤더를 http request에 포함