1. Introducción
La contenedorización front-end es una tecnología que empaqueta aplicaciones front-end en contenedores para que puedan implementarse y ejecutarse de manera rápida y eficiente en diferentes entornos.
2. Fondo
La tendencia a separar el front-end y el back-end ha tomado forma. La complejidad de la ingeniería del front-end está aumentando. Habrá diferencias en los entornos y las versiones de Node.js en las que se basan las implementaciones de proyectos nuevos y antiguos. y los archivos de recursos estáticos en el entorno de producción dependen del acceso al servicio de implementación del entorno, la ingeniería front-end no pudo formar una implementación de "artefacto único" y la aparición de contenedores simplificó enormemente el proceso de implementación.
La contenedorización front-end puede administrar fácilmente la inyección de variables del entorno front-end y el entorno de ejecución (diferentes proyectos dependen de diferentes entornos de nodos, la compatibilidad de las versiones de los nodos es un gran problema), ahorra costos de servidor, una reversión de versiones más rápida y conveniente y una implementación de múltiples arquitecturas. .Implementación integrada automatizada de CI/CD, DevOps, etc., los beneficios son más de los que puedas imaginar (risas manuales aquí).
Este artículo se basa en el proyecto React combinado con Docker para compartir los cambios provocados por la introducción de la tecnología de contenedores en el front-end.
3. Aplicación de la contenedorización en github.
Github ha lanzado github-action para realizar ci/cd en contenedores. A continuación mostraré un ejemplo del uso de github-action para realizar una entrega automatizada de paquetes npm:
- Cree un nuevo archivo .github/workflows/ci.yml en el directorio raíz del proyecto
- Vaya al sitio web oficial de npm para solicitar un token (específicamente cómo solicitarlo, búsquelo y resuélvalo usted mismo)
- Pegue este código en el archivo ci.yml
- ¡Envíe el código a la rama maestra y automáticamente usará ci/cd para la implementación!
name: CI
on:
push:
branches:
- master
jobs:
build:
# 指定操作系统
runs-on: ubuntu-latest
steps:
# 将代码拉到虚拟机
- name: Checkout repository
uses: actions/checkout@v2
# 指定node版本
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
# 依赖缓存策略
- name: Cache
id: cache-dependencies
uses: actions/cache@v3
with:
path: |
**/node_modules
key: ${
{runner.OS}}-${
{hashFiles('**/pnpm-lock.yaml')}}
- name: Install pnpm
run: npm install -g [email protected]
# 依赖下载
- name: Installing Dependencies
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: pnpm install
# 打包
- name: Running Build
run: pnpm run build
# 测试
- name: Running Test
run: pnpm run test-unit
# 发布
- name: Running Publish
run: npm publish
env:
# NPM_TOKEN is access token
NODE_AUTH_TOKEN: ${
{ secrets.NPM_TOKEN }}
4. Cree una imagen de front-end basada en Docker
Antes de aprender cómo construir el proyecto front-end ci/cd, primero aprendamos cómo construir la imagen front-end.
4.1 Instalar la ventana acoplable
Haga clic aquí para volar e instalar Docker.
Una vez completada la instalación, ejecute el siguiente comando para verificar la versión de Docker. Intente traer la versión buildx.
docker -v
Docker version 24.0.2, build cb74dfc
4.2 Escribir un archivo Docker
Aquí primero necesitamos popularizar el conocimiento de ingeniería front-end. Todos sabemos que un proyecto basado en npm requiere un archivo package.json, y luego ejecutar npm run install para descargar el paquete y npm run build para empaquetarlo. El archivo empaquetado no puede ejecutar directamente. Inicie un servicio de nodo para ejecutar, por lo que escribiremos la imagen más básica basada en nodo y nginx. El ejemplo es el siguiente
Agregue un archivo de configuración de nginx en el directorio raíz del proyecto, llamado nginx.conf, con el siguiente contenido
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
tcp_nodelay on;
keepalive_timeout 30;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/front/dist;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
location / {
try_files $uri $uri/ =404;
index index.html index.htm;
gzip_static on;
expires max;
add_header Cache-Control public;
if ($request_filename ~* ^.*?\.(eot)|(ttf)|(woff)|(svg)|(otf)$) {
add_header Access-Control-Allow-Origin *;
}
}
}
}
Agregue un archivo de configuración de Docker en el directorio raíz del proyecto, llamado Dockerfile, con el siguiente contenido
FROM node:17-buster as builder
WORKDIR /src
COPY ./ /src
RUN npm install -g pnpm \
&& pnpm install \
&& pnpm build
FROM nginx:alpine-slim
RUN mkdir /usr/share/nginx/front \
&& mkdir /usr/share/nginx/front/dist \
&& rm -rf /etc/nginx/nginx.conf
COPY --from=builder /src/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /src/dist /usr/share/nginx/front/dist
EXPOSE 80
A continuación, use Docker Build para empaquetar la imagen (si tiene una herramienta de escritorio, puede verla en la columna de imágenes de la herramienta de escritorio Docker después de que el empaquetado sea exitoso) y Docker Run para ejecutar la imagen (si tiene una herramienta de escritorio). herramienta, puede verlo en la columna de contenedores de la herramienta de escritorio de Docker después de que la ejecución sea exitosa), después de que la ejecución de Docker se haya ejecutado exitosamente, puede abrir el navegador e ingresar: http://localhost para ver
docker buildx build -t webapp-demo:v1 .
docker run -d -p 80:80 webapp-demo:v1
4.3 Cómo realizar el almacenamiento en caché pnpm basado en Dockerfile
Aquí cito un pasaje:
Al usar la compilación de varias etapas, la imagen creada solo contiene la carpeta de destino dist, pero todavía hay algunos problemas. Cuando el archivo package.json cambia, RUN npm i && rm -rf ~/.npm La capa Se volverá a ejecutar y, después de múltiples cambios, se generará una gran cantidad de imágenes de capa intermedia.
Para resolver este problema, podemos imaginar una función similar a un volumen de datos y montar la carpeta node_modules al crear la imagen. Una vez completada la construcción, la carpeta node_modules se desinstalará automáticamente. La imagen real no contiene node_modules. Esto La carpeta nos ahorra el tiempo de obtener dependencias cada vez, aumenta en gran medida la eficiencia de la construcción de imágenes y también evita generar una gran cantidad de imágenes intermedias.
El representante de la clase aquí resume: Es para minimizar la posibilidad de imágenes de capa intermedia y minimizar el tamaño de la imagen acoplable y el tiempo de construcción.
Como estoy usando pnpm para la administración de paquetes npm, revisé la documentación oficial de pnpm sobre esta optimización de la siguiente manera:
FROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY . /app
WORKDIR /app
FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
FROM base AS build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build
FROM base
COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
EXPOSE 8000
CMD [ "pnpm", "start" ]
Entonces, con el espíritu de copiar la calabaza y usar la configuración de producción de nginx, encontré la imagen de empaquetado de nginx escrita por mi colega. También puede ejecutar Docker Build y Docker Run para verificar, y luego mi código modificado es el siguiente:
FROM node:17-buster AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
WORKDIR /src
COPY ./ /src
RUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked \
--mount=type=cache,target=/pnpm/store,id=pnpm_cache \
pnpm install
RUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked \
pnpm run build
FROM ghcr.io/zboyco/webrunner:0.0.7
COPY --from=builder /src/dist /app
4.4 Cómo usar buildx para crear imágenes de múltiples arquitecturas
La herramienta Docker Buildx, para decirlo sin rodeos, le proporciona la capacidad. Cuando su host tiene una arquitectura x86 64 y desea crear una imagen con una arquitectura ARM64, necesita esta herramienta. Se siente un poco como una compilación cruzada. , como: La compilación cruzada de go build, la compilación de programas ejecutables en win10, se puede utilizar en plataformas Linux específicas
Básicamente, Buildx llama a la API del kit de compilación y la compilación se realiza en el entorno del kit de compilación. Si se admiten múltiples arquitecturas depende del entorno del kit de compilación. Si necesita que el kit de compilación admita múltiples arquitecturas, debe ejecutarlo en la máquina host (por supuesto, esto no es necesario, se controla de acuerdo con los requisitos de compilación). La versión de escritorio no necesita establecer esta configuración):
docker run --privileged --rm tonistiigi/binfmt --install all
Aquí modificamos el código de Dockerfile anterior para admitir múltiples arquitecturas. Dado que la plataforma es experimental, primero debemos ejecutar docker pull docker/dockerfile para extraer la imagen.
# syntax = docker/dockerfile:experimental
# --platform, 会让 builder 只会有一份,且 arch 与宿主机一致
FROM --platform=${BUILDPLATFORM:-linux/amd64} node:17-buster AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
WORKDIR /src
COPY ./ /src
RUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked \
--mount=type=cache,target=/pnpm/store,id=pnpm_cache \
pnpm install
RUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked \
pnpm run build
FROM ghcr.io/zboyco/webrunner:0.0.7
COPY --from=builder /src/dist /app
Antes de ejecutar el comando de imagen del paquete, primero verificamos la instancia del generador predeterminado de nuestra máquina.
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default docker
default default running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux * docker
desktop-linux desktop-linux running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
El uso de buildx para ejecutar el script anterior para empaquetar la imagen informará el siguiente error:
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t webapp-official-website:v1 .
ERROR: Multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
Dado que la instancia del generador predeterminada de Docker no admite la especificación de múltiples plataformas al mismo tiempo, primero debemos crear una nueva instancia del generador. Al mismo tiempo, debido a que extraer imágenes en China es lento, podemos usar la imagen dockerpracticesig/buildkit:master configurada con la dirección de aceleración de la imagen para reemplazar la imagen oficial.
Si tiene un acelerador de imágenes privado, puede crear su propia imagen de kit de compilación basada en https://github.com/docker-practice/buildx y utilizarla.
# 适用于国内环境
$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master
# 适用于腾讯云环境(腾讯云主机、coding.net 持续集成)
$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent
# $ docker buildx create --name mybuilder --driver docker-container
$ docker buildx use mybuilder
Elegimos el comando adecuado para el entorno doméstico para crear la solución, puedes ver que hay más instancias llamadas mybuilder-cn.
docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder-cn * docker-container
mybuilder-cn0 desktop-linux inactive
default docker
default default running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux docker
desktop-linux desktop-linux running v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
$ docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t myusername/hello . --push
# 查看镜像信息
$ docker buildx imagetools inspect myusername/hello
Ejecute la imagen en diferentes arquitecturas para obtener información sobre la arquitectura.
$ docker run -it --rm myusername/hello
5. Cómo utilizar la contenedorización para la inyección de variables de entorno front-end
- Aunque la interfaz no requiere muchas variables de entorno, se necesitan la API básica baseURL, appName y env.
- Si se trata de un escenario de micro front-end, entonces las URL requeridas de otros sitios web son variables de entorno, y hay muchas.
- Recuerdo vagamente que cuando entré por primera vez a la industria, el front-end distinguía el entorno de prueba y el entorno en línea se juzgaba directamente por el nombre de dominio, por ejemplo: inlcudes (url, ".com")?, y luego obtuve isProd para obtener las variables de diferentes ambientes configurados en el proyecto, las cuales me parecieron Muy bajas
- Los marcos como vue y reaccionar aparecieron más tarde. Puede especificar –prod cuando npm ejecuta dev y luego obtener isProd a través del proceso para obtener la configuración correspondiente.
- Ahora puede inyectar variables de entorno directamente a través de la contenedorización y luego usar nginx para inyectar las variables de entorno en el contenedor en el contenido de la metaetiqueta del html del proyecto front-end y luego obtener las variables de la metaetiqueta.
- Si es un proyecto monorepo, cuando npm ejecuta la compilación, Dockerfile también necesita usar las variables de entorno en el contenedor para obtener qué proyecto empaquetar.
- El entorno de prueba configura las variables de entorno a través de archivos ts y luego combina la información de estas variables de entorno cuando el proyecto comienza a generar la configuración default.yml. Cuando ci / cd, k8s escribe automáticamente las variables de entorno configuradas en default.yml en el contenedor.
- El entorno en línea proporciona directamente una página de interfaz de usuario para configurar las variables de entorno y luego llama a la API, y la API de back-end escribe las variables en el contenedor a través de k8s.
- Cómo leer las variables de entorno configuradas a través de k8s y escribirlas en el contenedor y escuchar la descomposición la próxima vez
A continuación se muestra un código de muestra de Dockerfile en un escenario de producción (¡la compañía probablemente no me matará!) Aquí omitimos cómo k8s inyecta variables de entorno en el contenedor y solo considera cómo leer las variables de entorno del contenedor (suponiendo que el entorno Se han inyectado variables en el contenedor))
FROM --platform=${BUILDPLATFORM} hub-dev.rockontrol.com/rk-infrav2/docker.io/library/node:17-bullseye as builder
WORKDIR /src
COPY ./ ./
ARG APP
ARG ENV
ARG PROJECT_GROUP
ARG PROJECT_NAME
ARG PROJECT_VERSION
ARG YARN_NPM_REGISTRY_SERVER
RUN npm install -g --registry=${YARN_NPM_REGISTRY_SERVER} pnpm
RUN pnpm --registry=${YARN_NPM_REGISTRY_SERVER} install
RUN PROJECT_GROUP=${PROJECT_GROUP} PROJECT_VERSION=${PROJECT_VERSION} \
npx devkit build --prod ${APP} ${ENV}
FROM hub-dev.rockontrol.com/rk-infrav2/ghcr.io/zboyco/webrunner:0.0.7
ARG PROJECT_NAME
COPY --from=builder /src/public/${PROJECT_NAME} /app
A continuación se muestra un fragmento de código que muestra cómo nginx combina variables de entorno y usa la configuración de nginx para escribirlas en la etiqueta mate de HTML.
#!/bin/sh
# This script is used to start the application
# 初始化一个字符串,用于存储拼接后的值
app_config="${APP_CONFIG}"
ext_config=""
# 遍历所有环境变量
for var in $(env | cut -d= -f1); do
# 检查变量是否以 "APP_CONFIG__" 开头
if [ "$(echo "$var" | grep '^APP_CONFIG__')" ]; then
# 去除变量名前缀 "APP_CONFIG__"
trimmed_var=$(echo "$var" | sed 's/^APP_CONFIG__//')
# 使用 eval 来获取变量值并拼接到字符串中
value=$(eval echo "\$$var")
app_config="${app_config},${trimmed_var}=${value}"
fi
done
# 去掉起始的逗号
export app_config=$(echo "$app_config" | sed 's/^,//')
# 解析app_config变量
# 以,分割 app_config
IFS=","
set -- $app_config
# 遍历数组
for config in "$@"; do
# 以等号分剥数组
IFS="="
set -- $config
# 将单个环境变量单独注入
ext_config="${ext_config} sub_filter '__$1__' '$2';\n"
echo "$1: $2"
done
# Install envsubst
echo "Installing envsubst"
# 将扩展变量替换到 conf.template 中
sed "s@__EXTENT_CONFIG__@${ext_config}@g" /etc/nginx/conf.d/conf-base.template > /etc/nginx/conf.d/conf.template
envsubst '${PROJECT_VERSION} ${ENV} ${app_config}' < /etc/nginx/conf.d/conf.template > /etc/nginx/conf.d/default.conf
# Start nginx
echo "Starting nginx"
nginx -g 'daemon off;'
Código de configuración de nginx, el marcador de posición de la etiqueta mate se reemplazará con la variable de entorno real, consulte sub_filter en el código
server {
listen 80;
listen [::]:80;
server_name localhost;
root /app;
#开启gzip
gzip on;
#低于1kb的资源不压缩
gzip_min_length 1k;
#压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在5左右。
gzip_comp_level 6;
#需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片.
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
location ~ ^/(static|__built__)/ {
root /app;
expires max;
proxy_cache static_memory_cache; # 使用内存缓存
proxy_cache_valid 200 1d;
proxy_cache_lock on;
}
location / {
expires -1;
try_files $uri /index.html;
add_header X-Frame-Options sameorigin;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1;mode=block" always;
sub_filter '__PROJECT_VERSION__' '$PROJECT_VERSION';
sub_filter '__ENV__' '$ENV';
sub_filter '__APP_CONFIG__' '$app_config';
# 需要将以下字符串替换为注入的扩展环境变量
__EXTENT_CONFIG__
sub_filter_once on;
}
}
A continuación se muestra una sección sobre cómo el front-end lee las variables de entorno de las metaetiquetas html.
import appConfig from "../../config";
interface IConfig {
appName: string;
baseURL: string;
version?: string;
env?: string;
}
export function getConfig(): IConfig {
const defaultAppConfig = {
appName: "",
version: "",
env: "",
baseURL: "",
};
console.log("metaEnv", import.meta.env);
if (import.meta.env.DEV) {
return appConfig;
} else {
const appConfigStr = getMeta("app_config");
if (!appConfigStr) return defaultAppConfig;
return parseEnvVar(appConfigStr);
}
}
function getMeta(metaName: string) {
const metas = document.getElementsByTagName("meta");
for (let i = 0; i < metas.length; i++) {
if (metas[i].getAttribute("name") === metaName) {
return metas[i].getAttribute("content");
}
}
return "";
}
function parseEnvVar(envVarURL: string) {
const arrs = envVarURL.split(",");
return arrs.reduce((pre, item) => {
const keyValues = item.split("=");
return {
...pre,
[keyValues[0]]: keyValues[1],
};
}, {
} as IConfig);
}
const BASE_URL = getConfig().baseURL;
const instance = axios.create({
baseURL: BASE_URL,
headers: {
"Content-Type": "application/json",
},
timeout: 60000, // 超时时间60秒
});
Finalmente, se publicó el Dockerfile, ¡así que publiquemos el código fuente del archivo ci en un escenario real! ! !
stages:
- ship
- deploy
ship:
stage: ship
image: hub-dev.rockontrol.com/rk-infrav2/gitlab-runner-buildx:0.0.0-b0450fe
# variables:
# MULTI_ARCH_BUILDER: 1
before_script:
- echo "${DOCKER_PASSWORD}" | docker login "${DOCKER_REGISTRY}" -u="${DOCKER_USERNAME}" --password-stdin
- BUILDKIT_NAME=node-buildkit hx buildx ci-setup
script:
- export PLATFORM=linux/amd64,linux/arm64
- |
if [[ -f ./.platform ]]; then
source ./.platform
else
echo "WARNING, there is no .platform in project, USE default PLATFORM=${PLATFORM} "
fi
- hx buildx --with-builder --push --platform=${PLATFORM}
tags:
- webapp
deploy:
stage: deploy
script:
- hx config
- hx deploy
dependencies:
- ship
tags:
- webapp
6. Implementación de aplicaciones front-end en Kubernetes
Kubernetes es una plataforma de orquestación de contenedores de código abierto que puede automatizar la implementación, el escalado y la gestión de aplicaciones en contenedores. Estos son los pasos para implementar una aplicación front-end en un clúster de Kubernetes:
6.1 Crear implementación
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-app
spec:
replicas: 3
selector:
matchLabels:
app: frontend-app
template:
metadata:
labels:
app: frontend-app
spec:
containers:
- name: frontend-app
image: my-frontend-app:latest
ports:
- containerPort: 3000
6.2 Crear servicio
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
6.3 Implementar en el clúster de Kubernetes
Utilice el comando kubectl para implementar la aplicación en el clúster de Kubernetes:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Ahora, su aplicación de front-end se ejecuta en el clúster de Kubernetes y se puede acceder a ella externamente a través del servicio tipo LoadBalancer.
7. Acerca de la arquitectura del proyecto front-end React
7.1 Tecnología central
- Empaquetar y compilar- vite
- Gestión de paquetes - pnpm
- Lenguaje de programación - mecanografiado
- Marco front-end: reaccionar
- enrutamiento- reaccionar-enrutador
- Biblioteca de componentes de UI : antd
- cssinjs (sin considerar los gastos generales de rendimiento) - emoción
- Intercambio global de datos - zustand
- Generar API automáticamente - openapi
- Solicitudes de red - axios
- Herramienta de solicitud de datos - reaccionar-query
- Gancho general (opcional) - ahooks
- Límite de error - reaccionar-error-límite
- Registro de front-end (aún no integrado) - sentry-javascript
- hackear - babel
- Inspección de código - eslint
- Complemento de inspección de código ts- TypeScript-eslint
- Embellecimiento del código: más bonito
- git gancho- husky
- formato de confirmación - commitlint
7.2 Obtener automáticamente la función de solicitud de API basada en openapi
// src/core/openapi/index.ts
// 示例代码
generateService({
// openapi地址
schemaPath: `${
appConfig.baseURL}/${
urlPath}`,
// 文件生成目录
serversPath: "./src",
// 自定义网络请求函数路径
requestImportStatement: `/// <reference types="./typings.d.ts" />\nimport request from "@request"`,
// 代码组织命名空间, 例如:Api
namespace: "Api",
});
7.3 Interfaz de llamada (react-query), admite carga automática y enlace de solicitud de interfaz
// HelloGet是一个基于axios的promise请求
export async function HelloGet(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: Api.HelloGetParams,
options?: {
[key: string]: any },
) {
return request<Api.HelloResp>('/gin-demo-server/api/v1/hello', {
method: 'GET',
params: {
...params,
},
...(options || {
}),
});
}
// 自动调用接口获取数据
const {
data, isLoading } = useQuery({
queryKey: ["hello", name],
queryFn: () => {
return HelloGet({
name: name });
},
});
export async function HelloPost(body: Api.HelloPostParam, options?: {
[key: string]: any }) {
return request<Api.HelloResp>('/gin-demo-server/api/v1/hello', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {
}),
});
}
// 提交编辑数据
const {
mutate, isLoading } = useMutation({
mutationFn: HelloPost,
onSuccess(data) {
setName(data?.data || "");
},
onError() {
// 清除queryKey为hello的接口数据缓存,自动重新获取接口数据
queryClient.invalidateQueries({
queryKey: ['hello'] });
}
})
mutate({
name: "lisi" });
8. CLI del código React de front-end
9. Conclusión
- Se introdujo la configuración básica de gitlab-action en el campo npm del front-end.
- Presenta la escritura de archivos Dockerfile de front-end, así como el plan de optimización de pnpm en Docker y cómo usar buildx para generar imágenes de múltiples arquitecturas de front-end.
- Introduce el uso de variables de entorno front-end en escenarios de producción.
- Presentamos el plan de arquitectura técnica del proyecto front-end React