패키지 만들기
모듈 시스템 이해
- 모듈 시스템이 등장한 이유
- 최초 JS는 하나의 파일에 모든 기능을 담아야 했다
-> 파일을 분리해서 포함하는 모듈이 없었기 때문
- 브라우저에서 모듈을 이해할 수 없었음
- ESM 등장 전까지 존재하던 CJS, AMD, UMD 방식은 결국 브라우저가 이해하기 위해서는 번들링을 통해 하나의 파일로 만들어 주는 과정이 필요했다
- ES6 이후 ESM 방식이 등장하기 전까지 브라우저는 모듈을 바로 이해할 수 X
- 모듈 시스템 종류
- CJS (CommonJS) -> 서버 사이드에서 사용 / 동기적 작동
- AMD (Asynchronous Module Definition) -> 클라이언트에서 주로 사용 / 비동기적 작동
- UMD (Universal Module Definition) -> CJS와 UMD를 함께 사용하기 위해 등장
- ESM (ECMASCript Module)
- 추가 시나리오
- ESM을 지원하지 않는 브라우저는 지원하지 않을 예정 + 파일이 많지도 않다
=> 번들링을 하지 않고 모듈을 배포해서 사용할 수도 있긴 함
=> 하지만, 웹 최적화를 위해 코드 스플리팅, 주석 자동 제거, 트리 쉐이킹 등과 같은 기능이 필요하므로 번들링을 하는 것이 좋아 보임
모듈 설정의 기본
npm init
명령으로 package.json
생성
- package.json 설정
- name : 모듈의 이름
- main : 모듈을 사용할 때 진입점이 되는 위치 / 즉, import 할 때 기준이 되는 위치
- module
- ESM (ECMAScript Module) 감지를 위한 번들러 도구에서 사용하는 옵션
- ES6 모듈 버전을 직접 가져오기 위한 역할
.mjs
확장자 / .js
확장자 사용
- refs : stackoverflow
- types
- 모듈을 typescript로 사용할 수 있도록 제공하는 스크립트
*.d.ts
확장자를 지정
- refs : stackoverflow
- svelte
- rollup-plugin-svelte / svelte-loader가 소스파일을 찾는데 사용
- 해당 속성을 지정하면 main, module보다 우선적으로 파일을 찾게된다
-> 비 svelte 사용자가 모듈을 사용하려면 오류가 발생할 수 있음 (비 ts 사용자도 포함)
- 즉, 해당 속성보다는 번들링된 js를 main에 위치시켜 사용하는 것이 더 범용성을 가질 수 있다
- refs : stackoverflow / rollup-plugin-svelte
local 패키지 테스트 방법
[ npm link ]
- npm link의 원리
- 서로 다른 두개의 패키지를 로컬 컴퓨터 내에서 연결
- global하게 사용할 수 있는 symlink를 생성한 뒤, 해당 symlink를 원하는 곳에서 연결하는 원리
- 구분
패키지 A
: 내가 만들고 있는 npm 패키지
패키지 B
: 패키지 A를 import해서 테스트 해볼 패키지
- 적용 흐름
패키지 A
의 최상단에서 npm link
명령으로 symlink
를 생성
-> /usr/local/lib/node_modules
에 패키지 A
의 모듈 이름
으로 폴더가 생겨서 전역으로 등록
패키지 B
의 최상단 경로에서 npm link {패키지 A의 모듈 이름}
으로 전역경로에 존재하는 패키지를 연결
-> 전역으로 생성했던 패키지 A
와 연결되어서, 패키지 B
에
- 실제 적용
- 상황 :
svelte-app
패키지에서 test-harmony-board
패키지를 사용하려 함
- 적용
npm link
명령을 통해 global symlink 생성
global symlink
와 연결한 뒤, 실제 node_modules
에 포함된 패키지 확인
svelte 관련
- svelte에서
<script context="module"> </sript>
를 통한 module 사용
- rollup 관련 라이브러리
@rollup/plugin-node-resolve
- node_modules에서 써드파티 모듈을 사용하는 용도로 사용
- npm docs
@rollup/plugin-commonjs
- CommonJS 모듈을 ES6으로 변환하는 롤업 플러그인
- npm docs
rollup-plugin-terser
- 생성 된 es 번들을 최소화하기위한 롤업 플러그인 후드 아래에서 terser 를 사용
- npm docs
@rollup/plugin-url
- 파일을 데이터 URI 또는 ES모듈로 가져오는 롤업 플러그인
- npm docs
@rollup/plugin-image
- JPG, PNG, GIF, SVG 및 WebP 파일을 가져 오는 롤업 플러그인
- npm docs
rollup-plugin-typescript2
- 타입스크립트를 지원하기 위한 플러그인
(rollup-plugin-typescript
은 deprecated)
- npm docs
rollup-plugin-peer-deps-external
- peerDependency로 설치된 라이브러리의 코드가 번들링된 결과에 포함되지 않고, import 구문으로 불러와서 사용할 수 있게 해주는 플러그인
- npm docs
rollup-plugin-sourcemaps
- rollup으로 번들하기 전에 소스 맵으로 파일을 변환에 사용되는 플러그인
- npm docs
@rollup/plugin-babel
- rollup에서 babel 을 사용 할 수 있게 해주는 플러그인입니다.
(rollup-plugin-babel
은 deprecated)
- npm docs
문제 & 해결 상황
- 번들링 파일이 아닌 src밑에 있는 소스를 자꾸 참조한다 ?
package.json
의 svelte
필드 때문
tsconfig.json
의 compilerOptions
> module : commonjs
때문
- 모듈을 export 해서 실제로 사용해보니 undefined ?
rollup.config.js
에서 output format
을 iife
-> umd
로 변경 후 해결
- 번들링된 파일을 알아보기가 힘들다
rollup-plugin-terser
에 포함된 terser
적용을 끄자