- 전체
- 명
- 오늘 찾아주신 분
- 명
내가 진행하고 있는 프로젝트의 경우에는 일반적인 프로젝트의 구성과는 약간 다르게 되어있다.
Electron 과 Vue 를 조합했지만 Electron 이 권하고 있는 main - renderer 프로세스는 아니며, 폴더의 구조도 Electron > Vue 가 아니라 Vue > Electron 이 되어있다.
"왜 그랬을까?" 하면 추가 확장성을 위해서 Vue 를 메인으로 생각했기 때문이라고 하고 싶은데..(어차피 Electron 은 껍데기니까.) Electron-vue 라는 Boilerplate 를 사용하지 않고 처음부터 만들어 보느라 갖가지 내 로직 상으로는 이해 안되는 일이 발생하곤 했다.
그 중 대표적인 하나가 Webpack 을 통해서 Code Splitting 을 한 Chunk 애들이 파일은 있는데 net::ERR_FILE_NOT_FOUND 가 나는 것 이었다. Development 모드에서는 1도 에러나지 않던 아이들이 갑자기 어디로 갔는지 당황했다.
원인은 무엇일까... 하면서 크롬 개발자 콘솔을 확인해보는데 다음의 경우가 발생 되었다.
- 처음 로드 되는 애들은 상대경로로 접했어도 스크립트 태그로 박혀있기 때문에 절대경로로 잘 불러와진다. 처음 불러와진 아이들은 chunk 를 관리하는 스크립트와 index 관련 스크립트였다. 일단은 UI 가 보인다.
- 버튼을 누르면 해당 기능이 들어있는 스크립트를 불러온다. 이 때에는 상대 경로지만 '.' 이 빠지고 '/' 만 있어 루트 경로로 들어가버린다.
프로젝트 내에서 Production 과 Development 의 차이는 Electron 에서 BrowserWindow 를 실행할 때 loadFile 을 썼는가, loadURL 을 썼는가 의 차이이다. 물론 Development 는 즉각적인 변경을 알아보기 위해서 localhost 를 연결해 주었고, Production 은 Electron 자체 내 서버가 없으니 index 파일을 불러 실행을 시킨 것이다. 어차피 절대 주소를 사용하지 않아서 localhost 가 있으나 없으나 인 줄 알았더니...
이 문제는 나만 발생되는 문제는 아니었던 것 같다. React 를 사용하는 사람들도 Production 으로 실행하려니 에러가 생긴다는 사람들이 많이 보였다. 구글링에서 나오는 관련 페이지들도 전부 React 뿐 이었다. 대부분의 답은 webpack.config 에 publicPath 를 "./" 로 설정을 해보라는 것 이었다(나머지들은 너무 아니래서 스킵했다).
그래서 일단 나는 React 가 아니기 때문에 vue.config.js 를 통해서 설정을 해 보았다. webpack 에 대해서 아직 잘 모르기 때문에 다른 값을 넣어서 어떤 모양이 나오는 지 확인해 보았다.
그러고 돌려보니,
publicPath 는 앞에 붙는 아이들이구나! 알 수 있었다. 그러니 "./" 를 붙여서 상대경로로 사용할 수 있구나 생각했다. 그러나, 막상 입력하고 확인을 해보니..
똑같이 루트로 잡히는 것이다. 아오... 그렇다고 절대경로로 잡아버리면 Build 하고서 배포하게 되면 절대경로가 말썽이 되기 때문에 할 수 없는 방법이었다.
그러다가 문득 생각 났던 것이, Electron 상에서 로컬 데이터를 불러올 때에 일반적인 Path 가 아니라 Scheme 을 커스터마이즈하면 불러올 수 있다는 것이 떠올랐다. 관련된 포스팅은 다음과 같다.
어차피 Production 은 로컬파일이고, 특정 Scheme 이 들어오면 path 조작이 용이하기 때문에 충분히 사용할 수 있는 로직이겠거니 생각하여 작업을 시작했다. 게다가 publicPath 라는 것이 Scheme 을 받을 수 있는 것으로 되어 있어서 이번에는 될 것 같았다.
먼저, Webpack 의 설정을 바꿨다. publicPath 를 특정 Scheme 으로 변경을 했다. Scheme 을 "build://" 라고 하자. 실행해보니 변경은 잘 되었다.
하지만 build:// 를 감지할 수 있는 무언가가 없기 때문에 Electron Protocol API 를 이용하여 build:// 를 감지 할 수 있는 로직을 만들어 준다.
const SCHEME = "build"
async function requestBuildProtocol(request, callback){
const url = request.url
const regex = new RegExp(`${SCHEME}:\/\/(?<path>.+)$`, 'g')
const { groups: G } = Array.from(url.matchAll(regex))[0]
// URL 값을 가져와서 정규식을 돌려 Path 부분만 가져온다.
// 이 Path 부분은 상대 경로이기 때문에 app.getAppPath() 를 통해서 각 환경의 절대 경로로
// 변경하도록 한다.
callback({
path: path.resolve(app.getAppPath(), G.path)
})
}
protocol.registerFileProtocol(SCHEME, requestBuildProtocol)
이 상태에서 돌려보도록 하자.
index 페이지에서 초기에 불러오는 JS/CSS 는 물론이고, Code Splitting 을 통해서 분리된 Chunk 스크립트 들도 import 가 잘 되는 것을 확인할 수 있었다.
결론은 행복한 결말을 볼 수 있었다.
추가로, Webpack 의 Externals 를 통해 외부 스크립트 파일로 다른 라이브러리를 사용하려면 같은 방식으로 Scheme 방식을 사용하면 된다.
{
externalsType: 'script',
externals: {
'lib1:' [ 'build://lib/lib1.js', 'lib1' ]
}
}
더 간단한 좋은 방법이 있으면 좋겠는데, Webpack 을 통해서는 아직 찾을 수가 없었다. 이외에도 Code Splitting 기능을 사용하지 않으면 가능하지만, 혹시나 사용해야 하는 일이 생긴다면 Electron 환경 아래에서는 이 방법도 나쁘지 않을 것으로 생각이 된다.
[Electron] electron-builder 의 files 에 대해 알아본다. (0) | 2022.06.17 |
---|---|
[Electron] Video 사이즈 정보를 가져오기 (0) | 2022.05.18 |
[Electron] <img> 태그에 로컬 이미지 로드하기 (0) | 2022.04.27 |
[Electron] Electron 과 Vue 의 간단한 연결 방법 (0) | 2022.03.28 |