[javascript] Knockout.js를 이용한 서버 사이드 렌더링 처리 방법

서버 사이드 렌더링은 웹 애플리케이션의 성능을 향상시키고 사용자 경험을 개선하는 중요한 기술입니다. Knockout.js는 클라이언트 사이드에서 데이터 바인딩과 UI 업데이트를 쉽게 처리할 수 있는 JavaScript 라이브러리입니다. 이번 글에서는 Knockout.js를 사용하여 서버 사이드 렌더링을 처리하는 방법에 대해 알아보겠습니다.

1. 서버 사이드 렌더링 기본 설정

서버 사이드 렌더링을 하기 위해서는 Node.js와 Express.js를 사용하여 기본 서버를 설정해야 합니다. 먼저, Node.js와 Express.js를 설치합니다.

npm install express --save

다음으로, 기본 서버를 설정하고 Knockout.js와 View 모듈을 불러옵니다.

// server.js
const express = require('express');
const app = express();

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

app.get('/', (req, res) => {
  const viewModel = {}; // View 모델 정의
  
  const html = require('knockout').renderToString(viewModel); // Knockout.js로 렌더링
  
  res.render('index', { html }); // 렌더링된 HTML 전달
});

app.listen(3000, () => {
  console.log('서버가 시작되었습니다.');
});

2. 라우팅과 뷰 모델 작성

Knockout.js는 데이터 바인딩을 위한 뷰 모델(View Model)을 사용합니다. 뷰 모델은 각각의 라우트에 대해 필요한 데이터를 가지고 있어야 합니다.

// viewModels/index.js
const ko = require('knockout');

const indexViewModel = function(params) {
  // 필요한 데이터와 동작 정의
  this.data = ko.observable();
  
  this.loadData = function() {
    // 데이터를 로드하는 비동기 호출 예시
    fetch('/api/data')
      .then(response => response.json())
      .then(data => this.data(data));
  };
};

ko.applyBindings(new indexViewModel());

module.exports = indexViewModel;

3. 클라이언트 사이드 코드 작성

클라이언트 사이드에서 사용할 JavaScript 파일을 작성합니다. 이 파일은 서버에서 제공되는 뷰 모델과 데이터 바인딩을 수행합니다.

// public/js/app.js
const knockout = require('knockout');
const indexViewModel = require('../viewModels/index');

// 라우팅 정의
knockout.router.addRoute('/', 'index');

// 초기화
knockout.router.start();

// 데이터 로드
indexViewModel.loadData();

4. 클라이언트 사이드에 Knockout.js 추가

클라이언트 사이드 HTML 파일에서 Knockout.js를 추가하고 애플리케이션에서 사용할 JavaScript 파일을 로드합니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Knockout.js Server-side Rendering</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-min.js"></script>
  <script src="/js/app.js"></script>
</head>
<body>
  <!-- 뷰가 렌더링될 위치 -->
  <div id="app" data-bind="template: { name: activeView }"></div>
</body>
</html>

참고 자료