在业务中使用Spring Boot和webpack进行环境配置的备忘录
首先
在业务新进人员策略中,
经过团队内的共识形成后,我们决定以SpringBoot为基础,
然后对于我们在公司内可以使用的技术,被告知可以自由选择,
因此,我首先想到了npm。
我认为这个原因是因为我希望能够在Spring Boot中开发时使用不仅仅是准备一个js文件,还要结合一些周边技术,比如包管理器和打包工具。所以,首先我会尝试安装npm。
以下是源代码。
(提交信息有点随便。对不起。)
创建者规格
-
- Jsはそこそこに書けるけど、実務の経験はないので客観的にできるとは言えないかも?
-
- モダンJSはReactもVueも一応書ける
-
- モジュールバンドラーからは逃げてきました
-
- Spring Bootはまだまだ学習中のため、本業務で身につけていきたい
- Spring Boot周りの開発技術はもっとわからない、、、頑張って勉強します
开始SpringBoot项目
请确保本地已经安装了npm,这样会更加方便。请准备好npm和Node.js并尝试一下。
我会尝试使用Java 17版本进行操作。
另外,我已根据业务需求进行了相应的依赖关系调整。
plugins {
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
这篇文章对于扩展功能会有所帮助。
我会参考下面的文章(虽然简单)制作一个大致能运行的东西。
这次我们将按照下面的图片所示的目录结构来设计。
用于运行npm的Gradle代码
我依照以下的文章进行环境搭建,这篇文章在工作期间多次拯救了我,真是感激之至。
首先,在Gradle中能够构建npm,从而导入插件,然后编写命令。
plugins {
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id 'java'
id "com.github.node-gradle.node" version "3.2.1"
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
bootRun {
// for static resource hot reloading
// クラスパスの変更を自動的に監視してくれる
// https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#running-your-application-reloading-resources
sourceResources sourceSets.main
}
repositories {
mavenCentral()
}
node {
// 16系はパッケージとの互換性がない可能性がある
version = '16.14.2'
download = true
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// task script-name in pacakge-json (dependsOn: ['npm_run_command'])
task webpack(dependsOn: ['npm_run_webpack'])
task dev(dependsOn: ['npm_run_dev'])
task format(dependsOn: ['npm_run_format'])
tasks.named('test') {
useJUnitPlatform()
}
在本地创建一个package.json文件。
请在本地运行npm init。(如果本地没有安装npm,则需要从零开始创建package.json文件,这很麻烦。)
npm init -y
让我们开始安装所需的软件包。
npm install jquery tailwindcss axios
npm install --save-dev @babel/core @babel/preset-env babel-loader webpack webpack-cli webpack-dev-server css-loader sass sass-loader mini-css-extract-plugin path webpack-remove-empty-scripts css-minimizer-webpack-plugin
我做了很多事情。而且,我写了一个脚本来运行webpack并整理了以下文件。
{
"name": "demo",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"webpack": "webpack --mode=development"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tkknot/spring-npm.git"
},
"author": "tkknot",
"license": "ISC",
"bugs": {
"url": "https://github.com/tkknot/spring-npm/issues"
},
"homepage": "https://github.com/tkknot/spring-npm#readme",
"dependencies": {
"axios": "^0.27.2",
"jquery": "^3.6.0",
"tailwindcss": "^3.1.8"
},
"devDependencies": {
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^4.0.0",
"mini-css-extract-plugin": "^2.6.1",
"node-sass": "^7.0.1",
"path": "^0.12.7",
"sass": "^1.54.4",
"sass-loader": "^13.0.2",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.10.0",
"webpack-remove-empty-scripts": "^0.8.1"
}
}
由于您的node和webpack版本可能与node-sass或sass-loader的scss编译版本不兼容,所以稍后再进行调整。
创建一个style.scss、style.css和main.js文件。
按照标题所示,请在以下路径创建。
-
- ..(省略)/static/css/style.scss
-
- ..(省略)/static/css/style.css
- ..(省略)/static/js/main.js
编写Webpack的配置文件
因为没有config文件,无法运行webpack,所以需要创建一个。
const webpack = require("webpack");
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const RemoveEmptySctiptsPlugin = require("webpack-remove-empty-scripts");
module.exports = {
entry: {
// バンドル対象ファイルが一つの場合
// 生成されるファイル名:対象ファイルの位置
main: path.join(__dirname, "/src/main/resources/static/js/main.js"),
style: path.join(__dirname, "/src/main/resources/static/css/style.scss"),
// バンドル対象のファイルが複数の場合
vendor: [
"axios",
"jquery",
],
},
target: 'node',
// バンドルファイルの出力先
output: {
path: path.join(__dirname, "/src/main/resources/static"), // eslint-disable-line
publicPath: "/",
filename: "js/[name].bundle.js",
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
}),
new MiniCssExtractPlugin({
// cssを別ファイルとして書き出し
filename: "css/[name].css",
}),
// バンドルの際に不要なファイルを削除
new RemoveEmptySctiptsPlugin(),
],
optimization: {
minimizer: [
new CssMinimizerPlugin()
]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
],
},
{
test: /\.(sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
// .css 内の URL パスなどをそれぞれの publicPath に合わせてくれる
"css-loader",
// .sass のビルド
"sass-loader",
],
},
],
},
resolve: {
extensions: [".js"],
modules: ["node_modules"],
},
};
以下的文章在解决错误和分割CSS时非常有用。
ESLint和Prettier的配置
我会在这里加入现代JS开发中常见的代码分析和格式化工具。
npm install --save-dev eslint prettier eslint-plugin-prettier eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-config-prettier
使用 eslint 和 prettier,您可以通过以下方式创建配置文件。
{
"env": {
"node": true,
"es6": true,
"commonjs": true,
"browser": true
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest"
},
"plugins": ["prettier"],
"extends":[
"eslint:recommended",
"prettier"
],
"rules": {"no-unused-vars": "off"}
}
对于未使用过的模块等,我们将关闭no-unused-vars,以避免产生错误判定。
{
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"quoteProps": "as-needed",
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always",
"bracketSameLine": true
}
我们应该忽略不需要进行整形的文件。
node_modules
package-lock.json
为了在npm上运行,编写命令。
使用Eslint进行静态分析,并使用Prettier进行格式化。
{
"scripts": {
"webpack": "webpack --mode=development",
//追加
"format" : "eslint --cache --fix src/ && prettier --write src/"
},
}
只要运行没有错误就算成功。
现在在Spring Boot中可以使用npm了!
npm run format
or
./gradlew format
准备Scss
这次我们将创建一个名为variables.scss的文件,并尝试将其导入到/css文件中。
@import "./variables.scss";
header {
color: #ffffff;
background: $color-primary;
}
$color-primary: #36e8ff;
另外,官方要求在导入JS文件时还需添加导入.scss文件的语句。
import '../css/style.scss';
运行npm run webpack或./gradlew webpack时,sass-loader会对其进行编译。
如果style.css文件如下所示,就可以了。
header {
color: #ffffff;
background: #36e8ff;
}
【番外篇】未能实现的事情
无法充分利用 tailwindcss
创建tailwindcss的配置文件,并在package.json中准备执行命令,
未能适当加载、无法使用特定的类、不能使用插件等等,
无法实现tailwindcss的真正价值。
我正在考虑把业务的部分改成Bootstrap,因为我通过官方文档的npx命令已经生成了CSS文件,接下来我会尝试加载它。
如果有了解的人可以告訴我,我將不勝感激。
尝试制作一个简单的界面。
既然有这个机会,我们就简单地做个屏幕吧。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta charset="utf-8" />
<link rel="stylesheet" th:href="@{/css/tailwind.css}">
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
<header class="text-center font-bold"><span th:text="${message}" class="text-lg"></span></header>
<script th:src="@{/js/main.bundle.js}"></script>
</body>
</html>
@import "./variables.scss";
header {
color: #ffffff;
background: $color-primary;
height: 100px;
font-size: 64px;
}
import $ from 'jquery';
$(() => {
console.log('hello');
});
在进行粘贴后,运行npm run webpack或./gradlew webpack,就会显示一个简单的问候画面!
你好像也在控制台打招呼了。
(控制台内的错误可能是扩展功能导致的。)
由于解决了tailwindcss的一些问题,所以我决定在2022年8月18日引入并试用daisyUI。
如果在webpack中使用postcss-loader,postcss的插件将能够运行,并且可以按照标准方式使用tailwindcss。
既然如此,让我们试试使用tailwindcss的插件daisyUI吧。
npx tailwindcss init -p
npm install --save-dev postcss-loader daisyui
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta charset="utf-8" />
<!-- tailwindcss のスタイルシートを消去 -->
<link rel="stylesheet" th:href="@{/css/style.css}" />
</head>
<body>
<header class="text-center font-bold">
<span th:text="${message}" class="text-5xl"></span>
</header>
<!-- button 追加 -->
<div class="w-full h-24 text-center">
<button class="btn btn-primary">OK</button>
</div>
<script th:src="@{/js/main.bundle.js}"></script>
</body>
</html>
import '../css/style.scss'
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{html,js}"],
theme: {
extend: {},
},
// daisyuiを呼び出す
plugins: [require('daisyui')],
}
...
new MiniCssExtractPlugin({
// cssを別ファイルとして書き出し
filename: './css/style.css',
}),
...
{
test: /\.(sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
// .css 内の URL パスなどをそれぞれの publicPath に合わせてくれる
'css-loader',
// postcssを使う
'postcss-loader',
// .sass のビルド
'sass-loader',
],
},
...
以下的布局还没有整理好,但已经加入了daisyUI!
我在下面的文章中介绍了daisyUI(我自己)。
到最后
如果有能力使用React+Spring Boot,我觉得可以引入一个方便运行前端并且容易与服务器端分离的机制,因此对于熟悉它的人来说,我觉得那条路更好。
由于业务团队成员都是开发和JS初学者,因此我们选择了这样一种稍显陈旧的JS配置,以便能够学习有关JS的知识。
非常感谢您耐心阅读这么长的文章。