Overview

이번에는 PHP Codeigniter 기반의 서비스에 VUE를 적용시키려고 고민했던 것들을 나누려고 합니다.

VUE JS는 가상 DOM을 활용하여 실시간으로 반응 컴포넌트를 제작할 수 있는 프레임워크입니다. 또한, VUE-ROUTER 및 VUEX라는 컴페니언 라이브러리를 통해 url 라우팅 및 전역상태를 관리하기에도 탁월하죠. VUE와 다른 프레임워크와의 비교 부분은 여기를 참고해주세요.

브랜디의 관리자 서비스는 PHP Codeigniter 프레임워크로 제작되었습니다. 하지만 관리자 서비스의 규모가 점점 커지고 기능이 다양해지면서 “자주 사용하는 기능을 묶어 컴포넌트화하자!”라는 숙제가 남아 있었죠.

요즘 잠깐의 여유가 생겨 이때다 싶었습니다. 관리자 서비스에 VUE를 도입하기 위한 시도를 시작했는데요. 얼마 지나지 않아 문제점에 봉착했습니다. 바로 IE9.0…. 개발자의 숙적 IE가 또 한 번 발목을 잡았습니다. 임포트가 되지 않아….

VUE를 좀 더 편리하게 사용하려면 JS의 모듈화가 필요했지만, ES2015에서는 import 혹은 require 구문을 지원하지 않아 불편하고, arrow 함수 또한 사용할 수 없습니다. 게다가 VUE의 JAX 탬플릿 구문을 사용할 수도 없었죠!! 뭔가 배보다 배꼽이 더 커질 것 같은 조짐이 보였습니다.

결국 Webpack의 도움 없이 VUE를 적용하려던 시도는 여러 가지 난관을 만났고, Codeigniter 프로젝트 내부에서 Webpack을 사용하는 방법을 연구하기 시작했습니다.

Webpack은 모듈 번들러입니다. Webpack의 메인 페이지를 방문하면 아래 네 개의 슬로건이 빙글빙글 돕니다.

Bundle your scripts
Bundle your images
Bundle your styles
Bundle your assets

아래의 이미지는 Webpack이 무엇을 하는 녀석인지 잘 설명해줍니다.

01

Webpack은 실제로 번들러라고 광고하는것 처럼 Only Webpack 빌드만으로는 소스 파일들을 모아줍니다. 만약 webpack-dev-server로 실행하면 websocket을 통해 소스가 변경됐을 때 실시간으로 화면을 갱신해주는 개발 툴 제공 정도의 역할 밖에 없습니다. (…충분히 훌륭하잖아?)

대부분의 기능은 엄청난 확장성을 가진 webpack의 설정으로 모듈로서 작동할 수 있죠. 예를 들면 Babel은 우리의 발목을 잡았던 IE를 위해 ES6로 작성된 js 문법을 IE에서 사용할 수 있는 ES5문법으로 너무나 쉽게 트랜스컴파일할 수 있습니다.

하지만… 관리자 서비스는 위에서 언급했듯이 Codeigniter 기반입니다. 따라서 완벽히 VUE와 API서버를 분리하려면 로그인, 메뉴구성, 헤더, 푸터 등 PHP 기반으로 제작된 모든 기능들과 인증 등 기존 방식을 전부 새로 만들어야만 VUE를 온전히 사용할 수 있습니다.

문제점들을 모두 해결하고 넘어가기엔 여유가 부족하기 때문에 조금씩 적용하자고 생각했습니다. 덕분에 webpack-dev-server의 실시간 소스 반영 기능을 포기해야만 했죠.(눈물) 우리의 서버는 node기반이 아닌 apache-php 기반이었기 때문입니다.

자, 그럼 Codeigniter 프로잭트 하위에 웹팩을 포함시켜 Hello World까지 가는 짧은(?)여정을 시작해봅시다.


Hello world로 가는 여정

Node, npm 설치

맥에서도 유사한 명령어로 제작할 수 있도록 CMD 위주로 진행하겠습니다. 먼저, 여기를 클릭해 Node를 설치합시다.

02
8.11.3 LTS버전으로 진행했습니다.


