728x90

Package-lock.json 이 생성되는 이유

Package.json에서 Dependency versioning을 할때 명확히 버전을 명시 해주지 않을때가 있기때문에 생성된다.

Package.json의 Dependencies의 역할은 패키지들의 릴리즈 버전 추적 및 해당 버전 install에 있다.

즉, 서로 다른 환경에서 package를 설치할때 패키지들이 sementic versioning을 명확히 지키더라도 다른 package를 설치하면서 하위호환이 안맞는 경우가 생길 수 있다. (버전이 올라가면서 특정 모듈 함수가 deprecated되었을때가 대표적)

 

이런 상황을 해결하기 위해 필요한 파일이 바로 package-lock.json 이다. package.json에는 모호하게 적혀있던 package 버전이 package-lock.json에는 설치되어야 할 버전이 명확히 명시되어있다.

 

 

package-lock.json이 존재할 때 npm install을 실행할 시 더 이상 package.json을 참조하지않고 해당 package-lock.json 파일을 참조하여 package를 설치한다.

 

 

 

 

https://junwoo45.github.io/2019-10-02-package-lock/

'Webpack' 카테고리의 다른 글

Package.json dependencies versioning  (0) 2021.07.27
Bundle Diet  (0) 2021.07.26
Webpack 이란?  (0) 2021.01.15
728x90

Semeantic Versioning(SemVer. 유의적 버전)

버전 번호를 어떻게 정하고 올려야 하는지를 명시하는 규칙과 요구사항을 제안한다.

공개 API를 정의하고, 버전 번호를 올리는 방식을 통해 API가 어떻게 바뀌는지 표현한다.

버전을 X.Y.Z (주.부.수) 형식으로 정한다. (Major,Minor,Patch)

API에 영향이 없는 버그 수정은 수(修)버전을 올리고, API가 호환되면서 바꾸거나 추가하는 경우에는 부(部)버전을 올리고, API가 호환되지 않는 변경이라면 주(主)버전을 올린다.

 

Dependency Versioning

Package.json의 Dependency들의 versioning은 위의 SemVer의 규칙을 따른다.

  • 1.2.3 : v1.2.3 과 일치해야한다.
  • >1.2.3 : v1.2.3보다 높아야한다. 만약 v1.2.4가 없다면 v1.2.5를 찾고 v1.2.5도 없다면 v1.2.6을 찾는 방식.
  • >=1.2.3 : v1.2.3보다 같거나 높아야한다.
  • <1.2.3 : v1.2.3보다 낮아야한다.
  • <=1.2.3 : v1.2.3보다 같거나 낮아야한다.
  • ~1.2.3 : v1.2.3과 가장 가까운 버전
    • 현재 지정한 버전의 마지막 자리(수) 내의 범위에서 자동 업데이트한다.
    • 위의 상황은 1.2.3<= x < 1.3.0 중 가장 1.2.3과 가까운 버전
  • ^1.2.3 : v1.2.3과 호환이 되는 버전
    • api의 주버전이 바뀌면 API의 호환성이 깨지게되고 부,수 버전은 하위호환성을 지킨다는 SemVer의 특성을 지키고 있다는 가정하에 사용한다 .
    • 현재 지정한 버전의 첫번째 자리 (주) 내의 범위에서 자동 업데이트한다. 
    • 위의 상황은 1.2.3 <= x < 2.0.0 중 가장 최신버전

'Webpack' 카테고리의 다른 글

Package-lock.json  (0) 2021.07.27
Bundle Diet  (0) 2021.07.26
Webpack 이란?  (0) 2021.01.15
728x90

Browser에서 Javascript 파일 실행과정

 

같은 용량이더라도 이미지는 파일을 다운로드한 후 디코딩만 하면되지만 JS를 실행하기위해서는 위와같이 작업단계가 많으므로 JS 실행이 이미지 로딩보다 오래걸리게된다.

브라우저에서 JS실행을 최적화 하기위해서 번들 최적화는 매우 중요하다.

 

1. 원인 찾기

Webpack을 기준으로 Bundle 분석 도구로는 Webpack Analyse, Webpack Visualizer, Webpack Bundle Analyzer 3개가 있다.

