Hot Module Replacement

Hot Module ReplacementHotModuleReplacementPlugin을 통해 활성화된 경우, 해당 인터페이스는 import.meta.webpackHot프로퍼티 뿐만 아니라 module.hot프로퍼티 아래 노출됩니다. strict ESM에서는 import.meta.webpackHot만 사용할 수 있습니다.

일반적으로, 사용자는 인터페이스에 접근할 수 있는지 확인한 후, 작업을 시작합니다. 예를 들어, 업데이트된 모듈을 accept 하는 방법은 다음과 같습니다.

if (module.hot) {
  module.hot.accept('./library.js', function () {
    // 업데이트된 라이브러리 모듈로 작업을 수행하세요...
  });
}

// or
if (import.meta.webpackHot) {
  import.meta.webpackHot.accept('./library.js', function () {
    // 업데이트된 라이브러리 모듈로 작업을 수행하세요…
  });
}

지원되는 메서드는 다음과 같습니다...

Module API

accept

주어진 dependencies에 대한 업데이트를 수락하고 해당 업데이트에 반응하기 위해 callback을 실행합니다. 또한, 선택적 에러 핸들러를 연결할 수 있습니다.

module.hot.accept(
  dependencies, // 문자열 또는 문자열 배열
  callback, // 의존성이 업데이트될 때 실행할 함수
  errorHandler // (err, {moduleId, dependencyId}) => {}
);

// 또는
import.meta.webpackHot.accept(
  dependencies, // 문자열 또는 문자열 배열
  callback, // 의존성이 업데이트될 때 실행할 함수
  errorHandler // (err, {moduleId, dependencyId}) => {}
);

ESM import를 사용하면 dependencies에서 가져온 모든 심볼이 자동으로 업데이트됩니다. 참고: 의존성 문자열은 importfrom 문자열과 정확히 일치해야 합니다. 경우에 따라 callback을 생략할 수 있습니다. callback에서 require()를 사용하는 것은 여기에서 의미가 없습니다.

CommonJS를 사용할 때 callback에서 require()를 사용해서 의존성을 수동으로 업데이트해야 합니다. callback을 생략하는 경우도 있습니다.

errorHandler for accept

(err, {moduleId, dependencyId}) => {}

  • err: ESM 의존성을 사용할 때 두 번째 인수 또는 의존성 실행 중에 콜백에 의해 발생한 에러.
  • moduleId: 현재 모듈 id.
  • dependencyId: (첫 번째) 변경된 의존성의 모듈 id.

accept (self)

자체적으로 업데이트를 수락합니다.

module.hot.accept(
  errorHandler // 새 버전을 평가할 때 에러를 처리하는 함수
);

// 또는
import.meta.webpackHot.accept(
  errorHandler // 새 버전을 평가할 때 에러를 처리하는 함수
);

모듈 또는 의존성이 업데이트되면, 부모에게 알리지 않고 이 모듈을 폐기하고 재평가 할 수 있습니다. 이것은 이 모듈에 내보내기가 없는 경우(또는 내보내기가 다른 방식으로 업데이트되는 경우) 의미가 있습니다.

이 모듈(또는 의존성)의 평가에서 예외가 발생하면 errorHandler가 실행됩니다.

errorHandler for self accept

(err, {moduleId, module}) => {}

  • err: 새 버전을 평가할 때 발생한 에러.
  • moduleId: 현재 모듈 id.
  • module: 현재 모듈 인스턴스.
    • module.hot: 에러가 발생한 모듈 인스턴스의 HMR API를 사용하도록 허용합니다. 일반적인 시나리오는 스스로 그것을 다시 수락하는 것입니다. 또한 데이터를 전달하기 위해 dispose 핸들러를 추가하는 것이 좋습니다. 에러가 발생한 모듈은 이미 부분적으로 실행되었을 수 있음으로, 일관성 없는 상태가 되지 않도록 주의하세요. module.hot.data를 사용하여 부분 상태를 저장할 수 있습니다.
    • module.exports: 오버라이드할 수 있지만, 프로덕션 모드에서 프로퍼티 이름이 손상될 수 있음으로 주의하세요.

decline

주어진 dependencies에 대한 업데이트를 거부하여 'decline' 코드로 업데이트가 실패하도록 합니다.

module.hot.decline(
  dependencies // 문자열 또는 문자열 배열
);

// 또는
import.meta.webpackHot.decline(
  dependencies // 문자열 또는 문자열 배열
);

