diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..861765276 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +.vscode/ diff --git a/.env.docker b/.env.docker new file mode 100644 index 000000000..2e4117be9 --- /dev/null +++ b/.env.docker @@ -0,0 +1,22 @@ +# Whether to open mock +VITE_USE_MOCK = false + +# public path +VITE_PUBLIC_PATH = / + +# timeout(seconds) +VITE_TIMEOUT = 15 +# Delete console +VITE_DROP_CONSOLE = true + +# Whether to enable gzip or brotli compression +# Optional: gzip | brotli | none +# If you need multiple forms, you can use `,` to separate +VITE_BUILD_COMPRESS = 'none' +VITE_GLOB_API_URL="__vg_base_url" + +# File upload address, optional +# It can be forwarded by nginx or write the actual address directly +VITE_GLOB_UPLOAD_URL=/files/upload +# Interface prefix +VITE_GLOB_API_URL_PREFIX= diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..13112f6fc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +# node 构建 +FROM node:16-alpine as build-stage +# 署名 +MAINTAINER Adoin 'adoin@qq.com' +WORKDIR /app +COPY . ./ +# 设置 node 阿里镜像 +RUN npm config set registry https://registry.npm.taobao.org +# 设置--max-old-space-size +ENV NODE_OPTIONS=--max-old-space-size=16384 +# 设置阿里镜像、pnpm、依赖、编译 +RUN npm install pnpm -g && \ + pnpm install --frozen-lockfile && \ + pnpm build:docker +# node部分结束 +RUN echo "🎉 编 🎉 译 🎉 成 🎉 功 🎉" +# nginx 部署 +FROM nginx:1.23.3-alpine as production-stage +COPY --from=build-stage /app/dist /usr/share/nginx/html/dist +COPY --from=build-stage /app/nginx.conf /etc/nginx/nginx.conf +EXPOSE 80 +## 将/usr/share/nginx/html/dist/assets/index.js 和/usr/share/nginx/html/dist/_app.config.js中的"$vg_base_url"替换为环境变量中的VG_BASE_URL,$vg_sub_domain 替换成VG_SUB_DOMAIN,$vg_default_user替换成VG_DEFAULT_USER,$vg_default_password替换成VG_DEFAULT_PASSWORD 而后启动nginx +CMD sed -i "s|__vg_base_url|$VG_BASE_URL|g" /usr/share/nginx/html/dist/assets/index.js && \ + sed -i "s|__vg_base_url|$VG_BASE_URL|g" /usr/share/nginx/html/dist/_app.config.js && \ + nginx -g 'daemon off;' +RUN echo "🎉 架 🎉 设 🎉 成 🎉 功 🎉" diff --git a/README.md b/README.md index da318bf6d..f51337e45 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,24 @@ pnpm serve pnpm build ``` +- docker + +### The dockerFile is located in the project root directory and supports differential deployment + +#### build image + +```bash +docker build -t vue-vben-admin . +``` + +#### Environment variables are dynamically used to achieve differentiated container deployment. Different VG_BASE_URL environment variables point to different back-end service addresses. In the following example, http://localhost:3333 is used as the back-end service address and the container is mapped to port 6666 + +```bash +docker run --name vue-vben-admin -d -p 6666:80 -e VG_BASE_URL=http://localhost:3333 vue-vben-admin +``` + +Then you can navigate http://localhost:6666 + ## Change Log [CHANGELOG](./CHANGELOG.zh_CN.md) diff --git a/README.zh-CN.md b/README.zh-CN.md index 73667a57a..defc5aebf 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -86,6 +86,24 @@ pnpm serve pnpm build ``` +- docker + +### dockerFile 位于项目根目录下 并且支持差异化部署 + +#### 构建镜像 + +```bash +docker build -t vue-vben-admin . +``` + +#### 动态使用环境变量实现容器差异化部署,通过不同的 VG_BASE_URL 环境变量,指向不同的后端服务地址,下面例子使用 http://localhost:3333 作为后端服务地址,并且将容器映射到 6666 端口 + +```bash +docker run --name vue-vben-admin -d -p 6666:80 -e VG_BASE_URL=http://localhost:3333 vue-vben-admin +``` + +而后可以打开 http://localhost:6666 访问 + ## 更新日志 [CHANGELOG](./CHANGELOG.zh_CN.md) diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts index 92c693421..eb8d58420 100644 --- a/internal/vite-config/src/config/application.ts +++ b/internal/vite-config/src/config/application.ts @@ -69,6 +69,8 @@ function defineApplicationConfig(defineOptions: DefineOptions = {}) { cssTarget: 'chrome80', rollupOptions: { output: { + // 入口文件名 + entryFileNames: 'assets/[name].js', manualChunks: { vue: ['vue', 'pinia', 'vue-router'], antd: ['ant-design-vue', '@ant-design/icons-vue'], diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts index 79aae58cf..a5fcf0f67 100644 --- a/internal/vite-config/src/plugins/index.ts +++ b/internal/vite-config/src/plugins/index.ts @@ -4,6 +4,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'; import DefineOptions from 'unplugin-vue-define-options/vite'; import { type PluginOption } from 'vite'; import purgeIcons from 'vite-plugin-purge-icons'; +import vueSetupExtend from 'vite-plugin-vue-setup-extend'; import { createAppConfigPlugin } from './appConfig'; import { configCompressPlugin } from './compress'; @@ -11,7 +12,7 @@ import { configHtmlPlugin } from './html'; import { configMockPlugin } from './mock'; import { configSvgIconsPlugin } from './svgSprite'; import { configVisualizerConfig } from './visualizer'; -import vueSetupExtend from 'vite-plugin-vue-setup-extend'; + interface Options { isBuild: boolean; root: string; diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 000000000..c6e81898a --- /dev/null +++ b/nginx.conf @@ -0,0 +1,37 @@ +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +#pid logs/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + server { + listen 80; + location / { + root /usr/share/nginx/html/dist; + try_files $uri $uri/ /index.html; + index index.html; + # Enable CORS + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } +} +} diff --git a/package.json b/package.json index 4d4365316..b3d1886b0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "bootstrap": "pnpm install", "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build", "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze", + "build:docker": "vite build --mode docker", "build:no-cache": "pnpm clean:cache && npm run build", "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode test", "commit": "czg", @@ -103,7 +104,7 @@ "vue-router": "^4.1.6", "vue-types": "^5.0.2", "vuedraggable": "^4.1.0", - "vxe-table": "^4.3.11", + "vxe-table": "^4.4.5", "vxe-table-plugin-export-xlsx": "^3.0.4", "xe-utils": "^3.5.7", "xlsx": "^0.18.5" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69bb27825..3386f4ff2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + importers: .: @@ -97,9 +101,6 @@ importers: vditor: specifier: ^3.9.1 version: 3.9.1 - vite-plugin-vue-setup-extend: - specifier: ^0.4.0 - version: 0.4.0(vite@4.3.0-beta.2) vue: specifier: ^3.2.47 version: 3.2.47 @@ -119,11 +120,11 @@ importers: specifier: ^4.1.0 version: 4.1.0(vue@3.2.47) vxe-table: - specifier: ^4.3.11 - version: 4.3.11(vue@3.2.47)(xe-utils@3.5.7) + specifier: ^4.4.5 + version: 4.4.5(vue@3.2.47)(xe-utils@3.5.7) vxe-table-plugin-export-xlsx: specifier: ^3.0.4 - version: 3.0.4(vxe-table@4.3.11) + version: 3.0.4(vxe-table@4.4.5) xe-utils: specifier: ^3.5.7 version: 3.5.7 @@ -236,6 +237,9 @@ importers: vite-plugin-mock: specifier: ^2.9.6 version: 2.9.6(mockjs@1.1.0)(rollup@2.79.1)(vite@4.3.0-beta.2) + vite-plugin-vue-setup-extend: + specifier: ^0.4.0 + version: 0.4.0(vite@4.3.0-beta.2) vue-tsc: specifier: ^1.2.0 version: 1.2.0(typescript@5.0.3) @@ -2436,7 +2440,7 @@ packages: dependencies: '@volar/language-core': 1.3.0-alpha.0 '@volar/source-map': 1.3.0-alpha.0 - '@vue/compiler-dom': 3.2.47 + '@vue/compiler-dom': 3.3.4 '@vue/compiler-sfc': 3.2.47 '@vue/reactivity': 3.2.47 '@vue/shared': 3.2.47 @@ -2622,7 +2626,7 @@ packages: js-beautify: 1.14.6 vue: 3.2.47 optionalDependencies: - '@vue/compiler-dom': 3.2.47 + '@vue/compiler-dom': 3.3.4 '@vue/server-renderer': 3.2.47(vue@3.2.47) dev: true @@ -9673,7 +9677,7 @@ packages: '@vue/compiler-sfc': 3.2.47 magic-string: 0.25.9 vite: 4.3.0-beta.2(@types/node@18.15.11)(less@4.1.3)(sass@1.60.0) - dev: false + dev: true /vite@4.3.0-beta.2(@types/node@18.15.11)(less@4.1.3)(sass@1.60.0): resolution: {integrity: sha512-RRghM7RiRnwknCG3hS+NE8C+N3CNX4yKfVhFxO3NqrtYErN6htac//De9IwIHWqgV8DdKoNPeK8Yb/FOlZvjoQ==} @@ -9851,16 +9855,16 @@ packages: vue: 3.2.47 dev: false - /vxe-table-plugin-export-xlsx@3.0.4(vxe-table@4.3.11): + /vxe-table-plugin-export-xlsx@3.0.4(vxe-table@4.4.5): resolution: {integrity: sha512-Og/NbXRIb+BS6sJ48oDNVrZnlkcpaCd/zS8JBAZjHLgioWr1Xoob6FEpaeXBebGPPgTumZNUrrBO57JhhYAerA==} peerDependencies: vxe-table: ^4.0.27 dependencies: - vxe-table: 4.3.11(vue@3.2.47)(xe-utils@3.5.7) + vxe-table: 4.4.5(vue@3.2.47)(xe-utils@3.5.7) dev: false - /vxe-table@4.3.11(vue@3.2.47)(xe-utils@3.5.7): - resolution: {integrity: sha512-n2OXuUaKurVxxhRz0b1DojLdvtYwKkidRAqI9oGDw2IQ0y2IPs2Oq+lX2V6ar3glFdjjkS3BqnDBAk0elt6e0Q==} + /vxe-table@4.4.5(vue@3.2.47)(xe-utils@3.5.7): + resolution: {integrity: sha512-5huB/p0pVgFZjH/abLkWBFnBFe/9mozdQmbXehiGZJHQ6KfzLEsqpKbPsKAnMYEhezPmH4igdhYkXxb7ohWbTA==} peerDependencies: vue: ^3.2.28 xe-utils: ^3.5.0