Webjarsを使ってSpringBoot2にTwitter Bootstrap5を適用する

# きっかけ

Thymeleafでアプリケーションを作る際に、バージョンをアプリケーションごとに定義しておきたかったので、その時の作業メモです。

## WebJarsの導入

gradleを利用しています。
build.gradleは 後述する Appendix を参照してください。dependencyに以下を追加します。

```gradle:build.gradle
implementation group: 'org.webjars', name: 'bootstrap', version: '5.1.3'
```

## HTMLテンプレート

WebJarsを利用したBootstrap用CSS/JavaScriptの指定は以下のとおりです。

```html:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>Title</title>
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/5.1.3/css/bootstrap.min.css}" />
</head>
<body>
<div th:text="${hello}"></div>
<script th:src="@{/webjars/bootstrap/5.1.3/js/bootstrap.min.js}"></script>
</body>
</html>
```

Thymeleafでの指定方法は、`@{/webjars/導入パッケージ/バージョン/リソースへのパス}` です。

## バージョン指定をSpringBootの設定から引っ張る

Bootstrapのバージョンをテンプレートに直接記載するのではなく、SpringBootの設定から読み出すようにもできます。次の例はSpringBootの設定： application.yml に記載してこの値をThymeleafから使います。

### 設定

```yml:application.yml
webjars:
  bootstrap: 5.1.3
```

### 設定した webjars を読む

いくつか方法はありますが、今回は1つの設定クラスを`@Component`としてSpring管理beanで扱います。

```java:WebjarsConfig.java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Data;

@Component
@ConfigurationProperties(prefix = "webjars")
@Data
public class WebjarsConfig {
	private String bootstrap;
}
```

### HTMLテンプレート(Thyemeleaf)

アンカーURLの設定方法と、Spring管理beanから値を参照する方法に注意。

```html:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>Title</title>
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/{version}/css/bootstrap.min.css(version=${@webjarsConfig.bootstrap})}" />
</head>
<body>
<div th:text="${hello}"></div>
<script th:src="@{/webjars/bootstrap/{version}/js/bootstrap.min.js(version=${@webjarsConfig.bootstrap})}"></script>
</body>
</html>
```

th:src 内に変数を設定する方法は { } で変数を囲み、URL内の末尾に(変数=${Springからバインドされた値})で指定します。

SpringBoot内のThymeleafは、SpringのApplicationContextから参照できますので、先ほどのWebjarsConfigを `@Component` 名称なしで設定していることから、参照する名前は webjarsConfig になります。 

# Appendix

## 検証環境

Windows11 / SpringBoot 2.6.6 / Java 17

### build.gradle

```gradle:build.gradle
plugins {
	id 'org.springframework.boot' version '2.6.6'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.github.apz'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	
	// https://mvnrepository.com/artifact/org.webjars/bootstrap
	implementation group: 'org.webjars', name: 'bootstrap', version: '5.1.3'
}

tasks.named('test') {
	useJUnitPlatform()
}

```

## 参考資料

* [WebJars 使い方メモ](https://qiita.com/opengl-8080/items/c8c5f787613c230a9827)
* [Thymeleaf3:4.4 Link URLs](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls)