Skip to content

Commit 3d13c4f

Browse files
committed
feat: improvements
support _level, normalizeComponents, add tests and improve resolving
1 parent 5016347 commit 3d13c4f

File tree

13 files changed

+6019
-318
lines changed

13 files changed

+6019
-318
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ node_modules
55
coverage
66
dist
77
types
8+
.nuxt

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ export default resolveConfig({
4848
})
4949
```
5050

51-
**Note:** While it is not necessary, it is recommended to also follow [Theme Author](#theme-author) section for your project so it is reusable for others.
52-
5351
### Theme Author
5452

5553
- Update `nuxt.config` and ensure required `rootDir` and `name` properties are provided
@@ -63,6 +61,8 @@ export default resolveConfig({
6361
}
6462
```
6563
64+
**Note:** If you are extending another theme, `rootDir` should be ONLY provided if you want to also extend project.
65+
6666
- Instead of using `~/` or `@/` aliases, use `~myTheme` or `@myTheme`
6767
6868
## License

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
],
1212
"scripts": {
1313
"build": "siroc build",
14+
"dev": "nuxt test/fixture/app -c nuxt.config.cjs.js",
1415
"lint": "eslint --ext .ts src",
1516
"prepublish": "yarn build",
1617
"release": "yarn test && yarn build && standard-version && git push --follow-tags && npm publish",
@@ -22,12 +23,15 @@
2223
"jiti": "^0.1.12"
2324
},
2425
"devDependencies": {
26+
"@nuxt/components": "^1.1.1",
2527
"@nuxt/types": "^2.14.7",
28+
"@nuxt/typescript-runtime": "^2.0.0",
2629
"@nuxtjs/eslint-config-typescript": "latest",
2730
"@types/jest": "latest",
2831
"@types/node": "latest",
2932
"eslint": "latest",
3033
"jest": "latest",
34+
"nuxt": "^2.14.7",
3135
"siroc": "^0.4.0",
3236
"standard-version": "latest",
3337
"ts-jest": "latest",

src/index.ts

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,47 @@
11
import { dirname } from 'path'
22
import Hookable, { configHooksT } from 'hookable'
33
import defu from 'defu'
4-
import { NuxtConfig } from '@nuxt/types'
4+
import type { NuxtConfig } from '@nuxt/types'
55

66
declare module '@nuxt/types' {
77
interface NuxtConfig {
8-
hooks: configHooksT
8+
_level?: Number
9+
hooks?: configHooksT
910
name?: string
1011
extends?: string
1112
alias?: { [key: string]: string }
1213
}
1314
}
1415

15-
export function extendConfig (base: NuxtConfig | string, target: NuxtConfig): NuxtConfig {
16-
// Resolve Configs
17-
base = resolveConfig(base)
18-
target = resolveConfig(target)
16+
export function resolveConfig (config: string | NuxtConfig, from: string = process.cwd()): NuxtConfig {
17+
if (typeof config === 'string') {
18+
const jiti = require('jiti')(from)
19+
const name = config
20+
const nuxtConfigFile = jiti.resolve(config)
21+
config = jiti(nuxtConfigFile) as NuxtConfig
22+
23+
if (!config.rootDir) {
24+
config.rootDir = dirname(nuxtConfigFile)
25+
}
26+
27+
if (!config.name) {
28+
config.name = name
29+
}
30+
}
31+
32+
if (!config.rootDir) {
33+
config.rootDir = from
34+
}
35+
36+
if (config.extends) {
37+
const _resolvedExtends = resolveConfig(config.extends, config.rootDir)
38+
config = extendConfig(config, _resolvedExtends)
39+
}
40+
41+
return config
42+
}
1943

44+
export function extendConfig (target: NuxtConfig, base: NuxtConfig): NuxtConfig {
2045
// Ensure base has require fileds
2146
if (!base.name) {
2247
throw new Error('Base config is missing `name` property')
@@ -28,6 +53,10 @@ export function extendConfig (base: NuxtConfig | string, target: NuxtConfig): Nu
2853
base.srcDir = base.rootDir
2954
}
3055

56+
// Set _level
57+
target._level = target._level || 0
58+
base._level = target.level + 1
59+
3160
// Ensure there is no name conflict
3261
if (target.alias && target.alias['~' + base.name]) {
3362
throw new Error('Theme name conflict: ' + base.name)
@@ -41,35 +70,37 @@ export function extendConfig (base: NuxtConfig | string, target: NuxtConfig): Nu
4170
base.alias['@@' + base.name] = base.rootDir
4271

4372
// Custom merges
44-
const override = {
45-
hooks: Hookable.mergeHooks(base.hooks || {}, target.hooks || {})
73+
const override: NuxtConfig = {}
74+
75+
// Merge hooks
76+
override.hooks = Hookable.mergeHooks(base.hooks || {}, target.hooks || {})
77+
78+
// Merge components prop
79+
if (base.components || target.components) {
80+
override.components = [
81+
...normalizeComponents(base.components, { level: base._level }),
82+
...normalizeComponents(target.components, { level: target._level })
83+
]
4684
}
4785

4886
// Merge with defu
4987
return defu.arrayFn(override, target, base)
5088
}
5189

52-
export function resolveConfig (config: string | NuxtConfig): NuxtConfig {
53-
if (typeof config === 'string') {
54-
const jiti = require('jiti')()
55-
56-
const name = config
57-
const nuxtConfigFile = jiti.resolve(config)
58-
59-
config = jiti(nuxtConfigFile) as NuxtConfig
60-
61-
if (!config.rootDir) {
62-
config.rootDir = dirname(nuxtConfigFile)
63-
}
64-
65-
if (!config.name) {
66-
config.name = name
67-
}
90+
function normalizeComponents (components: NuxtConfig['components'], dirOverride = {}) {
91+
if (typeof components === 'boolean') {
92+
components = []
6893
}
6994

70-
if (config.extends) {
71-
config = extendConfig(config.extends, config)
95+
if (!Array.isArray(components)) {
96+
// TODO: Deprecate components: { dirs } support from @nuxt/components
97+
throw new TypeError('`components` should be an array')
7298
}
7399

74-
return config
100+
components = components.map(dir => ({
101+
...(typeof dir === 'string' ? { dir } : dir),
102+
...dirOverride
103+
}))
104+
105+
return components
75106
}

test/__snapshots__/index.test.ts.snap

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`matches snapshot 1`] = `
4+
Object {
5+
"_level": Object {},
6+
"alias": Object {
7+
"@@baseTheme": "{test}/fixture/themes/base",
8+
"@@baseThemeEx": "{test}/fixture/themes/red",
9+
"@baseTheme": "{test}/fixture/themes/base",
10+
"@baseThemeEx": "{test}/fixture/themes/base",
11+
"~baseTheme": "{test}/fixture/themes/base",
12+
"~baseThemeEx": "{test}/fixture/themes/base",
13+
"~~baseTheme": "{test}/fixture/themes/base",
14+
"~~baseThemeEx": "{test}/fixture/themes/red",
15+
},
16+
"extends": "../themes/red/nuxt.config",
17+
"hooks": Object {},
18+
"name": "myApp",
19+
"publicRuntimeConfig": Object {
20+
"color": "red",
21+
},
22+
"rootDir": "{test}/fixture/app",
23+
"srcDir": "{test}/fixture/themes/base",
24+
}
25+
`;

test/fixture/app/nuxt.config.cjs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default require('jiti')(__dirname)('./nuxt.config.ts')

test/fixture/app/nuxt.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { NuxtConfig } from '@nuxt/types'
2+
import { resolveConfig } from '../../../src/index'
3+
4+
export default <NuxtConfig>resolveConfig({
5+
name: 'myApp',
6+
rootDir: __dirname,
7+
extends: '../themes/red/nuxt.config'
8+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { NuxtConfig } from '@nuxt/types'
2+
import { resolveConfig } from '../../../../src/index'
3+
4+
export default <NuxtConfig>resolveConfig({
5+
name: 'baseTheme',
6+
rootDir: __dirname,
7+
srcDir: __dirname,
8+
9+
publicRuntimeConfig: {
10+
color: 'blue'
11+
}
12+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<template>
2+
<div>
3+
Hello world from base!
4+
5+
<br>Color: {{ $config.color }}
6+
</div>
7+
</template>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
name: 'baseThemeEx',
3+
rootDir: __dirname,
4+
extends: '../base/nuxt.config',
5+
6+
publicRuntimeConfig: {
7+
color: 'red'
8+
}
9+
}

0 commit comments

Comments
 (0)