TIL

TIL 2022-01-12 webpack-hot-middleware, webpack-dev-middleware, FFMPEG.WASM

강에 뜨는 달 2022. 1. 12. 22:23

React로 변환하면서 react Dev server로 express을 사용하려고 했다.

Shared Array Buffer를 사용하기 위해서 Response 헤더를 설정해야했다.

 

 

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

사실 webpack 내 devServer에서도 header을 설정할 수 있어서 굳이 할 필요는 없었다.

 

webpack.config.js의 devServer에

devServer: {
		headers: [
			{
				key: 'Cross-Origin-Opener-Policy',
				value: 'same-origin',
			},
			{
				key: 'Cross-Origin-Embedder-Policy',
				value: 'require-corp',
			},
			{
				key: 'Access-Control-Allow-Origin',
				value: 'researchgate.net',
			},
			{
				key: 'Access-Control-Allow-Methods',
				value: 'GET,PUT,POST,DELETE',
			},
			{
				key: 'Access-Control-Allow-Headers',
				value: 'Content-Type',
			},
		],
	},

를 통해 header을 설정할 수 있다.

 

사실 webpack-dev-server가 express 기반으로 만들어졌다.

devServer으로는 부족할때 별도로 Express를 개발용 웹서버로 사용하는 것을 고려하는 것이 맞다.

 

 

webpack-dev-middleware

webpack-dev-middleware은 웹팩 번들과 같이 사용하는 express 미들웨어이며 웹팩에서 output한 파일을 처리할 수 있도록 해준다.

 

const webpack = require("webpack");
const middleware = require("webpack-dev-middleware");
const compiler = webpack({
  // webpack options
});
const express = require("express");
const app = express();

app.use(
  middleware(compiler, {
    // webpack-dev-middleware options
  })
);

app.listen(3000, () => console.log("Example app listening on port 3000!"));

이런 식으로 설정하며

webpack-dev-middleware의 옵션으로는 위와 같다.

 

Hot Module Replacement

HMR이라고도 하는데 이는 모듈 전체를 다시 로드하지 않고 실행되는 동안 변경된 사항만 갱신해주고 브라우저에서 바로바로 업데이트를 해준다.

 

webpack-dev-server에서는 hot이라는 key를 통해 설정이 가능하고 기본적으로 활성화되어있다.

 

webpack-dev-middleware을 통해서 커스텀 웹서버를 구성한다면 webpack-hot-middleware를 통해 별도로 활성화해주어야한다.

 

hot-middleware을 사용하는 방법으로는

 

plugins: [
    // OccurrenceOrderPlugin is needed for webpack 1.x only
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    // Use NoErrorsPlugin for webpack 1.x
    new webpack.NoEmitOnErrorsPlugin()
]

webpack config의 plugin에 new webpack.HotModuleReplacementPlugin()을 추가하고

 

 

 

app.use(require("webpack-hot-middleware")(compiler));

구성한 Express 서버인 server.js에 dev-middleware와 동일한 compiler을 사용한 webpack-hot-middleware을 추가한다.

 

그리고 리액트 index.tsx란에서

 

ReactDom.render(
	<React.StrictMode>
		<App />
	</React.StrictMode>,
	document.getElementById('root')
);
if (module && module.hot && module.hot.accept) {
	module.hot.accept();
}

이런 식으로 module.hot.accept()을 실행하도록 해주었다.

 

module.hot에 자주 사용하는 기능으로는

accept()

decline()

dispose()가 있는데,

 

 

module.hot.accept(
  dependencies, // Either a string or an array of strings
  callback, // Function to fire when the dependencies are updated
  errorHandler // (err, {moduleId, dependencyId}) => {}
);

module.hot.accept(
  errorHandler // Function to handle errors when evaluating the new version
);

accept는 주어진 dependency에 대해 update을 승인하고 dependency가 업데이트되고 난 후 실행되는 callback을 넣어줄수 있다.

 

errorHandler만 인자로 주는 경우는 스스로에 대한 업데이트를 한다.

 

module.hot.decline(
  dependencies // Either a string or an array of strings
);

module.hot.decline();

decline은 이름에서부터 알수 있듯 dependency에 대한 update를 거부한다.

 

module.hot.dispose((data) => {
  // Clean up and pass data to the updated module...
});

dispose는 모듈을 교체할떄 실행되는 핸들러를 추가한다. 현재 만든 persistance resource를 제거하는데 쓰이고 필요한 경우 새 모듈에 data를 넘길 수 있다.

https://github.com/webpack/webpack-dev-middleware#readme

 

GitHub - webpack/webpack-dev-middleware: A development middleware for webpack

A development middleware for webpack. Contribute to webpack/webpack-dev-middleware development by creating an account on GitHub.

github.com

https://github.com/webpack-contrib/webpack-hot-middleware

 

GitHub - webpack-contrib/webpack-hot-middleware: Webpack hot reloading you can attach to your own server

Webpack hot reloading you can attach to your own server - GitHub - webpack-contrib/webpack-hot-middleware: Webpack hot reloading you can attach to your own server

github.com

https://webpack.js.org/api/hot-module-replacement/

 

Hot Module Replacement | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

FFMPEG.WASM setProgress 오류

mp3와 사진을 mp4로 변환할떄

FFMPEG.WASM을 사용하면서 setProgress의 ratio가 0과 1일일때만 출력되고 그 이외에는 NaN이 출력되는 오류가 발생했다.

 

이는 ffmpeg/src/utils/parseProgress 에서의 코드 동작과 logger의 로그를 보면서 이해할 수 있었는데,

let duration = 0;
let ratio = 0;

const ts2sec = (ts) => {
  const [h, m, s] = ts.split(':');
  return (parseFloat(h) * 60 * 60) + (parseFloat(m) * 60) + parseFloat(s);
};

module.exports = (message, progress) => {
  if (typeof message === 'string') {
    if (message.startsWith('  Duration')) {
      const ts = message.split(', ')[0].split(': ')[1];
      const d = ts2sec(ts);
      progress({ duration: d, ratio });
      if (duration === 0 || duration > d) {
        duration = d;
      }
    } else if (message.startsWith('frame') || message.startsWith('size')) {
      const ts = message.split('time=')[1].split(' ')[0];
      const t = ts2sec(ts);
      ratio = t / duration;
      progress({ ratio, time: t });
    } else if (message.startsWith('video:')) {
      progress({ ratio: 1 });
      duration = 0;
    }
  }
};

parseProgress에서는 Duration의 값을 통해서 예상 시간과 ratio값을 구하는데, 문제는 사진의 경우에는 너무나 당연하게도? Duration 값이 존재하지 않는다.

 

따라서 N/A인 Duration인 경우에는 NaN의 ratio 값이 출력되었던 것이다. mp3와 사진이 인풋에 들어가는 위치를 바꿔줌으로써 해결했다. (mp3은 duration이 존재하기에)

 

https://github.com/ffmpegwasm/ffmpeg.wasm

 

GitHub - ffmpegwasm/ffmpeg.wasm: FFmpeg for browser and node, powered by WebAssembly

FFmpeg for browser and node, powered by WebAssembly - GitHub - ffmpegwasm/ffmpeg.wasm: FFmpeg for browser and node, powered by WebAssembly

github.com