在业务中使用Spring Boot和webpack进行环境配置的备忘录

首先

在业务新进人员策略中,
经过团队内的共识形成后,我们决定以SpringBoot为基础,
然后对于我们在公司内可以使用的技术,被告知可以自由选择,
因此,我首先想到了npm。

我认为这个原因是因为我希望能够在Spring Boot中开发时使用不仅仅是准备一个js文件,还要结合一些周边技术,比如包管理器和打包工具。所以,首先我会尝试安装npm。

以下是源代码。
(提交信息有点随便。对不起。)

 

创建者规格

    • Jsはそこそこに書けるけど、実務の経験はないので客観的にできるとは言えないかも?

 

    • モダンJSはReactもVueも一応書ける

 

    • モジュールバンドラーからは逃げてきました

 

    • Spring Bootはまだまだ学習中のため、本業務で身につけていきたい

 

    Spring Boot周りの開発技術はもっとわからない、、、頑張って勉強します

开始SpringBoot项目

请确保本地已经安装了npm,这样会更加方便。请准备好npm和Node.js并尝试一下。

 

スクリーンショット (45).png

我会尝试使用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()
}

这篇文章对于扩展功能会有所帮助。

 

我会参考下面的文章(虽然简单)制作一个大致能运行的东西。

 

这次我们将按照下面的图片所示的目录结构来设计。

スクリーンショット (49).png

用于运行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,就会显示一个简单的问候画面!

スクリーンショット (51).png

你好像也在控制台打招呼了。
(控制台内的错误可能是扩展功能导致的。)

由于解决了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!

スクリーンショット (54).png

我在下面的文章中介绍了daisyUI(我自己)。

 

到最后

如果有能力使用React+Spring Boot,我觉得可以引入一个方便运行前端并且容易与服务器端分离的机制,因此对于熟悉它的人来说,我觉得那条路更好。

由于业务团队成员都是开发和JS初学者,因此我们选择了这样一种稍显陈旧的JS配置,以便能够学习有关JS的知识。

非常感谢您耐心阅读这么长的文章。

广告
将在 10 秒后关闭
bannerAds