티스토리 뷰
execSync
Node Buffer 문제 (업데이트)
간단하게 업데이트 과정은 다음과 같습니다.
문제:
node_modules
에 firebase
가 추가 될 시
데스크탑 앱 자동 업데이트가 진행되지 않습니다.
=> execSync(XCopy ... ... )
까지 실행되고 그 이후 상황이 실행되지 않습니다.
업데이트 부분의 기존 파일과 교체 부분에서 문제가 발생했습니다.
원인:
**firebase
의 Buffer
크기(Node Buffer 란)가 커서 execSync
에서 받아드리지 못해서 생기는 문제**
(exec
의 기본 버퍼 사이즈는 200k 입니다.)
해결책:
1. XCopy
를 parent process와 분리하여 실행 ({detached: true}
사용)
- 실행 과정(
cmd
창)이 보입니다.
2. XCopy
후 npm i
합니다.(내부에서 node_modules
생성)
⇒ 기본적으로 node_modules
를 가지고 있지 않고 파일을 옮긴 후 node_modules
만들기
- Github에 올라가는
package.json
에는firebase
빼야 합니다. node
가 설치 되지 않은 컴퓨터에서는 동작하지 않습니다.
3. maxBuffer
옵션 사용
maxBuffer: Largest amount of data in bytes allowed on stdout or stderr.
- stdout, stderr 값을 어느 정도까지 해야할 지 의문
stdout or stderr 값 파악하는 방법
1. Terminal 사용
$ls -l ${파일/폴더 명} //파일, 폴더들의 정보 출력
ex) -rw-r--r-- 1 g w paeng 197121 816 Jul 8 2023 package.json
816 / 1024 * 1024 의 값이 해당 값입니다.
2. 내부 코드 사용
const { execSync } = require('child_process');
try {
const stdout = execSync('your_command'); // 2>&1을 사용하여 stderr도 stdout으로 리다이렉트합니다.
console.log('stdout:', stdout.toString());
} catch (error) {
console.error('stderr:', error.stderr.toString());
}
대략 firebase
에서 가장 큰 것이 5.xxMB
정도 했으니10MB({ maxBuffer: 1024 * 1024 * 10 })
로 설정하면 될 것 같아 다음과 같이 적용하였습니다.
4. try & catch
사용
문제가 생기는 Xcopy
쪽에 try & catch
를 적용하면 동작합니다.
- 그냥 넘어가는 부분이 있기 때문에 확인 필요
const tmp_command = `Xcopy "${before_folder}" "${after_folder}" /E /H /C /I /y /r`;
try {
let result = require('child_process').execSync(tmp_command);
} catch (error) {
console.error("error :" error);
}
5. spawn
사용
spawn
사용에 앞서 exec
와 비교부터 해보겠습니다.
exec: spawn 매서드를 이용하여 Shell을 실행시키고 해당 Shell에서 명령어 실행
- Shell에서 제공하는 기능 이용 가능
- 프로세스 간 데이터 통신에 이용되는 방식: Buffered
- 자식 프로세스의 데이터를 차곡차곡 쌓아 한번에 전달하기 때문에 하나의 콜백에서 모든 수신이 가능
spawn: 새로운 프로세스를 띄워 명령어 수행
- 프로세스 간 데이터 통신에 이용되는 방식: Stream
- 실시간으로 데이터를 수신할 수 있어야하기 때문에 이벤트 등록 방식으로 데이터를 주고 받음
문제가 발생하는 부분이 XCopy
명령어가 필요한 부분입니다.spawn
이 Buffer에 상관없지만 실시간, 쉘 필요하기 때문에 exec
를 사용하게 되었습니다.
마치며
다음과 같이 3번과 4번을 혼합하여 사용하는 방법으로 결정을 하게되었습니다.
const tmp_command = `Xcopy "${before_folder}" "${after_folder}" /E /H /C /I /y /r`;
try {
let result = require('child_process').execSync(tmp_command, {maxBuffer: 1024 * 1024 * 10});
} catch (error) {
console.error("error :" error);
}
1번, 2번 해결책을 생각했을 때는 Buffer
문제라는 것도 파악하지 못했습니다.
(에러 메세지도 나오지 않았다....)
그래도 하나하나 하다보니 문제를 해결하게 되었습니다. 그냥 다양한 방법으로 부딪쳐야 겠습니다.
긴 글 읽어주셔서 감사합니다.
'Tip and Error' 카테고리의 다른 글
Flutter 웹뷰 뒤로가기 (w. Webview_flutter) (2) | 2024.03.26 |
---|---|
앱 배포(Android, iOS) (0) | 2024.03.03 |
Mac 데스크탑앱 만들기 (2) | 2024.03.01 |
[업데이트 에러] 경로에 빈칸 있는 경우, 특수 문자 있는 경우 (0) | 2024.02.25 |
flutter 아이콘 및 앱 이름 수정 (0) | 2024.02.24 |