업데이트 불가능으로 의존성에 플래그를 지정합니다. 이것은 의존성 내보내기 변경을 처리할 수 없거나 처리가 아직 구현되지 않은 경우 의미가 있습니다. HMR 관리 코드에 따라, 이러한 의존성(또는 허용되지 않는 의존성)에 대한 업데이트로 인해 일반적으로 전체 페이지가 다시 로드됩니다.

decline (self)

자체적으로 업데이트를 거부합니다.

module.hot.decline();

// 또는
import.meta.webpackHot.decline();

업데이트 불가능으로 모듈에 플래그를 지정합니다. 이는 이 모듈에 되돌릴 수 없는 사이드 이펙트가 있거나, 이 모듈에 대해 HMR 처리가 아직 구현되지 않은 경우 의미가 있습니다. HMR 관리 코드에 따라, 이러한 모듈(또는 허용되지 않은 의존성)에 대한 업데이트로 인해 일반적으로 전체 페이지가 다시 로드됩니다.

dispose (or addDisposeHandler)

현재 모듈 코드가 교체될 때 실행되는 핸들러를 추가합니다. 이것은 요청하거나 생성한 영구 리소스를 제거하는 데 사용해야 합니다. 업데이트된 모듈에 상태를 전송하려면, 주어진 data 파라미터에 추가하세요. 이 객체는 업데이트 후 module.hot.data에서 사용할 수 있습니다.

module.hot.dispose((data) => {
  // 데이터를 정리하고 업데이트된 모듈로 전달합니다.
});

// 또는
import.meta.webpackHot.dispose((data) => {
  // 데이터를 정리하고 업데이트된 모듈로 전달합니다.
});

invalidate

이 메서드를 호출하면 현재 모듈이 무효화 되고, HMR 업데이트가 적용될 때 이를 삭제하고 다시 생성합니다. 버블은 이 모듈의 일반 업데이트와 같습니다. 이 모듈은 invalidate를 자체 승인할 수 없습니다.

idle 상태에서 호출되면, 이 모듈을 포함하는 새 HMR 업데이트가 생성됩니다. HMR은 ready 상태로 들어갑니다.

ready 또는 prepare 상태에서 호출되면, 이 모듈은 현재 HMR 업데이트에 추가됩니다.

check 상태에서 호출되면, 이 모듈은 업데이트를 사용할 수 있을 때 업데이트에 추가됩니다. 사용 가능한 업데이트가 없으면 새 업데이트가 생성됩니다. HMR은 ready 상태로 들어갑니다.

dispose 또는 apply 상태에서 호출되면, HMR은 해당 상태에서 나온 후 이를 선택합니다.

Use Cases

Conditional Accepting

모듈은 의존성을 받아들일 수 있지만, 의존성 변경을 처리할 수 없는 경우 invalidate를 호출할 수 있습니다.

import { x, y } from './dep';
import { processX, processY } from 'anotherDep';

const oldY = y;

processX(x);
export default processY(y);

module.hot.accept('./dep', () => {
  if (y !== oldY) {
    // 처리할 수 없으며, 부모에게 전달
    module.hot.invalidate();
    return;
  }
  // 처리할 수 없음
  processX(x);
});

Conditional self accept

모듈은 자체 수용할 수 있지만, 변경 사항을 처리할 수 없을 때 자체를 무효화 할 수 있습니다.

const VALUE = 'constant';

export default VALUE;

if (
  module.hot.data &&
  module.hot.data.value &&
  module.hot.data.value !== VALUE
) {
  module.hot.invalidate();
} else {
  module.hot.dispose((data) => {
    data.value = VALUE;
  });
  module.hot.accept();
}

Triggering custom HMR updates

const moduleId = chooseAModule();
const code = __webpack_modules__[moduleId].toString();
__webpack_modules__[moduleId] = eval(`(${makeChanges(code)})`);
if (require.cache[moduleId]) {
  require.cache[moduleId].hot.invalidate();
  module.hot.apply();
}

removeDisposeHandler

dispose 또는 addDisposeHandler를 통해 추가된 핸들러를 제거합니다.

module.hot.removeDisposeHandler(callback);

// 또는
import.meta.webpackHot.removeDisposeHandler(callback);

Management API

status

hot module replacement 프로세스의 현재 상태를 검색합니다.

module.hot.status(); // 다음 문자열 중 하나를 반환합니다...

