Skip to content

Commit c6fa52f

Browse files
committed
refactor: split out module utils into separate files
1 parent 846a3b0 commit c6fa52f

File tree

8 files changed

+181
-150
lines changed

8 files changed

+181
-150
lines changed

prettier.config.cjs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module.exports = {
22
semi: false,
33
singleQuote: true,
4+
printWidth: 100,
45
trailingComma: 'es5',
56
arrowParens: 'avoid',
67
}

src/module.ts

+27-142
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { existsSync, promises as fsp } from 'node:fs'
2-
import { fileURLToPath } from 'node:url'
2+
3+
import { defineNuxtModule, addComponent, addPlugin } from '@nuxt/kit'
34
import { join, resolve } from 'pathe'
45
import { readPackageJSON } from 'pkg-types'
56
import { defineUnimportPreset } from 'unimport'
6-
import {
7-
defineNuxtModule,
8-
addComponent,
9-
addPlugin,
10-
installModule,
11-
} from '@nuxt/kit'
12-
import { joinURL } from 'ufo'
13-
import type { NuxtPage } from '@nuxt/schema'
14-
import { provider } from 'std-env'
7+
8+
import { runtimeDir } from './utils'
9+
10+
import { useCSSSetup } from './parts/css'
11+
import { setupMeta } from './parts/meta'
12+
import { setupPWA } from './parts/pwa'
13+
import { setupRouter } from './parts/router'
1514

