์ƒˆ์†Œ์‹

Front-End/Vue

[Vue.JS] SpringBoot + Gradle ํ”„๋กœ์ ํŠธ ์—ฐ๋™

  • -

 

 

 

[Vue.JS] SpringBoot + Gradle ํ”„๋กœ์ ํŠธ ์—ฐ๋™

 

 

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ์— ์•ž์„œ ํ”„๋กœ์ ํŠธ ์„ค์ • ์ž‘์—… ๋ฐ ์–ธ์–ด ์„ ํƒ ๋“ฑ ๋‹ค์–‘ํ•œ ์„ ํƒ์ง€์™€ ๋ฒ„์ „ ๋“ฑ ๋งค ์ˆœ๊ฐ„ ์„ ํƒ์˜ ์—ฐ์†์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Gradle๊ณผ JPA๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ฐฑ์—”๋“œ(API)๋ฅผ ๋งŒ๋“ค๊ณ , ํ”„๋ŸฐํŠธ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Vue ๋˜๋Š” React๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐฑ์—”๋“œ๋Š” Java, SpringBoot๋กœ ์„ ํƒํ•˜๊ณ  ํ”„๋ก ํŠธ์ชฝ์„ Vue๋กœ ์„ ํƒ์€ ํ–ˆ์ง€๋งŒ ์„œ๋ฒ„์— ์˜ฌ๋ฆด ๋•Œ๋Š” ๊ฐ์ž์˜ ์„œ๋ฒ„ ๊ตฌ๋™ ๋ฐฉ์‹์ด ์•„๋‹Œ ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ SpringBoot์˜ ๋‚ด์žฅ ํ†ฐ์บฃ์˜ ํฌํŠธ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๋ฐฉ์‹์ด ๊ฐ€๋Šฅํ•œ์ง€ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์„ค์ •์€ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ์›๋ฆฌ๋Š” ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆ์ฆ์ด ์ƒ๊ฒจ์„œ ์ด์ฐธ์— ํ•œ๋ฒˆ ์ฐพ์•„๋ณด๊ณ  ํ”„๋กœ์ ํŠธ ์„ธํŒ…์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. (ํ•˜๊ฒ ๋‹ค๋Š” ๊ฑด ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋Š” ๊ฑฐ๊ฒ ์ฃ ? ๐Ÿ˜˜)

 

 

 


#1. SPA ? SSR ?! CSR !?!

SPA์˜ ์›๋ฆฌ์ธ CSR(Client Side Rendering)๊ณผ SSR(Server Side Rendering)์˜ ๊ธฐ๋ณธ ๊ฐœ๋… ๊ฐ„๋žตํ•˜๊ฒŒ๋งŒ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

SPA ๋ž€?

  • SPA(Single Page Application)๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ฒซ ํŽ˜์ด์ง€๋งŒ ๋ฐ›์•„์˜ค๊ณ  ์ดํ›„์—๋Š” ๋™์ ์œผ๋กœ ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋œป

 

 

SSR ์ด๋ž€ ?

 

  • SSR(Server Side Rendering), ์ฆ‰ ์„œ๋ฒ„ ์ธก์—์„œ ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚œ๋‹ค๋Š” ๋œป
  • ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ชจ๋‘ ์‚ฝ์ž…๋œ ์ƒํƒœ์˜ ์™„์„ฑ๋œ HTMl์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜ค๋Š” ๋ Œ๋”๋ง ๋ฐฉ์‹

 

CSR ์ด๋ž€ ?

 

  • CSR(Client Side Rendering)์€ ๋ง ๊ทธ๋Œ€๋กœ SSR๊ณผ ๋‹ฌ๋ฆฌ ๋ Œ๋”๋ง์ด ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ ์ผ์–ด๋‚œ๋‹ค๋Š” ๋œป
  • ์›น ๋ธŒ๋ผ์šฐ์ €์— ์ฃผ์†Œ ์ž…๋ ฅ ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๋นˆ HTMl๋งŒ ๋ฐ›์•„์˜ค๊ณ , ๋ฐ์ดํ„ฐ๋Š” ์—ฌ๋Ÿฌ static ํŒŒ์ผ๋“ค์ด ๋กœ๋“œ๋œ ํ›„์— ์„œ๋ฒ„์— ์š”์ฒญํ•ด์„œ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ Œ๋”๋ง

 

 