맥에서는 Homebrew를 통해 간편하게~

brew install node




설치 확인

npm



03
잘 설치되었네요.



web pack 폴더 생성 및 이동

mkdir webpack
cd webpack



04



nom init으로 초기화

npm init



06



webpack, vue, babel 설치

npm install -D webpack webpack-cli webpack-dev-server
npm install -D vue-loader vue-template-compiler
npm install -D babel-core babel-loader babel-preset-es2015



여기서 VUE는 설치하지 않습니다! 왜냐하면 VUE.js는 로딩만 하면 되고 필요하지 않습니다! (읭?) VUE는 Codeigniter view에서도 사용해야 하기 때문에 해당 view에서 import 해줍니다. 따라서 VUE 컴포넌트가 들어가는 시점에는 이미 전역에 vue.js 가 있습니다. 따라서 굳이 각 모듈마다 VUE를 import 했다가 webpack 설정에서 다시 vue.js를 제외할 필요는 없습니다.

VUE와 template 태그를 로딩할 수 있는 로더도 설치하고, 트랜스컴파일을 위한 바벨, IE9를 지원하기 위한 es2015프리셋도 함께 설치합니다.


webpack 빌드명령어 package.json의 script부분에 추가

"scripts": {   
"build": "webpack --mode production",
"build-dev": "webpack --mode development",
  }



이제 VUE를 빌드할 명령어를 작성합니다. 위처럼 두 가지 명령어를 제작해두면, 추후 env를 통해 webpack.config.js를 분기시켜 원하는 환경으로 빌드할 수 있습니다. 또한 production 모드로 빌드할 땐 자동으로 옵티마이저 - uglify 내장 플러그인이 적용되어 익숙한 min.js형태로 빌드되며 development를 빌드할 땐 사람이 알아볼 수 있는 형태로 빌드되고, debugger 코드 또한 살아있습니다.


weboack.config.js 작성

const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  entry: {
    HelloWorld: './src/main.js'
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
      }
    ]
  },

  resolve: {
    alias: {
      'vue$':'vue/dist/vue.esm.js'
    }
  },

  plugins: [
    new VueLoaderPlugin()
  ]
}



webpack.config.js 가 없다면 생성한 후 위와 같이 작성합니다.


.babelrc 작성

{
    "presets": ["es2015"]
}




테스트용 파일 작성

1)main.js 작성

import HelloWorld from './HelloWorld.vue'

Vue.component('hello-world', HelloWorld);



2)HelloWorld.vue 작성

<template>
  <div id="helloworld">
    <span></span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data: () => {
    return {
      word1: 'Hello',
      word2: 'World'
    }
  }
}
</script>




테스트 빌드

npm run build-dev


빌드를 할 땐 기본적으로 ‘/dist/’ 하위에 소스코드가 떨어집니다. 자, 여기까지 진행하셨다면 폴더 구조는 다음과 같을 것입니다.

05
지금까지 진행한 파일 모습입니다.

뷰 컴포넌트가 잘 제작되고 등록되는지 확인하려면 기본 빌드 폴더인 dist 폴더에 Test.html을 작성해 브라우저로 열어봅시다.


확인용 html 파일 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VUE Test</title>
    <!-- VUE 플러그인 -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
    <div id="vue">
        <hello-world></hello-world>
    </div>
    <script src="HelloWorld.js"></script>
    <script>
        new Vue({
            el: '#vue'
        })
    </script>
</body>
</html>


07
잘 나옵니다.


08


09
정상적으로 VUE가 적용된 것을 확인합니다.



코드이그나이터 설치

이제 코드이그나이터 프로젝트 내부에서 VUE 컴포넌트를 출력해보기 위해 코드이그나이터 프로젝트를 생성합시다. 먼저 Codeigniter와 XAMPP를 다운로드 받습니다.

Codeigniter 받으러 가기
XAMPP 받으러 가기

프로젝트 폴더 하위에 Codeigniter 프로젝트용 폴더를 생성합니다.

mkdir codeigniter-with-vue-webpack
cd codeigniter-with-vue-webpack


10

다운받은 Codeigniter를 해당 폴더에 압축 해제하면 Codeigniter 설치가 끝납니다.