1615
export interface ModuleOptions {
1716
integrations?: {
@@ -44,7 +43,6 @@ export default defineNuxtModule<ModuleOptions>({
4443
},
4544
},
4645
async setup(options, nuxt) {
47-
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
4846
nuxt.options.build.transpile.push(runtimeDir)
4947
nuxt.options.build.transpile.push(/@ionic/)
5048

@@ -70,33 +68,6 @@ export default defineNuxtModule<ModuleOptions>({
7068
// Set up Ionic Core
7169
addPlugin(resolve(runtimeDir, 'ionic'))
7270

73-
// Add Ionic Core CSS
74-
if (options.css?.core) {
75-
// Core CSS required for Ionic components to work properly
76-
nuxt.options.css.push('@ionic/vue/css/core.css')
77-
}
78-
79-
if (options.css?.basic) {
80-
// Basic CSS for apps built with Ionic
81-
nuxt.options.css.push(
82-
'@ionic/vue/css/normalize.css',
83-
'@ionic/vue/css/structure.css',
84-
'@ionic/vue/css/typography.css'
85-
)
86-
}
87-
88-
if (options.css?.utilities) {
89-
// Optional CSS utils that can be commented out
90-
nuxt.options.css.push(
91-
'@ionic/vue/css/padding.css',
92-
'@ionic/vue/css/float-elements.css',
93-
'@ionic/vue/css/text-alignment.css',
94-
'@ionic/vue/css/text-transformation.css',
95-
'@ionic/vue/css/flex-utils.css',
96-
'@ionic/vue/css/display.css'
97-
)
98-
}
99-
10071
// Add auto-imported components
10172
IonicBuiltInComponents.map(name =>
10273
addComponent({
@@ -116,108 +87,32 @@ export default defineNuxtModule<ModuleOptions>({
11687
)
11788
})
11889

90+
const { setupBasic, setupCore, setupUtilities } = useCSSSetup()
91+
92+
// Add Ionic Core CSS
93+
if (options.css?.core) {
94+
await setupCore()
95+
}
96+
97+
if (options.css?.basic) {
98+
await setupBasic()
99+
}
100+
101+
if (options.css?.utilities) {
102+
await setupUtilities()
103+
}
104+
119105
if (options.integrations?.meta) {
120-
nuxt.options.app.head.meta = nuxt.options.app.head.meta || []
121-
for (const meta of metaDefaults) {
122-
if (!nuxt.options.app.head.meta.some(i => i.name === meta.name)) {
123-
nuxt.options.app.head.meta.unshift(meta)
124-
}
125-
}
126-
nuxt.options.app.head.viewport =
127-
'viewport-fit: cover, width: device-width, initial-scale: 1.0, minimum-scale: 1.0, maximum-scale: 1.0, user-scalable: no'
106+
await setupMeta()
128107
}
129108

130109
if (options.integrations?.pwa) {
131-
if (provider === 'stackblitz') {
132-
;(nuxt.options.pwa as any) = (nuxt.options.pwa as any) || {}
133-
;(nuxt.options.pwa as any).icon = false
134-
console.warn(
135-
'Disabling PWA icon generation as `sharp` is not currently supported on StackBlitz.'
136-
)
137-
}
138-
await installModule('@kevinmarrec/nuxt-pwa')
110+
await setupPWA()
139111
}
140112

141113
// Set up Ionic Router integration
142114
if (options.integrations?.router) {
143-
const pagesDirs = nuxt.options._layers.map(layer =>
144-
resolve(layer.config.srcDir, layer.config.dir?.pages || 'pages')
145-
)
146-
147-
// Disable module (and use universal router) if pages dir do not exists or user has disabled it
148-
if (
149-
nuxt.options.pages === false ||
150-
(nuxt.options.pages !== true && !pagesDirs.some(dir => existsSync(dir)))
151-
) {
152-
console.warn(
153-
'Disabling Ionic Router integration as pages dir does not exist.'
154-
)
155-
return
156-
}
157-
158-
addPlugin(resolve(runtimeDir, 'router'))
159-
nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {}
160-
nuxt.options.vite.optimizeDeps.include =
161-
nuxt.options.vite.optimizeDeps.include || []
162-
nuxt.options.vite.optimizeDeps.include.push('@ionic/vue-router')
163-
164-
nuxt.hook('modules:done', () => {
165-
nuxt.options.plugins = nuxt.options.plugins.filter(
166-
p =>
167-
!(typeof p === 'string' ? p : p.src).endsWith(
168-
'nuxt/dist/pages/runtime/router'
169-
) &&
170-
!(typeof p === 'string' ? p : p.src).endsWith(
171-
'nuxt/dist/app/plugins/router'
172-
)
173-
)
174-
175-
// Add all pages to be prerendered
176-
const routes: string[] = []
177-
178-
nuxt.hook('pages:extend', pages => {
179-
routes.length = 0
180-
routes.push(
181-
'/',
182-
...((nuxt.options.nitro.prerender?.routes || []) as string[])
183-
)
184-
function processPages(pages: NuxtPage[], currentPath = '') {
185-
for (const page of pages) {
186-
if (page.path.includes(':')) continue
187-
188-
const path = joinURL(currentPath, page.path)
189-
routes.push(path)
190-
if (page.children) processPages(page.children, path)
191-
}
192-
}
193-
processPages(pages)
194-
})
195-
196-
nuxt.hook('nitro:build:before', nitro => {
197-
nitro.options.prerender.routes = routes
198-
})
199-
})
200-
201-
// Remove vue-router types
202-
nuxt.hook('prepare:types', ({ references }) => {
203-
const index = references.findIndex(
204-
i => 'types' in i && i.types === 'vue-router'
205-
)
206-
if (index !== -1) {
207-
references.splice(index, 1)
208-
}
209-
})
210-
211-
// Add default ionic root layout
212-
nuxt.hook('app:resolve', app => {
213-
if (
214-
!app.mainComponent ||
215-
app.mainComponent.includes('@nuxt/ui-templates') ||
216-
app.mainComponent.match(/nuxt3?\/dist/)
217-
) {
218-
app.mainComponent = join(runtimeDir, 'app.vue')
219-
}
220-
})
115+
await setupRouter()
221116
}
222117
},
223118
})
@@ -328,13 +223,3 @@ const IonicBuiltInComponents = [
328223
'IonModal',
329224
'IonPopover',
330225
]
331-
332-
const metaDefaults = [
333-
{ name: 'color-scheme', content: 'light dark' },
334-
{ name: 'format-detection', content: 'telephone: no' },
335-
{ name: 'msapplication-tap-highlight', content: 'no' },
336-
// add to homescreen for ios
337-
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
338-
{ name: 'apple-mobile-web-app-title', content: 'Ionic App' },
339-
{ name: 'apple-mobile-web-app-status-bar-style', content: 'black' },
340-
]

src/parts/css.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { useNuxt } from '@nuxt/kit'
2+
3+
export const useCSSSetup = () => {
4+
const nuxt = useNuxt()
5+
6+
const setupCore = () => {
7+
// Core CSS required for Ionic components to work properly
8+
nuxt.options.css.push('@ionic/vue/css/core.css')
9+
}
10+
11+
const setupBasic = () => {
12+
// Basic CSS for apps built with Ionic
13+
nuxt.options.css.push(
14+
'@ionic/vue/css/normalize.css',
15+
'@ionic/vue/css/structure.css',
16+
'@ionic/vue/css/typography.css'
17+
)
18+
}
19+
20+
const setupUtilities = () => {
21+
// Optional CSS utils that can be commented out
22+
nuxt.options.css.push(
23+
'@ionic/vue/css/padding.css',
24+
'@ionic/vue/css/float-elements.css',
25+
'@ionic/vue/css/text-alignment.css',
26+
'@ionic/vue/css/text-transformation.css',
27+
'@ionic/vue/css/flex-utils.css',
28+
'@ionic/vue/css/display.css'
29+
)
30+
}
31+
32+
return { setupCore, setupBasic, setupUtilities }
33+
}

src/parts/meta.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useNuxt } from '@nuxt/kit'
2+
3+
export const setupMeta = () => {
4+
const nuxt = useNuxt()
5+
6+
const metaDefaults = [
7+
{ name: 'color-scheme', content: 'light dark' },
8+
{ name: 'format-detection', content: 'telephone: no' },
9+
{ name: 'msapplication-tap-highlight', content: 'no' },
10+
// add to homescreen for ios
11+
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
12+
{ name: 'apple-mobile-web-app-title', content: 'Ionic App' },
13+
{ name: 'apple-mobile-web-app-status-bar-style', content: 'black' },
14+
]
15+
16+
nuxt.options.app.head.meta = nuxt.options.app.head.meta || []
17+
for (const meta of metaDefaults) {
18+
if (!nuxt.options.app.head.meta.some(i => i.name === meta.name)) {
19+
nuxt.options.app.head.meta.unshift(meta)
20+
}
21+
}
22+
nuxt.options.app.head.viewport =
23+
'viewport-fit: cover, width: device-width, initial-scale: 1.0, minimum-scale: 1.0, maximum-scale: 1.0, user-scalable: no'
24+
}

src/parts/pwa.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { installModule, useNuxt } from '@nuxt/kit'
2+
import { provider } from 'std-env'
3+
4+
export const setupPWA = async () => {
5+
const nuxt = useNuxt()
6+
7+
if (provider === 'stackblitz') {
8+
;(nuxt.options as any).pwa = (nuxt.options as any).pwa || {}
9+
;(nuxt.options as any).pwa.icon = false
10+
console.warn(
11+
'Disabling PWA icon generation as `sharp` is not currently supported on StackBlitz.'
12+
)
13+
}
14+
await installModule('@kevinmarrec/nuxt-pwa')
15+
}

src/parts/router.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { existsSync } from 'node:fs'
2+
import { addPlugin, useNuxt } from '@nuxt/kit'
3+
import type { NuxtPage } from '@nuxt/schema'
4+
import { join, resolve } from 'pathe'
5+
import { joinURL } from 'ufo'
6+
import { runtimeDir } from '../utils'
7+
8+
export const setupRouter = () => {
9+
const nuxt = useNuxt()
10+
const pagesDirs = nuxt.options._layers.map(layer =>
11+
resolve(layer.config.srcDir || layer.cwd!, layer.config.dir?.pages || 'pages')
12+
)
13+
14+
// Disable module (and use universal router) if pages dir do not exists or user has disabled it
15+
if (
16+
nuxt.options.pages === false ||
17+
(nuxt.options.pages !== true && !pagesDirs.some(dir => existsSync(dir)))
18+
) {
19+
console.warn('Disabling Ionic Router integration as pages dir does not exist.')
20+
return
21+
}
22+
23+
addPlugin(resolve(runtimeDir, 'router'))
24+
nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {}
25+
nuxt.options.vite.optimizeDeps.include = nuxt.options.vite.optimizeDeps.include || []
26+
nuxt.options.vite.optimizeDeps.include.push('@ionic/vue-router')
27+
28+
nuxt.hook('modules:done', () => {
29+
nuxt.options.plugins = nuxt.options.plugins.filter(
30+
p =>
31+
!(typeof p === 'string' ? p : p.src).endsWith('nuxt/dist/pages/runtime/router') &&
32+
!(typeof p === 'string' ? p : p.src).endsWith('nuxt/dist/app/plugins/router')
33+
)
34+
35+
// Add all pages to be prerendered
36+
const routes: string[] = []
37+
38+
nuxt.hook('pages:extend', pages => {
39+
routes.length = 0
40+
routes.push('/', ...((nuxt.options.nitro.prerender?.routes || []) as string[]))
41+
function processPages(pages: NuxtPage[], currentPath = '') {
42+
for (const page of pages) {
43+
if (page.path.includes(':')) continue
44+
45+
const path = joinURL(currentPath, page.path)
46+
routes.push(path)
47+
if (page.children) processPages(page.children, path)
48+
}
49+
}
50+
processPages(pages)
51+
})
52+
53+
nuxt.hook('nitro:build:before', nitro => {
54+
nitro.options.prerender.routes = routes
55+
})
56+
})
57+
58+
// Remove vue-router types
59+
nuxt.hook('prepare:types', ({ references }) => {
60+
const index = references.findIndex(i => 'types' in i && i.types === 'vue-router')
61+
if (index !== -1) {
62+
references.splice(index, 1)
63+
}
64+
})
65+
66+
// Add default ionic root layout
67+
nuxt.hook('app:resolve', app => {
68+
if (
69+
!app.mainComponent ||
70+
app.mainComponent.includes('@nuxt/ui-templates') ||
71+
app.mainComponent.match(/nuxt3?\/dist/)
72+
) {
73+
app.mainComponent = join(runtimeDir, 'app.vue')
74+
}
75+
})
76+
}

src/runtime/router.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
createRouter,
3-
createWebHistory,
4-
createMemoryHistory,
5-
} from '@ionic/vue-router'
1+
import { createRouter, createWebHistory, createMemoryHistory } from '@ionic/vue-router'
62

73
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'
84
// @ts-expect-error Virtual module generated by Nuxt
@@ -12,9 +8,7 @@ export default defineNuxtPlugin(nuxtApp => {
128
const config = useRuntimeConfig()
139
const baseURL = config.app.baseURL
1410
const router = createRouter({
15-
history: process.server
16-
? createMemoryHistory(baseURL)
17-
: createWebHistory(baseURL),
11+
history: process.server ? createMemoryHistory(baseURL) : createWebHistory(baseURL),
1812
routes,
1913
})
2014

src/utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { fileURLToPath } from 'url'
2+
3+
export const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))

0 commit comments

Comments
 (0)