@roki-h5/create-roki-app 0.1.9 → 0.1.11

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roki-h5/create-roki-app",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Roki H5 项目脚手架",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@roki-h5/scaffold-template",
3
3
  "private": true,
4
- "version": "0.1.5",
4
+ "version": "0.1.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite --mode development",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@roki-h5/ui": "workspace:*",
16
- "@vitejs/plugin-legacy": "^6.0.0",
16
+ "@vitejs/plugin-legacy": "8.0.1",
17
17
  "axios": "^1.7.9",
18
18
  "event-source-polyfill": "^1.0.31",
19
19
  "pinia": "^2.3.0",
@@ -33,7 +33,12 @@ function setupWebViewJavascriptBridge(
33
33
  window.WVJBCallbacks = [callback]
34
34
 
35
35
  const { iPhone, iPad, iPod } = browser.versions
36
- if (iPhone || iPad || iPod) {
36
+ // file:// 本地预览勿注入 bridge iframe,避免桌面浏览器报跨域安全错误
37
+ if (
38
+ (iPhone || iPad || iPod) &&
39
+ typeof location !== 'undefined' &&
40
+ location.protocol !== 'file:'
41
+ ) {
37
42
  const WVJBIframe = document.createElement('iframe')
38
43
  WVJBIframe.style.display = 'none'
39
44
  WVJBIframe.src = 'https://__bridge_loaded__'
@@ -5,6 +5,7 @@ import Home from '@/views/home/index.vue'
5
5
  const HOME_TITLE_FALLBACK = '燃气热水器'
6
6
 
7
7
  const router = createRouter({
8
+ // 与 iot-water-heater5.0 一致:hash 路由,dist 下直接打开 index.html / file:// 可用
8
9
  history: createWebHashHistory(import.meta.env.BASE_URL),
9
10
  routes: [
10
11
  {
@@ -9,7 +9,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
9
  const monorepoUiDir = path.resolve(__dirname, '../../../ui')
10
10
  const isMonorepoDev = fs.existsSync(path.join(monorepoUiDir, 'package.json'))
11
11
 
12
- /** file:// 打开 dist 时去掉 crossorigin;legacy-only 时再去掉 modulepreload */
12
+ /** file:// 下:去掉 crossorigin;仅 legacy 时再去掉 modulepreload(与 plugin-legacy 文档一致) */
13
13
  function distHtmlPostProcess({ removeModulePreload = false } = {}) {
14
14
  return {
15
15
  name: 'dist-html-post-process',
@@ -34,7 +34,7 @@ function distHtmlPostProcess({ removeModulePreload = false } = {}) {
34
34
  export default defineConfig(({ mode }) => {
35
35
  const env = loadEnv(mode, path.resolve(__dirname, 'config/env'), '')
36
36
 
37
- // 与 iot-ai-glasses 一致:由 VITE_PUBLIC_BASE 控制;未配置时默认 ./,便于 dist 下直接打开 index.html(file://)
37
+ // 与 iot-water-heater5.0 一致:由 VITE_PUBLIC_BASE 控制;未配置时默认 ./,便于 dist 下直接打开 index.html(file://)
38
38
  const rawPublicBase = (env.VITE_PUBLIC_BASE ?? '').trim()
39
39
  const base =
40
40
  mode === 'development'
@@ -47,10 +47,33 @@ export default defineConfig(({ mode }) => {
47
47
  : `${rawPublicBase}/`
48
48
  : './'
49
49
 
50
- /** 相对路径构建时仅输出 legacy 包,便于 file:// 直接打开 dist/index.html */
51
50
  const legacyOnlyForFileProtocol =
52
51
  mode !== 'development' && (base === './' || base === '.')
53
52
 
53
+ const publicBase = (env.VITE_PUBLIC_BASE || '').trim()
54
+ const withTrailingSlash =
55
+ publicBase.startsWith('/') && publicBase.length > 1
56
+ ? publicBase.endsWith('/')
57
+ ? publicBase
58
+ : `${publicBase}/`
59
+ : ''
60
+ const pathWithoutTrailingSlash = withTrailingSlash.replace(/\/+$/, '')
61
+ const trailingSlashRedirect =
62
+ pathWithoutTrailingSlash && pathWithoutTrailingSlash !== '/'
63
+ ? {
64
+ name: 'ensure-subpath-trailing-slash',
65
+ transformIndexHtml: {
66
+ order: 'pre' as const,
67
+ handler(html: string) {
68
+ const noTrail = JSON.stringify(pathWithoutTrailingSlash)
69
+ const withSlash = JSON.stringify(withTrailingSlash)
70
+ const snippet = `<script>(function(){var p=location.pathname;if(p===${noTrail})location.replace(location.origin+${withSlash}+location.search+location.hash);})();<\/script>`
71
+ return html.replace('<head>', `<head>${snippet}`)
72
+ },
73
+ },
74
+ }
75
+ : null
76
+
54
77
  return {
55
78
  plugins: [
56
79
  vue(),
@@ -66,6 +89,7 @@ export default defineConfig(({ mode }) => {
66
89
  renderLegacyChunks: true,
67
90
  renderModernChunks: !legacyOnlyForFileProtocol,
68
91
  }),
92
+ ...(trailingSlashRedirect ? [trailingSlashRedirect] : []),
69
93
  distHtmlPostProcess({ removeModulePreload: legacyOnlyForFileProtocol }),
70
94
  ],
71
95
  envDir: path.resolve(__dirname, 'config/env'),
@@ -90,10 +114,6 @@ export default defineConfig(({ mode }) => {
90
114
  : []),
91
115
  ],
92
116
  },
93
- base,
94
- build: {
95
- cssCodeSplit: !legacyOnlyForFileProtocol,
96
- },
97
117
  server: {
98
118
  host: true,
99
119
  port: 5174,
@@ -106,5 +126,28 @@ export default defineConfig(({ mode }) => {
106
126
  },
107
127
  },
108
128
  },
129
+ base,
130
+ build: {
131
+ // legacy-only 时 index 上 link 的 CSS 很少;关闭拆分,避免首页/懒路由样式未注入导致「样式丢失」
132
+ cssCodeSplit: false,
133
+ outDir: 'dist',
134
+ assetsDir: 'static',
135
+ assetsInlineLimit: 10240,
136
+ sourcemap: false,
137
+ chunkSizeWarningLimit: 2500,
138
+ rollupOptions: {
139
+ output: {
140
+ chunkFileNames: 'static/js/[name]-[hash].js',
141
+ entryFileNames: 'static/js/[name]-[hash].js',
142
+ assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
143
+ },
144
+ },
145
+ minify: 'esbuild',
146
+ esbuild: {
147
+ drop: mode === 'production' ? ['console', 'debugger'] : [],
148
+ legalComments: 'none',
149
+ charset: 'ascii',
150
+ },
151
+ },
109
152
  }
110
153
  })