XAMPP 설치 및 DocumentRoot 변경

XAMPP를 설치하고 DocumentRoot를 테스트 프로젝트 폴더로 설정한 뒤 아파치를 실행합니다.

11


12


13

Codeigniter 프로젝트가 생성되었고, 서버 실행이 완료되었습니다.


webpack 폴더를 Codeigniter 프로젝트 하위로 이동

14

node-modules는 너무 크기 때문에 기본 파일만 복사하고, npm install로 설치합니다.

Codeigniter에서 VUE를 사용하기 위한 webpack dist설정

기존의 프로젝트에서 스크립트를 모아두는 폴더 하위로 빌드 결과 파일을 보내기 위하여 webpack 빌드 시 dist 폴더가 아닌 /application/scripts/vue/hello_world 하위로 빌드 결과 파일이 생성되도록 설정합니다.

// 기존
module.exports = {
  entry: {
    HelloWorld: './src/main.js'
  },

  //... 생략
}

// 변경후
module.exports = {
  entry: {
    '../../application/scripts/vue/hello_world/HelloWorld.js': './src/main.js'
  },

  //... 생략
}




Codeigniter의 load->view 기능을 활용하여 파일 작성

1)header.php

// application/views/common/header.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VUE Test</title>
    <!-- VUE 플러그인 -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>



2)실제 view

// application/views/vue/hello_world/vueTestPage.php

<?php $this->load->view( 'common/header' ); ?>

<body>
    <div id="vue">
        <hello-world></hello-world>
    </div>

    <script src="/includes/scripts/vue/hello_world/HelloWorld.js" type="text/javascript"></script>
    <script>
        new Vue({
            el: '#vue'
        })
    </script>
</body>

<?php $this->load->view( 'common/footer' ); ?>



3)footer.php

// application/views/common/footer.php
</html>

실제 프로젝트 구성과 유사하게 header, body, footer로 나누어 파일을 작성해봅니다. 실제로는 더 복잡하지만 이 정도만 나누겠습니다.




Codeigniter 테스트용 컨트롤러 작성

// application/controllers/Vue.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Vue extends CI_Controller {

    public function index()
    {
        $this->load->view('vue/vueTestPage');
    }
}



정말 심플(?)한 테스트용 파일 작성이 모두 끝났습니다! 이제 잘 작동하는지 확인해볼까요?


코드이그나이터에서 helloworld 출력

15
짜잔

이번엔 문제의 IE에서 확인해봅시다.


IE9.0 환경에서 확인

16

IE에서도 무사히 출력되는군요. 이제 코드이그나이터 환경의 프로젝트에서도 IE까지 지원하며 무사히 VUE를 사용할 수 있게 되었습니다! (시간이 없어서 가상머신에 IE9가 설치된 윈도우7까지 테스트하진 못했습니다!) 모든 작업이 완료한 후, 파일 폴더 구조는 아래와 같습니다.

17
붉은 네모 부분이 실제로 제작하거나 수정한 파일들입니다.



Conclusion

여기까지가 Codeigniter 프래임워크 환경에서 webpack + vue를 사용하기 위한 웹팩의 설정 과정 및 테스트 결과였습니다. php 서버를 사용해야 하기 때문에 webpack-dev-server의 핫리로드 기능을 사용하지 못하는 건 매우 안타까운 일입니다. 하지만 짧은 시간에 신기술을 도입하면서도 수많은 리스크를 회피할 수 있다는 건 나쁘지 않은 선택이라 생각합니다.

위의 웹팩설정을 조금만 활용한다면 다른 프레임워크 프로젝트에서도 무리없이 VUE를 사용할 수 있을 겁니다! 비슷한 고민을 하셨던 개발자님들… 집에 가기 전 말고 오전에 Webpack을 설치해보세요. 안 그러면 저처럼 집에 못갈 수도 있으니까요!


참고
.gitignore 작성, index.php 제거 등은 내용에 포함하지 않았으며, 아래의 링크로 자세히 알 수 있음.

Codeigniter index.php 없애기


강원우 과장 | R&D 개발2팀
kangww@brandi.co.kr
브랜디, 오직 예쁜 옷만