// 또는
import.meta.webpackHot.status();
StatusDescription
idle프로세스가 check 호출을 기다리고 있습니다
check프로세스가 업데이트를 확인하는 중입니다
prepare프로세스가 업데이트를 준비 중입니다 (예. 업데이트된 모듈 다운로드)
ready업데이트가 준비되어 사용 가능합니다
dispose프로세스는 교체될 모듈에서 dispose 핸들러를 호출합니다
apply프로세스가 accept 핸들러를 호출하고 자체 승인된 모듈을 다시 실행합니다
abort업데이트가 중단되었지만, 시스템은 여전히 이전 상태입니다
fail업데이트에서 예외가 발생했으며 시스템 상태가 손상되었습니다

check

업데이트를 위해 로드된 모든 모듈을 테스트하고, 업데이트가 있는 경우 이를 apply 합니다.

module.hot
  .check(autoApply)
  .then((outdatedModules) => {
    // outdated 모듈...
  })
  .catch((error) => {
    // 에러 catch
  });

// 또는
import.meta.webpackHot
  .check(autoApply)
  .then((outdatedModules) => {
    // outdated 모듈...
  })
  .catch((error) => {
    // 에러 catch
  });

autoApply 파라미터는 boolean이거나 호출될 때 apply메서드에 전달할 options일 수 있습니다.

apply

업데이트 프로세스를 계속합니다.(module.hot.status() === 'ready'인 동안)

module.hot
  .apply(options)
  .then((outdatedModules) => {
    // outdated 모듈...
  })
  .catch((error) => {
    // 에러 catch
  });

// 또는
import.meta.webpackHot
  .apply(options)
  .then((outdatedModules) => {
    // outdated 모듈...
  })
  .catch((error) => {
    // 에러 catch
  });

선택적 options 객체에는 다음 프로퍼티가 포함될 수 있습니다.

  • ignoreUnaccepted (boolean): 허용되지 않는 모듈에 대한 변경 사항을 무시합니다.
  • ignoreDeclined (boolean): 거부된 모듈에 대한 변경 사항을 무시합니다.
  • ignoreErrored (boolean): accept 핸들러, 에러 핸들러 및 모듈을 재평가하는 동안 발생하는 에러를 무시합니다.
  • onDeclined (function(info)): 거부된 모듈에 대한 알림
  • onUnaccepted (function(info)): 허용되지 않는 모듈에 대한 알림
  • onAccepted (function(info)): 허용된 모듈에 대한 알림
  • onDisposed (function(info)): 폐기된 모듈에 대한 알림
  • onErrored (function(info)): 에러 알림

info 파라미터는 다음 값 중 일부를 포함하는 객체입니다.

{
  type: 'self-declined' | 'declined' |
        'unaccepted' | 'accepted' |
        'disposed' | 'accept-errored' |
        'self-accept-errored' | 'self-accept-error-handler-errored',
  moduleId: 4, // 질문의 모듈.
  dependencyId: 3, // 에러의 경우: accept 핸들러를 소유한 모듈 id.
  chain: [1, 2, 3, 4], // 거부/허용/허용되지 않음의 경우: 업데이트가 전파된 체인.
  parentId: 5, // 거부된 경우: 거부하는 상위의 모듈 ic
  outdatedModules: [1, 2, 3, 4], // 허용된 경우: 오래되어 폐기될 모듈
  outdatedDependencies: { // 허용된 경우: 업데이트를 처리할 accept 핸들러의 위치
    5: [4]
  },
  error: new Error(...), // 에러의 경우: throw 된 에러
  originalError: new Error(...) // For self-accept-error-handler-errored:
                                // 에러 핸들러가 처리를 시도하기 전에 모듈에서 발생한 에러.
}

addStatusHandler

status의 변경을 수신할 함수 등록합니다.

module.hot.addStatusHandler((status) => {
  // 현재 상태에 반응...
});

// 또는
import.meta.webpackHot.addStatusHandler((status) => {
  // 현재 상태에 반응...
});

상태 핸들러가 Promise를 반환하면, HMR 시스템은 계속하기 전에 Promise가 해결될 때까지 기다립니다.

removeStatusHandler

등록된 상태 핸들러 제거.

module.hot.removeStatusHandler(callback);

// 또는
import.meta.webpackHot.removeStatusHandler(callback);

6 Contributors

sokraskipjacktbroadleybyzykwizardofhogwartssnitin315

Translators