NPM으로 Front-end 라이브러리 관리

dongbin_Shin·2021년 8월 17일
0

spring boot

목록 보기
2/2
post-thumbnail

스프링 부트에서 프론트엔드를 관리하는 방법

  • 프로젝트 내부에 패키징하지 않고 관리: 외부에서 받아오기, 트래픽 분산
    • CDN
  • 프로젝트 내부에 패키징하여 관리
    • WebJar
    • NPM

NPM is better than WebJar: 대중적으로 많이 쓰이지 않는 라이브러리는 버전 업데이트 등 관리가 잘 되지만 대부분 라이브러리가 관리되지 않고 있다.

NPM 라이브러리 관리

npm으로 라이브러리를 관리한다는 것은 package.json으로 dependencies를 관리하는 것을 말한다.
npm install로 의존성을 설치한다.

npm으로 라이브러리를 관리하기 위해서는 다음과 같은 단계를 거쳐 설정을 해주어야 한다.
1. 프론트엔드 라이브러리 위치 설정
2. HTML에 경로 작성
3. build.gradle plugin, task 추가
4. 스프링 시큐리티 설정

1. 프론트엔드 라이브러리 위치 설정

# 위치 이동
$ cd src/main/resources/static

# package.json 생성
$ npm init

# 부트스트랩 라이브러리 설치
$ npm install bootstrap

그 후 만들어진 node_modules 경로를 .gitignore에 추가해준다.

2. HTML에 경로 작성

설치한 라이브러리를 사용하고자 하는 html 코드 내부에 경로와 함께 작성해준다.
(npm으로 설치한 라이브러리들은 node_modules 아래에 위치하게 된다.)

<head>
    <meta charset="UTF-8">
    <title>title</title>
    <link rel="stylesheet" ref="/node_modules/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css" />
    <script src="/node_modules/jquery/dist/jquery.min.js"></script>
    <script src="/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/node_modules/jdenticon/dist/jdenticon.min.js"></script>
</head>

3. build.gradle plugin, task 추가하기

build Issue

빌드를 할 때 static 디렉토리 아래에 있는 package.json도 빌드하도록 설정해야 한다.
package.json을 빌드하지 않으면 프론트엔드 라이브러리를 받아오지 않아서 view에서 필요한 참조가 끊어진다.
(빌드 ==> npm install 실행)
결과적으로 화면이 제대로 보이지 않는다.

스프링 빌드 관리는 Maven과 Gradle로 나뉜다.
이에 따라 빌드 방법이 나뉘어진다.

maven

Maven의 경우 플러그인 중 frontend-maven-plugin을 사용하여 관리할 수 있다.
이 플러그인은 npm이나 node.js가 설치되어 있지 않아도 프론트엔드 라이브러리를 알아서 관리해준다.

pom.xml

<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.8.0</version>
    <configuration>
        <nodeVersion>v4.6.0</nodeVersion>
        <workingDirectory>src/main/resources/static</workingDirectory>
    </configuration>
    <executions>
        <execution>
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <phase>generate-resources</phase>
        </execution>
        <execution>
            <id>npm install</id>
            <goals>
                <goal>npm</goal>
            </goals>
            <phase>generate-resources</phase>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

gradle

nodeModulesDir라는 변수에 package.json이 위치하는 경로를 설정한다.
설정을 해주면 spring boot가 빌드될 때 package.json에 정의된 프론트엔드 라이브러리도 같이 설치할 수 있다.

  • 플러그인 추가
  • nodeModulesDir 설정
  • copyFrontLib task 추가
  • 체인걸기: copyFrontLib - npmInstall - compile.java

build.gradle

방법1

plugins {
 ...
   id "com.github.node-gradle.node" version "3.1.0"
}

repositories {
   ...
   gradlePluginPortal()
}

dependencies {
    // npm
    implementation 'com.github.node-gradle:gradle-node-plugin:3.1.0'
}

node {
   version = '16.3.0' //자신이 사용하는 노드 버전
   download = true
   nodeModulesDir = file("${projectDir}/src/main/resources/static")

}
task copyFrontLib(type: Copy) {
   from "${projectDir}/src/main/resources/static"
   into "${projectDir}/build/resources/main/static/."
}
copyFrontLib.dependsOn npmInstall
compileJava.dependsOn copyFrontLib

방법2

plugins {
    id "com.github.node-gradle.node" version "2.2.3"
}

/**
 * npm install start
 */
node {
    version = '12.13.1' //자신이 사용하는 노드 버전
    download = true
    nodeModulesDir = file("${projectDir}/src/main/resources/static")
}

task copyFrontLib(type: Copy) {
    from "${projectDir}/src/main/resources/static"
    into "${projectDir}/build/resources/main/static/."
}

copyFrontLib.dependsOn npmInstall
compileJava.dependsOn copyFrontLib

/**
 * npm install end
 */

4. 스프링 시큐리티 설정

프론트엔드 라이브러리가 위치하는 경로를 spring security 필터가 차단하지 않도록 무시해준다.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()
            .mvcMatchers("/node_modules/**")
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}

Reference

"본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다."

profile
멋있는 백엔드 개발자

0개의 댓글