프론트엔드 프로젝트와 백엔드 프로젝트를 분리하여 개발하는 방법도 있지만, 개발 편의성 혹은 구조상의 문제로 합쳐야 하는 경우가 있다.
이 글에서는 Spring boot 프로젝트와 Vue 프로젝트의 소스가 합쳐진 프로젝트를 생성한다.
추가로 크롤링을 위해 Prerendering 플러그인도 적용한다.
1. 스프링 부트 프로젝트를 생성한다.
Spring Boot 프로젝트를 생성한다
2. 뷰 CLI를 이용하여 뷰 프로젝트를 생성한다.
이 예제는 webpack-simple 템플릿으로 생성했다
3. 뷰 프로젝트 폴더에 만들어진 파일을 스프링 프로젝트로 이동한다.
From (Vue project) | To (Spring project) | 비고 |
src | ./src/main/vue |
|
Index.html | ./src/main/resources/templates | 템플릿 엔진을 사용한다면 확장자도 변경 |
그 외 | ./ | .babel.rc, webpack.config.js 등 설정 파일 |
4. package.json 파일의 상세 정보 및 의존성을 설정하고 npm install 명령을 수행한다.
5. webpack.config.js 파일을 설정한다.
A. Entry
엔트리(main.js) 파일의 위치로 설정한다.
B. Output
빌드 결과물의 위치를 /src/main/resources/static/dist 폴더로 지정한다.
const __resourceDir = 'src/main/resources/';
const __index = 'index.html';
인덱스 파일 및 리소스 파일 path 변수 선언
module.exports = {
entry: './src/main/vue/main.js',
output: {
path: path.resolve(__dirname, __resourceDir, 'static/dist'),
publicPath: '/dist/',
filename: 'build.js' },
C. webpack-dev-server를 설정한다.
기본 포트는 8080으로 스프링 부트의 기본 포트와 겹치므로 변경하는 것이 좋다.
devServer: {
before: function (app) {
app.get('/', (req, res) => {
res.sendFile(
path.resolve(__dirname, __resourceDir, 'templates', __index)
);
});
},
port: 4200,
historyApiFallback: true,
noInfo: true,
overlay: true
}
6. Gradle을 설정한다.
A. Gradle-node-plugin 디펜전시를 추가한다.
buildscript {
ext { springBootVersion = '2.0.4.RELEASE' }
repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } }
dependencies { classpath "com.moowork.gradle:gradle-node-plugin:1.2.0" classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}
apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' apply plugin: "com.moowork.node"
B. Gradle에서 사용할 npm build 및 full-build task를 추가한다.
/***** TASK DEFINE *****/
task npmBuild(type: NpmTask) { workingDir = file("./") args = ['run', 'build'] }
task fullBuild(type: Zip) { def tasks = [npmBuild, clean, build] for (int i = 0; i < tasks.size() - 1; i++) { tasks[i + 1].mustRunAfter(tasks[i]) } dependsOn(tasks) }
7. 인덱스 컨트롤러를 만들고 빌드하고 테스트한다.
@Controller
public class IndexController { public String index() { return "index.html"; } }
추가된 fullBuild task를 실행하면 npm build 이후 스프링 부트 프로젝트를 빌드한다.
@ 추가 설정: prerender-spa-plugin을 이용해 프리렌더링하여 크롤러에 노출시키는 방법
https://github.com/chrisvfritz/prerender-spa-plugin
A. package.json 파일에 의존성 추가 및 npm install
"devDependencies": { "prerender-spa-plugin": "~3.2.1" }
B. webpack.config.js 파일에 플러그인 설정 추가
const PrerenderSPAPlugin = require('prerender-spa-plugin'); const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const __resourceDir = 'src/main/resources/';const __index = 'index.html';
최상단 플러그인 import 및 디렉토리 위치 선언
module.exports.plugins = (module.exports.plugins || []).concat([
...,
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, __resourceDir, 'static'), indexPath: path.join(__dirname, __resourceDir, 'templates', __index), routes: [ '/' ], renderer: new Renderer({ renderAfterElementExists: '#app' })
})
])
최하단 production 빌드 구문에 prerender 플러그인 추가
C. 결과 확인
Postman으로 확인한 모습
'ECMAScript | TypeScript' 카테고리의 다른 글
FE개발자로서 못해준 이야기 2 - 컴포넌트 (3) | 2022.01.18 |
---|---|
FE개발자로서 못해준 이야기 1 - 프로젝트 (1) | 2022.01.13 |
ECMAScript, Console 객체 (0) | 2018.06.01 |
ECMAScript6로 만든 에라토스테네스의 체 (0) | 2018.06.01 |
ECMAScript6, Spread Operator (0) | 2018.06.01 |