#2. ํ”„๋กœ์ ํŠธ ์„ค์ •

ํ˜„์žฌ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ธํ…”๋ฆฌ์ œ์ด(IntelliJ IDEA) ํˆด์„ ์ด์šฉํ•ด์„œ ์ž‘์—…์„ ํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. VS Code๋‚˜ ๋‹ค๋ฅธ ํˆด์— ์นœ์ˆ™ํ•˜์‹œ๋‹ค๋ฉด ํ•ด๋‹น ํˆด์—์„œ ์ž‘์—…ํ•˜์…”๋„ ๋ฉ๋‹ˆ๋‹ค.

 

ํ•ด๋‹น ๋‚ด์šฉ์—์„œ๋Š” SpringBoot ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋‚ด์šฉ์€ ๋‹ค๋ฃจ์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „์— ์ž‘์„ฑํ•ด ๋‘” ํฌ์ŠคํŒ…์ด ์žˆ์œผ๋‹ˆ ์„ค์ •์— ์ฐธ๊ณ ํ•ด ์ฃผ์‹œ๊ณ  ๋ฒ„์ „์ด ๋‚ฎ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์ฃผ์‹œ๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ํ•ด๋‹น๋งํฌ๋Š” ์—ฌ๊ธฐ๋ฅผ ํด๋ฆญํ•ด ์ฃผ์„ธ์š”.

 

[SpringBoot] IntelliJ์—์„œ Springboot + gradle ์‹คํ–‰ํ•˜๊ธฐ

IntelliJ์—์„œ Springboot ์‹คํ–‰ํ•˜๊ธฐ 1. ๊ธฐ๋ณธ์„ค์ • ํ™•์ธ ํ›„ Next 2. GroupId์™€ ArtifactId ์„ค์ •. ํŠนํžˆ ArtifactId๋Š” ํ”„๋กœ์ ํŠธ์˜ ์ด๋ฆ„์ด๋˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ์ด๋ฆ„์œผ๋กœ ์ž‘์„ฑ ํ›„ Finish 3. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋˜

sm-code.tistory.com

 

1. Vue ์„ค์น˜ ๋ฐ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

#์„ค์น˜
$ npm install -g @vue/cli

#ํ™•์ธ
$ vue --version

#vue ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
$ vue create frontend

#ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ธํŒ… ์žฌํ™•์ธ
$ npm i

#vue ํ”„๋กœ์ ํŠธ ์‹œ์ž‘
$ cd frontend
$ npm run serve
300x250

 

์œ„์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ๋ช…๋ น์–ด ์‹คํ–‰ํ•ด์„œ Vue ์„ค์น˜ ๋ฐ Vue ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€ ์ง„ํ–‰ํ–ˆ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๊ฐ€ ๋˜์–ด์žˆ์„ ๊ฒ๋‹ˆ๋‹ค.

SpringBoot + Gradle + Vue ํ”„๋กœ์ ํŠธ ์„ธํŒ… ์ค‘๊ฐ„ ํ™•์ธ
์ฐธ๊ณ ์šฉ ์˜ˆ์‹œ

 