Webpack Bundle Analyzer가 용량별로 시각화를 해주기때문에 어떤 라이브러리가 많이 사용되고 있는지 알 수있고 사이드바를 이용해 검색과 필터링도 가능하다사용하기 쉽고 기능이 좋다.

같은 라이브러리이지만 버전이 다른경우

  • npm이 dependency conflict를 해결하는 특성때문이다. npm은 라이브러리간 관계를 검색하고 필요한 라이브러리를 다운받는다. 이 때 dependency가 같은 라이브러리를 참조하지만 이 라이브러리의 버전이 다르다면 해당 버전을 모두 설치한다. 각 library별로 가상 환경의 node_modules를 이용하기 때문에 충돌이 없다. 
    • browserfy는 직접 사용자에게 어떤 버전을 설치할지 물어본다.
  • node_modules의 용량이 과도하게 커질 수 있다.


2. 라이브러리 중복 줄이기

  • node_modules의 용량이 과도하게 커지는 문제를 해결하기위해 npm은 라이브러리들이 시멘틱버전(semver)을 지킨다고 가정한다. major 버전이 바뀌지 않는한 더 높은 버전을 사용해도 문제가 생기지 않는다고 가정
  • npm dedupe 명령어로 중복된 모듈을 지워준다.
  • 특정 라이브러리가 다양한 버전의 라이브러리가 있다면 webpack의 resolve.alias기능을 이용하여 특정 라이브러리만 사용하도록한다.
    • lodash와 같은 라이브러리에는 다양한 라이브러리가 있다는 것이다. (lodash-es, lodash.get, lodash.isPlainObject, ...)  
    • {
        resolve: {
          alias: {
            	'lodash-es':'lodash',
              'lodash.get':'lodash/get',
              'lodash.isPlainObject':'lodash/isPlainObject'
          }
        }
  • tree shaking을 지원하지 않는 라이브러리의 경우(lodash), lodash-es를 쓰거나, babel-lodash-plugin을 이용해 사용중인 부분만 가려낼 수 있다.
  • 같은 기능을 하는  라이브러리의 경우 낮은 용량의 라이브러리를 찾아 사용한다.
    • webpack은 브라우저와 node환경을 최대한 맞추기위해 polyfill을 추가할 수 있다. 이로인해 라이브러리의 자체용량이 적어도 polyfill이 추가되어 느려질 때도 있다.
    • node-rsa 라이브러리의 경우 node.js의 지원만 생각하고 만들어진 라이브러리이기 때문에 브라우저로 넘어갈 경우 polyfill로 cryto, Buffer, big number등의 polyfill이 추가된다. (100kb)
    • bundle phobia에서 미리 용량 및 dependency를 확인한다. (export analysis)

 

라이브러리를 만들 때

tree-shaking

불필요한 코드를 정적분석을 통해 제거하는 기술. 정말 사용중인 코드만 bundle에 포함되기때문에 더 가벼운 번들을 만들 수 있다.

 

tree shaking이 어려울때

//module boo
export const a = foo();
export const b = bar();

//user
import {b} from './boo';

이때 과연 boo의 a를 bundle에서 빼도 될까? 정답은 그럴수도 있고 아닐수도 있다

// a를 제거해도 될때
function foo(){
  return 'Hello World';
}

export const a = foo();
export const b = bar();


// a를 제거해서는 안될때
let count = 0;
const foo(){
  count++;
  return count;
}

export const a = foo();
export const b = bar();

위의 코드의 경우 a를 제거해도 동작이 달라지지 않지만 밑의 코드의 경우 a를 제거하면 동작이 달라질 수 있다. 이 때를 side effect가 있다고 한다. 

tree-shaking을 하려면 side-effect가 없을때만 가능하다

이 side-effect판별능력은 bundler에 따라 다르다. webpack은 별로 안좋은편

 

 

webpack의 side-effect 판별 향상방법

webpack에게 side effect여부를 알려줘야한다. 이는 webpack에 sideEffects 필드를 설정하면된다.

이 필드가 있을때만 treeshaking을 시도한다. side effect를 발견하거나 분석이 어려운경우 tree shaking을 하지않는다.

 

프로덕션 빌드에서는 terser의 도움을 받아 deadcode를 삭제할 수 있다.

terser도 side effect의 유무를 판단하여 코드를 지운다. 이 때 terser의 판단을 돕는것이 pure annotation이다.

pure annotation이 붙어있으면 side effect가 없다고 판단한다.

const a = /*#__PURE__#*/ foo();
const b = /*#__PURE__#*/ bar();
console.log(b);


//prduction
const b =bar();
console.log(b);

side effect를 발생할때 이를 발견할 ㅅ수 있는방법은 무엇일까?

webpack의 stats (nextjs에서는 webpack-stats-plugin)를 사용한다.

 

라이브러리 영향 줄이기

라이브러리 용량을 더이상 줄이는 것이 어렵다면 무거운 라이브러리의 영향을 최소화한다.

이 때 bundle의 chunk를 나누도록한다.

 

단일 chunk일때 하나의 라이브러리가 추가되면 모든 페이지의 용량이 커지게된다.

 

dynamic import

용량이 큰 라이브러리를 필요할때만 받는 기법

import dynamic from 'next/dynamic';

const pageA = dynamic(()=> import('./PageA'));
const pageB = dynamic(()=> /*webpackPrefetch: true*/ import('./PageB'));

webpack magic comment를 사용하면 prefetch기능을 사용할 수 있다. prefetch를 이용하면 여유로운 시간에 미리 받아둔다. 

 

 

'Webpack' 카테고리의 다른 글

Package-lock.json  (0) 2021.07.27
Package.json dependencies versioning  (0) 2021.07.27
Webpack 이란?  (0) 2021.01.15
728x90

bundler

webpack bundler의 역할

bundler를 쓰지않는다면?

  • 브라우저에서 페이지를 load 할때 많은 파일들이 로드 된다. 일반적으로 서버와의 접속이 많을수록 어플리케이션이 느려지게되는 문제점이 생기기때문에 매우 비효율적이다.
  • bundler가 없다면 아래에서 처럼 요청을 보낼때마다 해당 페이지에서 사용하는 resource(js,html,jpg,css)마다 각각 하나의 파일 단위로 로드하기 때문에 매우 비효율적이다. 
    • 만약 하나의 파일을 로드하는데 2초가 걸리고 resource가 총 5개 있다고하면 하나의 페이지를 여는데 10초가 걸리게 된다. (비동기 가정)

 

bundler 이란

  • 위에서의 비효율성을 해결하기위해 소프트웨어 및 일부 하드웨어와 함께 작동하는 데 필요한 모든 resource을 포함하는 패키지를 만들어 하나의 파일로 관리하도록 도와주는 라이브러리이다.
    • 위의 5개의 resource가 존재하는 페이지를 로드하는 상황에서 걸리는 시간은 2~3초 정도로 줄게 될 것이다.
  • 특히 서로다른 패키지들이 같은 이름과 같은 변수를 사용하면서 어플리케이션이 깨지게되는데 이를 해결해 준다.
    •  
    • //index1.html <!DOCTYPE html> <html> <head> <title>Document</title> <script> let duplicated = 1;</script> </head> <body> </body> </html> //index2.html <!DOCTYPE html> <html> <head> <title>Document</title> <script src="./index1.html"> let duplicated = 1;</script> // 변수 중복지정으로 인한 에러 발생 </head> <body> </body> </html>
    • 기본적으로 import시 모듈 개념이 잡혀있지않다. import 'asdf.js'
      • import마다 index.html에서 < script type="module">import asdf from 'asdf.js' </script>을 해줘야한다.
        • 하지만 webpage에서는 매 import되는 자원마다 download를 하게되어 load가 많이 생기게된다. --> 하나로 묶어주고싶다.
    • 여러개의 파일을 묶어주는 도구 --> webpack, broserify,parcel등이 해당
  • 여러가지 모듈들을 몰아넣고 성능향상을위해 다시 분리할 수 있다. 이외에도 최적화등을 위한 다양한 확장 기능들이 존재

 

 

'Webpack' 카테고리의 다른 글

Package-lock.json  (0) 2021.07.27
Package.json dependencies versioning  (0) 2021.07.27
Bundle Diet  (0) 2021.07.26

+ Recent posts