본문 바로가기
프로젝트

24/10/02 - [개인] 점핑 액션 게임(7): ES6 모듈 환경에서 Express.js로 최상위 폴더의 JSON 파일 불러오기

by Jini_Lamp 2024. 10. 2.

스테이지 구분을 위해서는 미리 준비되어 있는 stage.json 파일에서 값을 가져와 사용해야 한다.

그러기 위해서 먼저, index.js 파일에서 최상위 폴더에 위치한 assets 폴더의 stage.json 파일을 불러오려고 시도했다.

import stageData from '../assets/stage.json' with { type: 'json' };

console.log(stageData);

 

이 방식은 JS에서 ES Modules 방식으로 JSON 파일을 가져올 때 사용하는 새로운 옵션이다. 특히 with { type: 'json' }; 구문은 JSON 파일을 모듈로 불러올 때 명시적으로 그 파일의 유형을 'json'으로 지정하는 역할을 하는데, JavaScript가 파일 형식을 제대로 처리할 수 있도록 돕는다.

 

하지만 결과는...

장렬하게 실패...

 

이때부터 머리가 아파오기 시작했다. with { type: 'json' }; 대신 기존에 사용한 방법이라는 fetch 함수를 사용해도 결과는 같았기 때문이다.

 

이 문제를 해결해야 다음 단계로 나아갈 수 있기 때문에, 검색을 계속하던 중 나와 같은 고민을 하고 있는 어느 게시물을 발견했다.(링크)

 

게시물을 조금 요약하자면, 클라이언트 파일이 담겨 있는 public 폴더와, json 파일이 담겨 있는 assets 폴더는 서로 최상위 경로에 배치되어 있다.

그러나 클라이언트 파일이 있는 public 폴더가 아닌 곳에서는 json 파일을 읽을 수 없어, assets 폴더를 public 폴더의 하위에 집어 넣었다고 한다.

// 수정 전
/assets
    - stage.json
/public
    - index.js


// 수정 후
/public
    /assets
        - stage.json
    - index.js

 

해당 게시물을 참고하여, 나도 assets 폴더를 public 폴더의 하위로 옮겼다.

그러자 드디어 제대로 된 값을 얻을 수 있게 되었다.

와!!!

 

하지만 여기서 의문점이 생겼다.

 

왜 public 폴더의 하위에 있을 때만 제대로 동작하는 걸까?

public 폴더가 어떤 영향을 주고 있는건가?

 

결론만 말하자면, "그렇다"라고 할 수 있다.

이전에 나는 app.js 파일에서 다음과 같은 코드를 작성해 서버와 클라이언트를 연동한 적 있다.

app.use(express.static('public'));

 

해당 코드는 이미지나 CSS, JS 파일과 같은 정적 파일을 서버에 제공하는 건데, 여기서는 public을 사용했기 때문에 public 하위에 있는 파일들을 제공한다. 또한 경로를 지정하지 않아 서버는 기본적으로 public 폴더 내부에서 파일을 찾도록 설정되어 있다.

즉, public 폴더 바깥에 있는 파일은 브라우저가 직접 접근할 수 없게 되어 있다.

그래서 올바른 경로를 사용했음에도 stage.json 파일을 찾을 수 없었다.

 

원인을 알았다면 이젠 해결할 차례다.

public 폴더를 Express 서버에 서빙했던 것처럼, assets 폴더 또한 Express 서버에 서빙하면 된다. 다만 이미 기본 경로는 public 폴더가 차지했으므로, /assets 경로를 사용할 예정이다.

더보기
import express from "express";
import { createServer } from 'http';
import initSocket from "./init/socket.js";
import { loadGameAssets } from "./init/assets.js";

const app = express();
const server = createServer(app);   // 이걸 이용해 서버를 키고, 웹 소켓도 연결하는 등 이것저것 할 것이다.

const PORT = 3000;

app.use(express.static('public'));
app.use('/assets', express.static('assets'));	// assets 폴더를 서빙한다.

app.use(express.json());
app.use(express.urlencoded({extended: false}));
initSocket(server);

app.get('/', async(req, res) => {
    res.send('<h1>Hello World?</h1>');
});

server.listen(PORT, async () => {
    console.log(`Server is running on port ${PORT}`);

    // 이곳에서 파일을 읽음
    try {
        const assets = await loadGameAssets();
        console.log(assets);
        console.log('Assets loaded successfully');
    } catch(error) {
        console.log('Failed to load game assets: ' + error);
    }
});

 

다시 결과를 확인해보면...

폴더를 옮기지 않아도 멀쩡하게 가져왔다!