cmpt-huitu-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +169 -0
  2. package/bin/huitu.js +30 -0
  3. package/package.json +38 -0
  4. package/src/create.js +127 -0
  5. package/src/versions.js +23 -0
  6. package/templates/default/README.md +127 -0
  7. package/templates/default/eslint.config.js +187 -0
  8. package/templates/default/index.html +38 -0
  9. package/templates/default/jsconfig.json +29 -0
  10. package/templates/default/package.json +56 -0
  11. package/templates/default/public/.DS_Store +0 -0
  12. package/templates/default/public/config/envCfg.js +68 -0
  13. package/templates/default/public/images/favicon.ico +0 -0
  14. package/templates/default/src/.DS_Store +0 -0
  15. package/templates/default/src/App.vue +49 -0
  16. package/templates/default/src/assets/.DS_Store +0 -0
  17. package/templates/default/src/assets/empty.png +0 -0
  18. package/templates/default/src/assets/images/.DS_Store +0 -0
  19. package/templates/default/src/assets/images/404/403_1.png +0 -0
  20. package/templates/default/src/assets/images/404/404.png +0 -0
  21. package/templates/default/src/assets/images/404/404_2.png +0 -0
  22. package/templates/default/src/assets/images/404/404_cloud.png +0 -0
  23. package/templates/default/src/assets/images/login/img.png +0 -0
  24. package/templates/default/src/assets/images/login/logo.png +0 -0
  25. package/templates/default/src/assets/images/login/person.png +0 -0
  26. package/templates/default/src/components/.DS_Store +0 -0
  27. package/templates/default/src/components/error/Error.vue +259 -0
  28. package/templates/default/src/components.d.ts +18 -0
  29. package/templates/default/src/imports.d.ts +90 -0
  30. package/templates/default/src/main.js +27 -0
  31. package/templates/default/src/routers/base.js +41 -0
  32. package/templates/default/src/routers/guard.js +43 -0
  33. package/templates/default/src/routers/index.js +36 -0
  34. package/templates/default/src/routers/modules/example.js +17 -0
  35. package/templates/default/src/services/.DS_Store +0 -0
  36. package/templates/default/src/services/login.js +32 -0
  37. package/templates/default/src/stores/README.md +317 -0
  38. package/templates/default/src/stores/index/global.js +49 -0
  39. package/templates/default/src/stores/index/template.js +31 -0
  40. package/templates/default/src/stores/index.js +14 -0
  41. package/templates/default/src/stores//344/275/277/347/224/250/347/244/272/344/276/213.vue +94 -0
  42. package/templates/default/src/styles/index.scss +23 -0
  43. package/templates/default/src/styles/theme/README.md +52 -0
  44. package/templates/default/src/styles/theme/variables.scss +62 -0
  45. package/templates/default/src/utils/RequestCache.js +198 -0
  46. package/templates/default/src/utils/auth.js +51 -0
  47. package/templates/default/src/utils/errorCode.js +16 -0
  48. package/templates/default/src/utils/index.js +519 -0
  49. package/templates/default/src/utils/requestAxios.js +148 -0
  50. package/templates/default/src/utils/theme.js +20 -0
  51. package/templates/default/src/views/About.vue +6 -0
  52. package/templates/default/src/views/Home.vue +111 -0
  53. package/templates/default/src/views/login/index.vue +285 -0
  54. package/templates/default/vite/plugins/autoComponents.js +18 -0
  55. package/templates/default/vite/plugins/autoImport.js +13 -0
  56. package/templates/default/vite/plugins/compression.js +24 -0
  57. package/templates/default/vite/plugins/externals.js +8 -0
  58. package/templates/default/vite/plugins/index.js +18 -0
  59. package/templates/default/vite/plugins/visualizer.js +11 -0
  60. package/templates/default/vite.config.js +185 -0
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <div class="home">
3
+ <ModuleTitle title="欢迎使用慧图标准脚手架" />
4
+ <VexTable
5
+ :columns="columns"
6
+ :data="data"
7
+ />
8
+ <HTable
9
+ :data="data"
10
+ :columns="hTableColumns"
11
+ >
12
+ </HTable>
13
+ <div class="content">
14
+ <p>这是一个基于 Monorepo 架构的 Vue 3 标准模版。</p>
15
+ <p>已集成:</p>
16
+ <ul>
17
+ <li><el-tag>Vue 3</el-tag></li>
18
+ <li><el-tag type="success">Vite</el-tag></li>
19
+ <li><el-tag type="warning">Element Plus</el-tag></li>
20
+ <li><el-tag type="danger">@huitu/ui</el-tag></li>
21
+ <li><el-tag type="info">@huitu/utils</el-tag></li>
22
+ </ul>
23
+
24
+ <div class="demo-section">
25
+ <h3>UI 组件演示</h3>
26
+ <div class="demo-item">
27
+ <p>AccentTitle:</p>
28
+ <AccentTitle
29
+ title="测试标题"
30
+ unit="单位: 个"
31
+ />
32
+ </div>
33
+ <div class="demo-item">
34
+ <p>BgTag:</p>
35
+ <BgTag label="标签组件" />
36
+ </div>
37
+ </div>
38
+
39
+ <div class="demo-section">
40
+ <h3>Utils 工具演示</h3>
41
+ <p>当前时间 (formatted by @huitu/utils): {{ currentTime }}</p>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script setup>
48
+ import { ref, onMounted } from 'vue'
49
+ import { parseTime } from '@huitu/utils'
50
+
51
+ const currentTime = ref('')
52
+ const columns = [
53
+ { type: 'seq', title: '序号', width: 80 },
54
+ { field: 'name', title: '姓名', width: 120 },
55
+ { field: 'age', title: '年龄', width: 120 },
56
+ ]
57
+ const data = [
58
+ {
59
+ name: '张三',
60
+ age: 18,
61
+ },
62
+ {
63
+ name: '李四',
64
+ age: 20,
65
+ },
66
+ ]
67
+
68
+ const hTableColumns = [
69
+ {
70
+ prop: 'name',
71
+ label: '站名',
72
+ width: 100,
73
+ align: 'center',
74
+ fixed: 'left',
75
+ },
76
+ {
77
+ prop: 'age',
78
+ label: '年龄',
79
+ width: 100,
80
+ align: 'center',
81
+ fixed: 'left',
82
+ },
83
+ ]
84
+
85
+ onMounted(() => {
86
+ currentTime.value = parseTime(new Date(), 'YYYY-MM-DD HH:mm:ss')
87
+ })
88
+ </script>
89
+
90
+ <style scoped>
91
+ .home {
92
+ padding: 20px;
93
+ }
94
+ .content {
95
+ margin-top: 20px;
96
+ }
97
+ ul {
98
+ list-style: none;
99
+ padding: 0;
100
+ display: flex;
101
+ gap: 10px;
102
+ }
103
+ .demo-section {
104
+ margin-top: 30px;
105
+ border-top: 1px solid #eee;
106
+ padding-top: 20px;
107
+ }
108
+ .demo-item {
109
+ margin-bottom: 20px;
110
+ }
111
+ </style>
@@ -0,0 +1,285 @@
1
+ <!--
2
+ @FileDescription: 登录demo页面
3
+ -->
4
+ <template>
5
+ <div
6
+ class="loginWrapper"
7
+ id="app"
8
+ >
9
+ <div class="loginPanel">
10
+ <div class="divWelcome"></div>
11
+ <div class="loginContainer">
12
+ <el-form
13
+ ref="loginFormRef"
14
+ status-icon
15
+ :model="loginForm"
16
+ label-width="0px"
17
+ class="loginForm"
18
+ :rules="loginRules"
19
+ >
20
+ <el-form-item>
21
+ <div class="heard_images">
22
+ <img
23
+ src="@assets/images/login/logo.png"
24
+ alt=""
25
+ />
26
+ </div>
27
+ <div class="loginTitle">
28
+ <span>系统登录</span>
29
+ </div>
30
+ </el-form-item>
31
+ <el-form-item
32
+ label
33
+ prop="userName"
34
+ >
35
+ <el-input
36
+ type="text"
37
+ name="userName"
38
+ v-model="loginForm.userName"
39
+ auto-complete="off"
40
+ clearable
41
+ placeholder="请输入用户名"
42
+ class="userName"
43
+ ></el-input>
44
+ </el-form-item>
45
+ <el-form-item
46
+ label
47
+ prop="password"
48
+ >
49
+ <el-input
50
+ :type="passw"
51
+ name="password"
52
+ v-model="loginForm.password"
53
+ class="password"
54
+ >
55
+ <i
56
+ slot="suffix"
57
+ :class="icon"
58
+ @click="showPass"
59
+ ></i>
60
+ </el-input>
61
+ </el-form-item>
62
+ <el-form-item>
63
+ <div
64
+ class="homeBut"
65
+ type="primary"
66
+ native-type="submit"
67
+ @click="startLogin"
68
+ :loading="loading"
69
+ >
70
+ 登录
71
+ </div>
72
+ </el-form-item>
73
+ </el-form>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </template>
78
+
79
+ <script setup>
80
+ import { loginApi } from '@/services/login'
81
+ import { setToken, setRefreshToken } from '@/utils/auth'
82
+ const { proxy } = getCurrentInstance()
83
+
84
+ // 定义组件名称
85
+ defineOptions({
86
+ name: 'Login',
87
+ })
88
+
89
+ // 响应式数据
90
+ const passw = ref('password')
91
+ const icon = ref('el-input__icon el-icon-view')
92
+ const loading = ref(false)
93
+ const loginFormRef = ref(null)
94
+
95
+ const loginForm = reactive({
96
+ userName: '',
97
+ password: '',
98
+ })
99
+
100
+ const loginRules = {
101
+ userName: [
102
+ {
103
+ required: true,
104
+ trigger: ['blur', 'change'],
105
+ message: '请输入账号',
106
+ },
107
+ ],
108
+ password: [
109
+ {
110
+ required: true,
111
+ trigger: ['blur', 'change'],
112
+ message: '请输入密码',
113
+ },
114
+ ],
115
+ }
116
+
117
+ // 密码的隐藏和显示
118
+ const showPass = () => {
119
+ // 点击图标是密码隐藏或显示
120
+ if (passw.value == 'text') {
121
+ passw.value = 'password'
122
+ // 更换图标
123
+ icon.value = 'el-input__icon el-icon-view'
124
+ } else {
125
+ passw.value = 'text'
126
+ icon.value = 'el-input__icon el-icon-loading'
127
+ }
128
+ }
129
+
130
+ const startLogin = () => {
131
+ loginFormRef.value.validate((valid) => {
132
+ if (valid) {
133
+ loading.value = true
134
+ // 通用登录逻辑
135
+ loginApi({
136
+ username: loginForm.userName,
137
+ password: loginForm.password,
138
+ })
139
+ .then((res) => {
140
+ if (res.success) {
141
+ const { token, refreshToken } = res.data
142
+ setToken(token)
143
+ setRefreshToken(refreshToken)
144
+ proxy.$message.success('登录成功')
145
+ // 跳转到首页或重定向页面
146
+ const redirect = route.query.redirect || '/'
147
+ router.push(redirect)
148
+ } else {
149
+ proxy.$message.error(res.msg || '登录失败')
150
+ }
151
+ })
152
+ .catch((err) => {
153
+ proxy.$message.error(err.message || '登录请求异常')
154
+ })
155
+ .finally(() => {
156
+ loading.value = false
157
+ })
158
+ }
159
+ })
160
+ }
161
+ </script>
162
+
163
+ <style lang="scss" scoped>
164
+ .loginWrapper {
165
+ height: 100%;
166
+ background: url('@assets/images/login/img.png') no-repeat;
167
+ background-size: 100% 100%;
168
+ display: flex;
169
+ flex-direction: row;
170
+ flex-wrap: nowrap;
171
+ justify-content: center;
172
+ align-items: center;
173
+ font-size: 14px;
174
+ }
175
+
176
+ .loginPanel {
177
+ display: flex;
178
+ height: 50%;
179
+ width: 62%;
180
+ min-height: 630px;
181
+ min-width: 760px;
182
+ }
183
+
184
+ .divWelcome {
185
+ display: flex;
186
+ flex-direction: column;
187
+ width: 100%;
188
+ height: 100%;
189
+ background: url('@assets/images/login/person.png') no-repeat;
190
+ background-size: 100% 100%;
191
+ }
192
+
193
+ .loginContainer {
194
+ width: 440px;
195
+ height: 630px;
196
+ box-sizing: border-box;
197
+ background: #fff;
198
+ display: flex;
199
+ align-items: center;
200
+ padding: 1rem;
201
+ justify-content: center;
202
+ }
203
+
204
+ .heard_images {
205
+ width: 100%;
206
+ display: flex;
207
+ flex-direction: column;
208
+ align-items: center;
209
+ margin-bottom: 10px;
210
+ }
211
+
212
+ .heard_images img {
213
+ width: 94px;
214
+ height: 94px;
215
+ line-height: 94px;
216
+ }
217
+
218
+ .loginTitle {
219
+ width: 300px;
220
+ height: 50px;
221
+ line-height: 50px;
222
+ text-align: center;
223
+ font-size: 20px;
224
+ font-family: Microsoft YaHei;
225
+ font-weight: 400;
226
+ color: rgba(44, 149, 255, 1);
227
+ border-bottom: 1px solid rgba(44, 149, 255, 1);
228
+ }
229
+
230
+ .redior {
231
+ display: flex;
232
+ justify-content: flex-end;
233
+ }
234
+
235
+ .loginForm {
236
+ width: 95%;
237
+ }
238
+
239
+ .homeBut {
240
+ height: 48px;
241
+ font-size: 16px;
242
+ width: 100%;
243
+ background: #66b1ff;
244
+ border-color: #66b1ff;
245
+ color: #fff;
246
+ padding: 9px 15px;
247
+ border-radius: 3px;
248
+ text-align: center;
249
+ cursor: pointer;
250
+ }
251
+
252
+ .el-form-item {
253
+ margin-bottom: 16px !important;
254
+ }
255
+ :deep(.el-form-item__content .el-input .el-input__inner) {
256
+ height: 48px;
257
+ line-height: 48px;
258
+ color: gray !important;
259
+ background: rgba(255, 255, 255, 1);
260
+ border: 1px solid rgba(233, 238, 243, 1) !important;
261
+ opacity: 1;
262
+ border-radius: 4px;
263
+ }
264
+
265
+ :deep(.el-form-item__content .el-input .el-input__inner) :focus {
266
+ border: 1px solid #4d98ff !important;
267
+ }
268
+
269
+ :deep(.el-form-item__content .el-input .el-input__inner) :hover {
270
+ border: 1px solid #4d98ff !important;
271
+ }
272
+
273
+ .el-button {
274
+ height: 48px !important;
275
+ font-size: 16px !important;
276
+ }
277
+
278
+ .el-switch .el-switch__label {
279
+ color: #c4cbd2 !important;
280
+ }
281
+
282
+ .el-switch .el-switch__label .is-active {
283
+ color: #4d98ff !important;
284
+ }
285
+ </style>
@@ -0,0 +1,18 @@
1
+ import components from 'unplugin-vue-components/vite'
2
+ // import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
3
+
4
+ // 配置自动组件注册
5
+ export default function createAutoComponents() {
6
+ return components({
7
+ // 关闭element-plus组件自动注册(因为element-plus自动注册会导致全局注册的方法失效,如proxy.$message失效)
8
+ // resolvers: [ElementPlusResolver()],
9
+
10
+ dirs: ['src/components', 'src/views'],
11
+ directoryAsNamespace: false, // 关闭目录命名空间,虽然能防止组件名冲突,但是组件标签名太长
12
+ dts: 'src/components.d.ts', // 生成组件注册名称,如果要关闭可以这样:dts: false
13
+
14
+ // importPathTransform: (path) =>{
15
+ // return path.replace(/^src\/components/, 'H') // 路径替换为前缀
16
+ // }
17
+ })
18
+ }
@@ -0,0 +1,13 @@
1
+ import autoImport from 'unplugin-auto-import/vite'
2
+ // import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
3
+
4
+ // 配置自动导入,这样项目中的文件就不需要import导入下面类库就可以直接使用了
5
+ export default function createAutoImport() {
6
+ return autoImport({
7
+ // 关闭element-plus组件自动导入
8
+ // resolvers: [ElementPlusResolver()],
9
+
10
+ imports: ['vue', 'vue-router', 'pinia'],
11
+ dts: 'src/imports.d.ts', // 生成自动导入注册名称,如果要关闭可以这样:dts: false
12
+ })
13
+ }
@@ -0,0 +1,24 @@
1
+ import compression from 'vite-plugin-compression'
2
+
3
+ // 配置 gzip,针对资源进行自动gzip压缩
4
+ export default function createCompression() {
5
+ // const plugin = []
6
+ // const { VITE_BUILD_COMPRESS } = env
7
+ // if (VITE_BUILD_COMPRESS) {
8
+ // const compressList = VITE_BUILD_COMPRESS.split(',')
9
+ // if (compressList.includes('gzip')) {
10
+ // plugin.push(
11
+ // compression({
12
+ // ext: '.gz',
13
+ // deleteOriginFile: false
14
+ // })
15
+ // )
16
+ // }
17
+ // }
18
+ // return plugin
19
+
20
+ return compression({
21
+ ext: '.gz',
22
+ deleteOriginFile: false,
23
+ })
24
+ }
@@ -0,0 +1,8 @@
1
+ import { viteExternalsPlugin } from 'vite-plugin-externals'
2
+
3
+ // 将第三方依赖(如echarts)声明为外部资源,不打包进 bundle,通过 CDN 引入,减小包体积。
4
+ export default function createExternals() {
5
+ return viteExternalsPlugin({
6
+ // vue: 'Vue' // 此配置会将vue替换为全局变量Vue,避免打包到bundle中。
7
+ })
8
+ }
@@ -0,0 +1,18 @@
1
+ import vue from '@vitejs/plugin-vue'
2
+ import createAutoImport from './autoImport'
3
+ import createAutoComponents from './autoComponents'
4
+ import createCompression from './compression'
5
+ import createExternals from './externals'
6
+ import createVisualizer from './visualizer'
7
+ import vueDevTools from 'vite-plugin-vue-devtools'
8
+ export default function createVitePlugins(isBuild = false) {
9
+ const vitePlugins = [vue()]
10
+ vitePlugins.push(createAutoImport())
11
+ vitePlugins.push(createAutoComponents())
12
+ isBuild && vitePlugins.push(createCompression())
13
+ isBuild && vitePlugins.push(createExternals())
14
+ isBuild && vitePlugins.push(createVisualizer())
15
+ !isBuild && vitePlugins.push(vueDevTools())
16
+
17
+ return vitePlugins
18
+ }
@@ -0,0 +1,11 @@
1
+ import { visualizer } from 'rollup-plugin-visualizer' // 包分析
2
+
3
+ // 包大小分析(生产构建时启用)
4
+ export default function createVisualizer() {
5
+ return visualizer({
6
+ open: false,
7
+ gzipSize: true,
8
+ brotliSize: true,
9
+ filename: './dist/report.html',
10
+ })
11
+ }
@@ -0,0 +1,185 @@
1
+ import { defineConfig, loadEnv } from 'vite'
2
+ import { resolve, dirname } from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import createVitePlugins from './vite/plugins'
5
+ // import { readdirSync } from 'fs';
6
+
7
+ // https://vite.dev/config/
8
+ export default defineConfig(({ mode, command }) => {
9
+ // mode如果没设置默认值:production | development
10
+ // command如果没设置默认值: dev | build
11
+ const __dirname = dirname(fileURLToPath(import.meta.url))
12
+ const __cwd = process.cwd() /* eslint-disable-line no-undef */
13
+
14
+ // ########环境变量说明begin########
15
+ // import.meta.env的变量如下:
16
+ // 以下变量是系统自带的变量
17
+ // import.meta.env.MODE: 当前环境模式
18
+ // import.meta.env.DEV: 当前环境是否是开发环境
19
+ // import.meta.env.PROD: 当前环境是否是生产环境
20
+ // import.meta.env.SSR: 当前环境是否是服务端渲染环境
21
+ // import.meta.env.BASE_URL: 当前环境基础路径
22
+ // 以下变量是在.env文件中定义的变量
23
+ // import.meta.env.VITE_MOCK: 模拟数据地址
24
+ // import.meta.env.VITE_PATH: 开发基础路径
25
+ // import.meta.env.VITE_PORT: 开发端口
26
+ // ########环境变量说明end########
27
+
28
+ // 环境变量
29
+ const env = loadEnv(mode, __cwd)
30
+ // 推荐:使用command进行环境判断,而非直接检查MODE,因为MODE可能被环境变量文件或者命令改变
31
+ const isProduction = command === 'build'
32
+ const base = env.VITE_PATH || '/'
33
+ const port = Number(env.VITE_PORT) || 3001
34
+
35
+ // // 多页面应用自动配置
36
+ // const pages = readdirSync('./src/pages').reduce((arr, page) => {
37
+ // arr[page] = resolve(__dirname, `src/pages/${page}/index.html`);
38
+ // return arr;
39
+ // }, {});
40
+
41
+ return {
42
+ // 项目根目录,是指相对html页面的路径,(vite官方标准不建议把html放在src或public下)
43
+ root: __cwd,
44
+
45
+ // 公共基础路径(部署时使用,相当于vue2中的publicPath 配置项)(此处配置会成为 import.meta.env.BASE_URL 的值)
46
+ base: base,
47
+
48
+ // 开发服务器配置
49
+ server: {
50
+ host: '0.0.0.0',
51
+ port: port,
52
+ open: true,
53
+ cors: true,
54
+ proxy: {
55
+ '/socket.io': {
56
+ // 代理 websockets 或 socket.io 写法:ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io
57
+ target: 'ws://localhost:5174',
58
+ ws: true,
59
+ },
60
+ // 示例:API 代理配置
61
+ '/api': {
62
+ target: 'http://localhost:8080',
63
+ changeOrigin: true,
64
+ rewrite: (path) => path.replace(/^\/api/, ''),
65
+ },
66
+ },
67
+ // 当路由模式是history模式时,且多页面时候 server需要特别配置,防止404
68
+ // historyApiFallback: {
69
+ // rewrites: [
70
+ // { from: /./, to: '/index.html' },
71
+ // { from: /^\/system/, to: '/system.html' },
72
+ // ],
73
+ // },
74
+ },
75
+
76
+ // 插件配置
77
+ plugins: createVitePlugins(isProduction),
78
+
79
+ // 路径别名配置
80
+ resolve: {
81
+ alias: {
82
+ '~': resolve(__dirname, './'),
83
+ '@': resolve(__dirname, './src'),
84
+ '@mock': resolve(__dirname, './mock'),
85
+ '@public': resolve(__dirname, './public'),
86
+ '@pages': resolve(__dirname, './src/pages'),
87
+ '@components': resolve(__dirname, './src/components'),
88
+ '@views': resolve(__dirname, './src/views'),
89
+ '@routers': resolve(__dirname, './src/routers'),
90
+ '@stores': resolve(__dirname, './src/stores'),
91
+ '@styles': resolve(__dirname, './src/styles'),
92
+ '@utils': resolve(__dirname, './src/utils'),
93
+ '@assets': resolve(__dirname, './src/assets'),
94
+ '@services': resolve(__dirname, './src/services'),
95
+ '@plugins': resolve(__dirname, './src/plugins'),
96
+ },
97
+ // import引用可以忽略文件后缀如:import router from './router' === import router from './router/index.js'
98
+ extensions: ['.mjs', '.ts', '.jsx', '.tsx', '.json', '.js', '.vue', '.css', '.scss'],
99
+ },
100
+
101
+ // CSS预处理器配置
102
+ css: {
103
+ // modules: { // 启用CSS modules
104
+ // generateScopedName: '[name]__[local]___[hash:base64:5]' // 生成的类名格式
105
+ // },
106
+ preprocessorOptions: {
107
+ scss: {
108
+ additionalData: `
109
+ @use "${resolve(__dirname, '../../packages/ui/src/styles/variables.scss')}" as *;
110
+ @use "${resolve(__dirname, '../../packages/ui/src/styles/mixin.scss')}" as *;
111
+ `,
112
+ },
113
+ },
114
+ },
115
+
116
+ // 构建配置
117
+ build: {
118
+ outDir: 'dist',
119
+ assetsDir: 'assets',
120
+ sourcemap: !isProduction, // 开发保留 sourcemap
121
+ target: ['es2015', 'edge88', 'chrome87'], // 产物目标浏览器
122
+ minify: 'esbuild', // 代码压缩,vite默认使用esbuild,如果需要使用terser,需要安装npm install terser@vitejs/plugin-terser -D
123
+ // 下面要配合 minify: 'terser',才能生效
124
+ // terserOptions: isProduction
125
+ // ? {
126
+ // compress: {
127
+ // drop_console: true, // 生产环境移除 console
128
+ // drop_debugger: true
129
+ // },
130
+ // format: {
131
+ // comments: false // 移除注释
132
+ // }
133
+ // }
134
+ // : {},
135
+ rollupOptions: {
136
+ // 多页面应用配置,通过自动配置
137
+ input: {
138
+ // 多页面:一张图
139
+ index: resolve(__dirname, 'index.html'),
140
+ },
141
+ output: {
142
+ format: 'es', // 输出格式为 ES 模块
143
+ entryFileNames: 'assets/js/entry-[name]-[hash].js',
144
+ chunkFileNames: 'assets/js/[name]-[hash].js',
145
+ assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
146
+ manualChunks: {
147
+ 'x-vuelib': ['vue', 'vue-router', 'pinia', 'axios', 'dayjs', 'lodash-es'],
148
+ 'x-eleuilib': ['element-plus'],
149
+ },
150
+ experimentalMinChunkSize: 2048, // 该选项用于为代码分割设置一个以字节为单位的最小 chunk 大小
151
+ // inlineDynamicImports: true // 该选项用于内联动态引入,该选项只在单页面应用的时候起作用
152
+
153
+ // globals: { // 不打包的全局变量声明,告诉 Rollup vue 是外部依赖 和 external配套使用
154
+ // vue: 'Vue'
155
+ // }
156
+ },
157
+ // external: ['vue', 'axios'], // 放在externals.js插件中处理了,排除打包,如:['vue', 'axios'],通过html中引入的库,如:<script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.prod.js"></script>
158
+
159
+ // 以下属性废弃
160
+ // cssCodeSplit: true, // 启用 CSS 代码分割
161
+ // chunkSizeWarningLimit: 2000, // chunk 大小警告的限制(以 kbs 为单位)
162
+ // assetsInlineLimit: 2048 // 小于2kb的资源内联
163
+ },
164
+ },
165
+
166
+ // 优化依赖预构建(当你首次启动 vite 时,Vite 在本地加载你的站点之前预构建了项目依赖。)
167
+ optimizeDeps: {
168
+ include: ['vue', 'vue-router', 'pinia', 'axios', 'element-plus', 'dayjs'], // 默认情况下,不在 node_modules 中的,链接的包不会被预构建
169
+ exclude: ['@huitu'], // 在预构建中强制排除的依赖项
170
+ force: false, // 强制进行依赖预构建
171
+ },
172
+
173
+ // 下面要配合 minify: 'esbuild',才能生效
174
+ esbuild: {
175
+ drop: isProduction ? ['console', 'debugger'] : [],
176
+ legalComments: 'none',
177
+ },
178
+
179
+ // 日志级别
180
+ logLevel: 'info',
181
+
182
+ // 缓存配置
183
+ cacheDir: resolve(__dirname, 'node_modules/.viteCache'),
184
+ }
185
+ })