์‚ฌ์‹ค ์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ํ•ด๋„ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ๋Š” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ €์˜ ๋ชฉํ‘œ๋Š” ์„œ๋ฒ„ ๋ฐฐํฌ๊นŒ์ง€ ์™„๋ฃŒํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„œ๋ฒ„์— ์ด๋Œ€๋กœ ๋ฐฐํฌํ•˜๋ ค๋ฉด Vue ํ”„๋กœ์ ํŠธ์—์„œ ์ž‘์—…ํ•˜๊ณ  ๋นŒ๋“œ๋œ ํŒŒ์ผ์„ ์Šคํ”„๋ง๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ์— ์ˆ˜์ž‘์—…์œผ๋กœ ์˜ฎ๊ฒจ์™€์•ผ ํ•˜๊ณ ... ์ƒ๊ฐ๋งŒ ํ•ด๋„ ๊ท€์ฐฎ์€ ์ž‘์—… ๊ฐ™์ง€ ์•Š๋‚˜์š”?! ์•„๋‹ˆ์‹œ๋ผ๋ฉด ์–ด์ฉ” ์ˆ˜ ์—†์ง€๋งŒ.. ์˜ˆ... ์ €๋Š” ๊ทธ๋ž˜์„œ ์Šคํ”„๋ง๋ถ€ํŠธ ๋‚ด์žฅ ํ†ฐ์บฃ ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ Vue Build๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ ํŒŒ์ผ๋“ค์€ ์Šคํ”„๋ง๋ถ€ํŠธ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •์„ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค๋ฉด ๋กœ์ปฌ ๊ฐœ๋ฐœ ์‹œ์—๋Š” ํฌํŠธ๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์“ฐ๊ณ  ๊ฐœ๋ฐœ ์„œ๋ฒ„์— ์˜ฌ๋ฆด ๋•Œ๋Š” Jar ํŒŒ์ผ ํ•˜๋‚˜๋งŒ์œผ๋กœ ํ•˜๋‚˜์˜ ํฌํŠธ๋ฅผ ๊ฐ€์ง„ ์ƒํƒœ๋กœ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

โ€ป ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ”„๋กœ์ ํŠธ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค. โ€ป
ํ•œ ํ”„๋กœ์ ํŠธ์— ๊ฐ™์ด ๋‘๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋™์ผ Depth์— Vue ํ”„๋กœ์ ํŠธ์™€ SpringBoot ํ”„๋กœ์ ํŠธ๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค๊ณ  ๊ฒฝ๋กœ๋งŒ ๋งž์ถฐ์ฃผ๋ฉด ๊ฐ๊ฐ์˜ ์†Œ์Šค๋ฅผ ๋”ฐ๋กœ ํ˜•์ƒ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

2. Springboot ์‹คํ–‰ ์‹œ Vue.js ์ž๋™ ๋ฐฐํฌ ์‹คํ–‰ ์ฝ”๋“œ ์ถ”๊ฐ€

์•„๋ฌดํŠผ! ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” SpringBoot ํ”„๋กœ์ ํŠธ ์•ˆ์—์„œ Vue ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋นŒ๋“œ๋ฅผ ๋Œ๋ฆฐ ํ›„ ๋นŒ๋“œ๋œ ํŒŒ์ผ์˜ ํƒ€๊ฒŸ ์œ„์น˜๋ฅผ /src/main/resources/static ์œผ๋กœ ์ง€์ •ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

// build.gradle ์„ค์ • ์ถ”๊ฐ€


plugins {
    id 'com.moowork.node' version '1.3.1'
}

node {
    workDir = file("./frontend")
    npmWorkDir = file("./frontend")
    nodeModulesDir = file("./frontend")
}

task setUp (type: NpmTask) {
    description = "Install Node.js packages"
    args = ['install']
    inputs.files file('package.json')
    outputs.files file('node_modules')
}

task buildFrontEnd (type: NpmTask, dependsOn: setUp) {
    description = "Build vue.js"
    args = ['run', 'build']
}

processResources.dependsOn 'buildFrontEnd'
// vue.config.js ํŒŒ์ผ์— ์„ค์ • ์ถ”๊ฐ€


