├── .dockerignore
├── env.d.ts
├── .env.test
├── .env.development
├── public
└── favicon.ico
├── src
├── assets
│ ├── main.css
│ ├── logo.svg
│ ├── icons
│ │ └── github.svg
│ └── base.css
├── App.vue
├── main.ts
└── components
│ └── Welcome.vue
├── scripts
├── vars.mjs
├── git.mjs
├── version.mjs
├── changelog.mjs
├── docker.mjs
└── build.mjs
├── .vscode
└── extensions.json
├── .env.production
├── Dockerfile-test
├── Dockerfile-development
├── .prettierrc.json
├── Dockerfile-production
├── nginx.test.conf
├── nginx.development.conf
├── nginx.production.conf
├── CHANGELOG.md
├── tsconfig.json
├── tsconfig.vitest.json
├── index.html
├── .eslintrc.cjs
├── tsconfig.app.json
├── tsconfig.node.json
├── .gitignore
├── uno.config.ts
├── README.md
├── package.json
├── .github
└── workflows
│ └── deploy.yaml
└── vite.config.ts
/.dockerignore:
--------------------------------------------------------------------------------
1 | .github
2 | .vscode
3 | node_modules
--------------------------------------------------------------------------------
/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | #是否移除控制台
2 | VITE_DROP_CONSOLE=false
3 | # 网站前缀
4 | VITE_BASE_URL=/
--------------------------------------------------------------------------------
/.env.development:
--------------------------------------------------------------------------------
1 | #是否移除控制台
2 | VITE_DROP_CONSOLE=false
3 | # 网站前缀
4 | VITE_BASE_URL=/
5 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zerotower69/demo-template/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app{
4 | height: 100%;
5 | width: 100%;
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/vars.mjs:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 |
3 | export const CMD = process.cwd()
4 |
5 | export const PKG_PATH = path.resolve(CMD,'package.json')
6 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "Vue.volar",
4 | "dbaeumer.vscode-eslint",
5 | "esbenp.prettier-vscode"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.env.production:
--------------------------------------------------------------------------------
1 | #是否移除控制台
2 | VITE_DROP_CONSOLE=true
3 | # 网站前缀 按github部署仓库名修改
4 | # 如果仓库名是 scroll-image,则
5 | # VITE_BASE_URL=/scroll-image/
6 | VITE_BASE_URL=/
7 |
--------------------------------------------------------------------------------
/Dockerfile-test:
--------------------------------------------------------------------------------
1 | FROM nginx:stable-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY dist /usr/share/nginx/html/web
6 | COPY ./nginx.test.conf /etc/nginx/conf.d/default.conf
7 |
8 | EXPOSE 80
--------------------------------------------------------------------------------
/Dockerfile-development:
--------------------------------------------------------------------------------
1 | FROM nginx:stable-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY dist /usr/share/nginx/html/web
6 | COPY ./nginx.develpment.conf /etc/nginx/conf.d/default.conf
7 |
8 | EXPOSE 80
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import './assets/main.css'
2 |
3 | import { createApp } from 'vue'
4 | import App from './App.vue'
5 | import "virtual:uno.css"
6 |
7 | const app=createApp(App)
8 | app.mount('#app')
9 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/prettierrc",
3 | "semi": false,
4 | "tabWidth": 2,
5 | "singleQuote": true,
6 | "printWidth": 100,
7 | "trailingComma": "none"
8 | }
--------------------------------------------------------------------------------
/Dockerfile-production:
--------------------------------------------------------------------------------
1 | FROM nginx:stable-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY dist /usr/share/nginx/html/web
6 | COPY ./nginx.production.conf /etc/nginx/conf.d/default.conf
7 |
8 | EXPOSE 80
9 |
10 |
11 |
--------------------------------------------------------------------------------
/nginx.test.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name localhost;
4 |
5 | location / {
6 | root /usr/share/nginx/html/web;
7 | index index.html;
8 | try_files $uri /index.html;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/nginx.development.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name localhost;
4 |
5 | location / {
6 | root /usr/share/nginx/html/web;
7 | index index.html;
8 | try_files $uri /index.html;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/nginx.production.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name localhost;
4 |
5 | location / {
6 | root /usr/share/nginx/html/web;
7 | index index.html;
8 | try_files $uri /index.html;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 更新日志
2 |
3 | ## 1.0.0 (2024-05-25 14:28)
4 |
5 | Y
6 | # 更新日志
7 |
8 | ## 1.0.0 (2024-05-25 14:42)
9 |
10 | feat: vue3模板初步创建完成
11 | # 更新日志
12 |
13 | ## 0.1.0 (2024-05-25 14:13)
14 |
15 | feat: vue3模板初步创建完成
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | {
5 | "path": "./tsconfig.node.json"
6 | },
7 | {
8 | "path": "./tsconfig.app.json"
9 | },
10 | {
11 | "path": "./tsconfig.vitest.json"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tsconfig.vitest.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.app.json",
3 | "exclude": [],
4 | "compilerOptions": {
5 | "composite": true,
6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
7 |
8 | "lib": [],
9 | "types": ["node", "jsdom"]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%- title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | require('@rushstack/eslint-patch/modern-module-resolution')
3 |
4 | module.exports = {
5 | root: true,
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended',
9 | '@vue/eslint-config-typescript',
10 | '@vue/eslint-config-prettier/skip-formatting'
11 | ],
12 | parserOptions: {
13 | ecmaVersion: 'latest'
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4 | "exclude": ["src/**/__tests__/*"],
5 | "compilerOptions": {
6 | "composite": true,
7 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
8 |
9 | "baseUrl": ".",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/node20/tsconfig.json",
3 | "include": [
4 | "vite.config.*",
5 | "cypress.config.*",
6 | "nightwatch.conf.*",
7 | "playwright.config.*"
8 | ],
9 | "compilerOptions": {
10 | "composite": true,
11 | "noEmit": true,
12 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
13 |
14 | "module": "ESNext",
15 | "moduleResolution": "Bundler",
16 | "types": ["node"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | output
14 | docker
15 | dist-ssr
16 | coverage
17 | *.local
18 |
19 | /cypress/videos/
20 | /cypress/screenshots/
21 |
22 | # Editor directories and files
23 | .vscode/*
24 | !.vscode/extensions.json
25 | .idea
26 | *.suo
27 | *.ntvs*
28 | *.njsproj
29 | *.sln
30 | *.sw?
31 |
32 | *.tsbuildinfo
33 | .env.local
34 |
--------------------------------------------------------------------------------
/uno.config.ts:
--------------------------------------------------------------------------------
1 | import {defineConfig,presetIcons,presetAttributify,presetUno} from "unocss"
2 | import {FileSystemIconLoader} from "@iconify/utils/lib/loader/node-loaders"
3 |
4 | export default defineConfig({
5 | presets:[
6 | presetUno({}),
7 | presetAttributify({}),
8 | presetIcons({
9 | collections:{
10 | custom:
11 | FileSystemIconLoader('./src/assets/icons',
12 | svg => svg.replace(/#fff/, 'currentColor'))
13 | }
14 | })
15 | ]
16 | })
--------------------------------------------------------------------------------
/src/components/Welcome.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | vue3示例模板
5 |
10 |
11 |
12 |
24 |
--------------------------------------------------------------------------------
/scripts/git.mjs:
--------------------------------------------------------------------------------
1 | import {execSync} from "child_process"
2 | import dayjs from 'dayjs'
3 |
4 | //get git user
5 | export function getGitUser(){
6 | return execSync('git config user.name').toString('utf8')
7 | }
8 |
9 | /**
10 | * get current info
11 | * @return {{date: string, author: string, id: string, message: string, email: string}}
12 | */
13 | export function getCurrentCommitInfo(){
14 | const message = execSync(`git log -1 --pretty=format:"%H#%s#%an#%ad#%ae"`).toString('utf8')
15 | const list = message.split('#')
16 | return {
17 | id: list[0],
18 | message:list[1],
19 | author:list[2],
20 | date:dayjs(list[3]).format('YYYY-MM-DD HH:mm:ss'),
21 | email:list[4]
22 | }
23 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue3 示例模板
2 |
3 | > vue3快速模板,引入了unocss支持快速示例搭建,并提供完善的打包配置。
4 |
5 | ## 安装依赖
6 |
7 | **项目node版本16起步,如果低于该版本,请考虑使用nvm升级**
8 |
9 | ```bash
10 | npm install
11 | ```
12 |
13 | ## 项目运行
14 |
15 | ```bash
16 | npm run dev
17 | ```
18 |
19 | ## 打包
20 |
21 | ```bash
22 | npm run build #普通打包,会检查ts和eslint错误
23 | npm run build-only #普通打包,不会检查ts错误
24 | npm run build:docker
25 | ```
26 |
27 | ## 配置文件
28 |
29 | 可以前往[.dev.production](/.env.production)文件查看,你可以按注释提示修改
30 | 相关的VITE_ 应用变量来完成相应的应用标题,部署路径的更改
31 |
32 | ## 工作流
33 |
34 | 可以将项目快速部署到github pages,因此你需要注意工作流中使用的node版本和pnpm版本是否和
35 | [package.json](package.json)中一致。如果你的项目输出目录更改后(默认是dist),
36 | 对应[deploy.yaml](.github/workflows/deploy.yaml)文件的部署路径也需要相应地更改。
37 |
38 | ## 其它
39 | 使用上有问题请提issues。
40 |
--------------------------------------------------------------------------------
/scripts/version.mjs:
--------------------------------------------------------------------------------
1 | import fs from "fs"
2 | import {PKG_PATH,CMD} from "./vars.mjs"
3 | import semver from "semver"
4 |
5 | /**
6 | * get package.json info
7 | * @return {Record}
8 | */
9 | export function getPKG(){
10 | const text=fs.readFileSync(PKG_PATH,'utf8');
11 | return JSON.parse(text)
12 | }
13 |
14 | /**
15 | * get app version
16 | * @return {string}
17 | */
18 | export function getVersion(){
19 | return process.env['npm_package_version']
20 | }
21 |
22 | /**
23 | * set app version
24 | * @param {string} version
25 | * @return boolean
26 | */
27 | export function setVersion(version){
28 | try{
29 | const pkg = getPKG();
30 | pkg.version = version;
31 | fs.writeFileSync(PKG_PATH,JSON.stringify(pkg,null,2))
32 | return true
33 | } catch (e){
34 | return false
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/scripts/changelog.mjs:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import {CMD} from "./vars.mjs"
3 | import fs from 'fs'
4 | import dayjs from 'dayjs'
5 | import { getCurrentCommitInfo } from './git.mjs'
6 |
7 | const CHANGELOG_PATH = path.resolve(CMD,'CHANGELOG.md')
8 |
9 | /**
10 | *
11 | * @param {{version:string,startTime:number,message:string}} info
12 | */
13 | export function writeChangelog(info){
14 | const originContent = fs.readFileSync(CHANGELOG_PATH,{encoding:'utf8'})
15 | const time = dayjs(info.startTime).format('YYYY-MM-DD HH:ss')
16 | //info
17 | const title = `\n\n## ${info.version} (${time})`
18 | const gitInfo = getCurrentCommitInfo();
19 | let content = `\n\n${info.message}`
20 | content=title+content
21 | content = '# 更新日志'+content+"\n"+originContent
22 | fs.writeFileSync(CHANGELOG_PATH,content,{encoding:'utf8'})
23 | }
--------------------------------------------------------------------------------
/scripts/docker.mjs:
--------------------------------------------------------------------------------
1 | import os from 'os'
2 | import {execSync} from "child_process"
3 | import fs from 'fs'
4 | import path from 'path'
5 | import { CMD } from './vars.mjs'
6 |
7 | /**
8 | * docker command exit
9 | * @return {boolean}
10 | */
11 | export function exitDocker(){
12 | const platform=os.platform()
13 | const command = platform ==='win32' ? 'where docker':'which docker'
14 | try{
15 | execSync(command).toString('utf8')
16 | return true
17 | } catch (e){
18 | return false
19 | }
20 | }
21 |
22 | /**
23 | *
24 | * @param {string} filepath
25 | */
26 | export function checkConfigPath(filepath){
27 | return fs.existsSync(path.resolve(CMD,filepath))
28 | }
29 |
30 | /**
31 | * check docker deamon
32 | * @return {boolean}
33 | */
34 | export function dockerIsRunning(){
35 | try{
36 | execSync('docker info')
37 | return true
38 | } catch (e){
39 | return false
40 | }
41 | }
42 |
43 | export function beforeValidate(){
44 |
45 | }
46 |
47 | /**
48 | *
49 | * @param {string} name
50 | */
51 | export function buildImage(name){
52 | try{
53 | execSync(`docker ps -q --filter ancestor=${name}`)
54 | } catch (e){
55 |
56 | }
57 | }
--------------------------------------------------------------------------------
/src/assets/icons/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3-demo",
3 | "version": "1.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "preview": "vite preview",
9 | "build": "node scripts/build.mjs",
10 | "test:unit": "vitest",
11 | "build-only": "vite build",
12 | "type-check": "vue-tsc --build --force",
13 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
14 | "format": "prettier --write src/"
15 | },
16 | "dependencies": {
17 | "dayjs": "^1.11.11",
18 | "vue": "^3.4.21"
19 | },
20 | "devDependencies": {
21 | "@iconify/utils": "^2.1.23",
22 | "@rushstack/eslint-patch": "^1.8.0",
23 | "@tsconfig/node20": "^20.1.4",
24 | "@types/consola": "^2.2.5",
25 | "@types/inquirer": "^9.0.7",
26 | "@types/jsdom": "^21.1.6",
27 | "@types/node": "^20.12.5",
28 | "@vitejs/plugin-legacy": "^5.4.0",
29 | "@vitejs/plugin-vue": "^5.0.4",
30 | "@vitejs/plugin-vue-jsx": "^3.1.0",
31 | "@vue/eslint-config-prettier": "^9.0.0",
32 | "@vue/eslint-config-typescript": "^13.0.0",
33 | "@vue/test-utils": "^2.4.5",
34 | "@vue/tsconfig": "^0.5.1",
35 | "chalk": "^5.3.0",
36 | "consola": "^3.2.3",
37 | "eslint": "^8.57.0",
38 | "eslint-plugin-vue": "^9.23.0",
39 | "inquirer": "^9.2.22",
40 | "jsdom": "^24.0.0",
41 | "npm-run-all2": "^6.1.2",
42 | "prettier": "^3.2.5",
43 | "semver": "^7.6.2",
44 | "typescript": "~5.4.0",
45 | "unocss": "^0.60.2",
46 | "vite": "^5.2.8",
47 | "vite-plugin-html": "^3.2.2",
48 | "vite-plugin-progress": "^0.0.7",
49 | "vite-plugin-vue-devtools": "^7.0.25",
50 | "vitest": "^1.4.0",
51 | "vue-tsc": "^2.0.11"
52 | }
53 | }
--------------------------------------------------------------------------------
/src/assets/base.css:
--------------------------------------------------------------------------------
1 | /* color palette from */
2 | :root {
3 | --vt-c-white: #ffffff;
4 | --vt-c-white-soft: #f8f8f8;
5 | --vt-c-white-mute: #f2f2f2;
6 |
7 | --vt-c-black: #181818;
8 | --vt-c-black-soft: #222222;
9 | --vt-c-black-mute: #282828;
10 |
11 | --vt-c-indigo: #2c3e50;
12 |
13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17 |
18 | --vt-c-text-light-1: var(--vt-c-indigo);
19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20 | --vt-c-text-dark-1: var(--vt-c-white);
21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22 | }
23 |
24 | /* semantic color variables for this project */
25 | :root {
26 | --color-background: var(--vt-c-white);
27 | --color-background-soft: var(--vt-c-white-soft);
28 | --color-background-mute: var(--vt-c-white-mute);
29 |
30 | --color-border: var(--vt-c-divider-light-2);
31 | --color-border-hover: var(--vt-c-divider-light-1);
32 |
33 | --color-heading: var(--vt-c-text-light-1);
34 | --color-text: var(--vt-c-text-light-1);
35 |
36 | --section-gap: 160px;
37 | }
38 |
39 | @media (prefers-color-scheme: dark) {
40 | :root {
41 | --color-background: var(--vt-c-black);
42 | --color-background-soft: var(--vt-c-black-soft);
43 | --color-background-mute: var(--vt-c-black-mute);
44 |
45 | --color-border: var(--vt-c-divider-dark-2);
46 | --color-border-hover: var(--vt-c-divider-dark-1);
47 |
48 | --color-heading: var(--vt-c-text-dark-1);
49 | --color-text: var(--vt-c-text-dark-2);
50 | }
51 | }
52 |
53 | *,
54 | *::before,
55 | *::after {
56 | box-sizing: border-box;
57 | margin: 0;
58 | padding: 0;
59 | font-weight: normal;
60 | }
61 |
62 | html,body{
63 | height: 100%;
64 | width: 100%;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yaml:
--------------------------------------------------------------------------------
1 | # 1. 为工作流定义名字
2 | name: Build for scroll-image
3 |
4 | # 2. 触发条件修改为: 当 指定的分支, 有 push 的时候, 执行任务
5 | on:
6 | push:
7 | branches:
8 | # 当代码被推送到这个分支时触发相应的工作流
9 | - gh-pages
10 | # 这个选项可以使你手动在 Action tab 页面触发工作流
11 | workflow_dispatch:
12 |
13 | # 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages。
14 | permissions:
15 | contents: read
16 | pages: write
17 | id-token: write
18 |
19 | # 允许一个并发的部署
20 | concurrency:
21 | group: 'pages'
22 | cancel-in-progress: true
23 |
24 | # 3. 创建工作流
25 | jobs:
26 | deploy: #单次部署的工作描述
27 | # Deploy to the github-pages environment
28 | environment:
29 | name: github-pages
30 | url: ${{ steps.deployment.outputs.page_url }}
31 | runs-on: ubuntu-latest # 依赖环境
32 |
33 | steps: # 工作流步骤
34 | # step 1. 获取源码, 拉取仓库代码
35 | - name: Checkout 🛎️ # 步骤名
36 | uses: actions/checkout@v3 # 使用插件 => https://github.com/actions/checkout
37 |
38 | # step 2. 使用指定版本 node
39 | - name: Use Node 📦 # 步骤名
40 | uses: actions/setup-node@v3 # 使用插件 => https://github.com/actions/setup-node
41 | with: # 插件携带参数
42 | # 记得按最低要求的来
43 | node-version: 16.14.2 # 指定 node 版本
44 | # step 3. 安装pnpm
45 | - name: Install pnpm
46 | uses: pnpm/action-setup@v2
47 | with:
48 | # 如果你指定了pnpm的最低版本要求,需要更改
49 | version: '8.10.0'
50 | # step 4. 安装依赖并打包
51 | - name: Install dependencies
52 | run: pnpm install
53 | - name: Build
54 | run: pnpm build
55 |
56 | - name: Setup Pages
57 | uses: actions/configure-pages@v3
58 | - name: Upload artifact
59 | uses: actions/upload-pages-artifact@v1
60 | with:
61 | # 打包输出的目录,建议保持不动
62 | path: './dist'
63 | - name: Deploy to GitHub Pages
64 | id: deployment
65 | uses: actions/deploy-pages@v2 #使用插件 => https://github.com/actions/deploy-pages
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 |
3 | import { defineConfig, loadEnv } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 | import vueJsx from '@vitejs/plugin-vue-jsx'
6 | import legacy from '@vitejs/plugin-legacy'
7 | import VueDevTools from 'vite-plugin-vue-devtools'
8 | import { createHtmlPlugin } from 'vite-plugin-html'
9 | import UnoCSS from 'unocss/vite'
10 | import ProgressBar from 'vite-plugin-progress'
11 |
12 | // https://vitejs.dev/config/
13 | export default defineConfig((config) => {
14 | const CWD = process.cwd()
15 | const { mode, command } = config
16 | const { VITE_BASE_URL, VITE_TITLE, VITE_DROP_CONSOLE } = loadEnv(mode, CWD)
17 | const currentVersion = process.env['npm_package_version']!
18 | // let buildPath = `output/${mode}/${currentVersion.replaceAll('.','-')}`
19 |
20 | return {
21 | base: VITE_BASE_URL,
22 | server: {
23 | host: '0.0.0.0',
24 | port: 8000
25 | },
26 | plugins: [
27 | vue(),
28 | vueJsx(),
29 | legacy({
30 | targets: ['defaults', 'not IE 11']
31 | }),
32 | VueDevTools(),
33 | createHtmlPlugin({
34 | minify: true,
35 | inject: {
36 | data: {
37 | title: VITE_TITLE
38 | }
39 | }
40 | }),
41 | UnoCSS(),
42 | ProgressBar()
43 | ],
44 | resolve: {
45 | alias: {
46 | '@': fileURLToPath(new URL('./src', import.meta.url))
47 | }
48 | },
49 | //优化
50 | optimizeDeps: {
51 | include: []
52 | },
53 | esbuild: {
54 | pure: VITE_DROP_CONSOLE === 'true' ? ['console.log', 'debugger'] : []
55 | },
56 | //构建目标
57 | build: {
58 | target: 'es2017',
59 | minify: 'esbuild',
60 | cssTarget: 'chrome79',
61 | chunkSizeWarningLimit: 2000,
62 | outDir: 'dist',
63 | //rollupOptions
64 | rollupOptions: {
65 | output: {
66 | entryFileNames: 'js/[name]-[hash].js',
67 | chunkFileNames: 'js/[name]-[hash].js',
68 | assetFileNames(chunkInfo) {
69 | if (chunkInfo.name?.endsWith('.css')) {
70 | return 'css/[name]-[hash].css'
71 | }
72 | const imagesExts = ['.png', 'jpeg', 'jpg', '.svg', '.webp']
73 | if (imagesExts.some((ext) => chunkInfo.name?.endsWith(ext))) {
74 | return 'images/[name]-[hash][ext]'
75 | }
76 | return 'assets/[name]-[hash][ext]'
77 | }
78 | }
79 | }
80 | }
81 | }
82 | })
83 |
--------------------------------------------------------------------------------
/scripts/build.mjs:
--------------------------------------------------------------------------------
1 | import inquirer from 'inquirer'
2 | import semver from 'semver'
3 | import chalk from 'chalk'
4 | import consola from 'consola'
5 | import { execSync } from 'child_process'
6 | import path from 'path'
7 | import fs from 'fs'
8 | import { getVersion, setVersion } from './version.mjs'
9 | import { getCurrentCommitInfo, getGitUser } from './git.mjs'
10 | import { buildImage, dockerIsRunning, exitDocker } from './docker.mjs'
11 | import { writeChangelog } from './changelog.mjs'
12 | import { CMD } from './vars.mjs'
13 | function prompt(){
14 |
15 | //get current version
16 | const currentVersion = getVersion()
17 | const username = getGitUser();
18 | const info = getCurrentCommitInfo()
19 |
20 | const hasDocker = exitDocker()
21 |
22 | const versions ={
23 | major: semver.inc(currentVersion,'major'),
24 | minor:semver.inc(currentVersion,'minor'),
25 | patch:semver.inc(currentVersion,'patch'),
26 | prerelease:semver.inc(currentVersion,'prerelease','beta')
27 | }
28 |
29 | /**
30 | * questions for inquirer
31 | * @type {import('inquirer').Question[]}
32 | */
33 | const questions = [
34 | //step1: build mode
35 | {
36 | type:"list",
37 | name:"mode",
38 | message:"请选择打包模式:",
39 | choices:[
40 | {name:`测试打包`,value:"test"},
41 | {name:"本地开发打包",value:"development"},
42 | {name:"生产打包",value:"production"}
43 | ]
44 | },
45 | //step2: ask to generate version
46 | {
47 | type:"confirm",
48 | name:'updateVersion',
49 | message:`是否更新版本号(当前版本:${currentVersion})?`,
50 | },
51 | //step3: the mode of version
52 | {
53 | type:"list",
54 | name:"version",
55 | message:`请选择你要更新的版本号模式,当前版本号:${currentVersion}`,
56 | choices: [
57 | {name:`大的版本迁移,新建分支,项目结构改变,或者破坏式不兼容的升级(${versions.major})`,value:versions.major},
58 | {name:`新增功能,增加新的库包等(${versions.minor})`,value: versions.minor},
59 | {name:`bug的修复,样式调整、文档修改等(${versions.patch})`,value: versions.patch},
60 | {name:`预览功能打包(${versions.prerelease})`,value: versions.prerelease}
61 | ],
62 | when:(answers)=>{
63 | return answers.updateVersion
64 | }
65 | },
66 | //step4: ask to generate changelog
67 | {
68 | type:"confirm",
69 | name:"useLog",
70 | message:"是否生成changelog",
71 | when:(answers)=>{
72 | return answers.updateVersion
73 | }
74 | },
75 | //step5: input changelog info, default is latest commit message
76 | {
77 | type:"input",
78 | name:"logInfo",
79 | message:"请输入changelog说明(默认为最新提交信息)",
80 | default:info.message,
81 | when:(answers)=>{
82 | return answers.useLog
83 | }
84 | },
85 | //step6: ask use docker or not
86 | {
87 | type:"confirm",
88 | name:'useDocker',
89 | message:'是否打包生成docker镜像?',
90 | when:()=>hasDocker
91 | },
92 | {
93 | type:"input",
94 | name:"imageName",
95 | message:"请输入你的镜像名:",
96 | default:'web-app',
97 | when:(answers)=>answers.useDocker
98 | }
99 | ]
100 |
101 | return inquirer.prompt(questions)
102 | }
103 |
104 | //record info
105 | function recordBuildInfo(){
106 |
107 | }
108 |
109 | (function main(){
110 | prompt().then((answers)=>{
111 | const {updateVersion,mode} =answers
112 | const version = answers.version || getVersion()
113 | const outputPath = `./output/${mode}/dist(${version})`
114 | if(updateVersion){
115 | console.info(chalk.blue(`更新应用版本:${getVersion()}`))
116 | setVersion(answers.version)
117 | consola.success(chalk.green('版本号修改成功'))
118 | }
119 | // start build
120 | consola.info('开始打包...')
121 | //vite
122 | const buildCommand = `vite build --mode ${answers.mode}`
123 | consola.info(buildCommand)
124 | const startTime = Date.now()
125 | execSync(buildCommand,{stdio:'inherit',encoding:'utf8'});
126 | consola.success(chalk.green('打包完成.'))
127 | const buildEndTime = Date.now()
128 | if(answers.useLog){
129 | writeChangelog({version:answers.version,startTime:startTime,message:answers.logInfo})
130 | }
131 | if(answers.useDocker){
132 | if(!dockerIsRunning()){
133 | consola.error(chalk.red('docker进程暂未启动'))
134 | } else{
135 | consola.info(chalk.blue('docker开始打包'))
136 | const imageName = answers.imageName
137 | const outputName = `docker/${answers.mode}/${imageName}-${version}.tar`
138 | const configPath = `Dockerfile-${answers.mode}`
139 | const author = getGitUser()
140 | //create use buildx instance
141 | execSync(`docker buildx create --use`);
142 | mkdir(`docker/${mode}`)
143 | execSync(`docker build -f ${configPath} -t ${imageName}:${version} -o type=tar,dest=${outputName} .`)
144 | consola.success(chalk.green('docker 打包成功'))
145 | }
146 | }
147 | mkdir(outputPath)
148 | fs.cpSync('./dist',outputPath,{recursive:true})
149 | fs.rmSync('./dist',{recursive:true})
150 | consola.success(chalk.green('******本地打包完成******'))
151 | }).catch((err)=>{
152 | console.log(err)
153 | })
154 | })()
155 |
156 |
157 | /**
158 | *
159 | * @param {string} pathstr
160 | */
161 | function mkdir(pathstr){
162 | const paths = pathstr.split('/').filter(item=>!item.includes('.'));
163 | let current = CMD;
164 | while (paths.length){
165 | current = current+'/'+paths.shift()
166 | if(!fs.existsSync(current)){
167 | fs.mkdirSync(current)
168 | }
169 | }
170 | }
171 |
172 |
--------------------------------------------------------------------------------