const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({

    ....(์ค‘๋žต)

    transpileDependencies: true,
    outputDir: "../src/main/resources/static",  // ๋นŒ๋“œ ํƒ€๊ฒŸ ๋””๋ ‰ํ† ๋ฆฌ
    devServer: {
        proxy: {
        	// ๋กœ์ปฌ ์„œ๋ฒ„ ํ…Œ์ŠคํŠธ ์‹œ ์ด์šฉ
            '/api': {
                // '/api' ๋กœ ๋“ค์–ด์˜ค๋ฉด ํฌํŠธ 8081(์Šคํ”„๋ง ์„œ๋ฒ„)๋กœ proxy ์ฒ˜๋ฆฌ
                target: 'http://localhost:8081',
                changeOrigin: true // cross origin ํ—ˆ์šฉ
            }
        }
    }

    ....(์ค‘๋žต)

})
// WebConfig.java


@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {

	....(์ค‘๋žต)

    registry.addResourceHandler("/**/*")
            .addResourceLocations("classpath:/static/")
            .resourceChain(true)
            .addResolver(new PathResourceResolver() {
                @Override
                protected Resource getResource(String resourcePath, Resource location) throws IOException {
                    Resource requestedResource = location.createRelative(resourcePath);
                    return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                            : new ClassPathResource("/static/index.html");
                }
            });
            
            
	....(์ค‘๋žต)

}

 

 

์—ฌ๊ธฐ๊นŒ์ง€ ์„ฑ๊ณต์ ์œผ๋กœ ์„ค์ •์ด ๋˜์…จ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์œ„์น˜์— ๋นŒ๋“œ๋œ ํŒŒ์ผ์ด ์ƒ์„ฑ์ด ๋ฉ๋‹ˆ๋‹ค.

Vue ๋นŒ๋“œ๋œ ํŒŒ์ผ SpringBoot resources ๋””๋ ‰ํ„ฐ๋ฆฌ ํ•˜์œ„์— ์ €์žฅ

 

์ถ”๊ฐ€๋กœ, ํ˜‘์—…ํ•˜๊ณ  ๊ณ„์‹ค ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊นƒ ์ด๊ทธ๋…ธ์–ด ํŒŒ์ผ์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ ์„ค์ •ํ•ด ์ฃผ์…”์•ผ ๋‹ค๋ฅธ ์ž‘์—…์ž๋“ค๊ณผ์˜ ์ถฉ๋Œ์„ ์˜ˆ๋ฐฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// .gitignore ์— ์•„๋ž˜์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” Git Commit ์˜ˆ์™ธ ์ฒ˜๋ฆฌ


....(์ค‘๋žต)

/frontend/node_modules
/src/main/resources/static

....(์ค‘๋žต)

 

 


๋งˆ์น˜๋ฉฐ..

ํ•œ๋ฒˆ ์„ค์ •ํ•œ ๋‚ด์šฉ์„ ๋‹ค์‹œ ์Šคํ…์„ ๋ฐŸ์•„๊ฐ€๋ฉด์„œ ๊ธฐ๋กํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ... ์ด ๊ท€์ฐฎ์Œ์„ ์ด๊ฒจ๋‚ด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์— ํฌ์ŠคํŒ…ํ•  ๋•Œ๋Š” ์šฉ๊ธฐ ๋‚ด์„œ ์ž๋ฃŒ์กฐ์‚ฌ๋ถ€ํ„ฐ ์„ค์ •, ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋ฐœ๊นŒ์ง€ ์ง„ํ–‰ํ•˜๋Š” ๋‚ด์šฉ์œผ๋กœ ๋‹ค์‹œ ๋Œ์•„์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ œ ํฌ์ŠคํŒ…์„ ๋ณด์‹œ๊ณ  ์„ค์ •์„ ํ•˜์‹œ๋‹ค๊ฐ€ ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ๊ฐ™์ด ๊ณ ๋ฏผํ•ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๋„์›€์ด ๋˜์‹ค ์ˆ˜๋„...? ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค ๐Ÿ˜œ๐Ÿ˜œ

 

 

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Š

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿ‘