Skip to content

Commit 045e76b

Browse files
committed
initial commit
0 parents  commit 045e76b

File tree

11 files changed

+6580
-0
lines changed

11 files changed

+6580
-0
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

.eslintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": [
3+
"@nuxtjs/eslint-config-typescript"
4+
]
5+
}

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- dev
8+
pull_request:
9+
branches:
10+
- master
11+
- dev
12+
13+
jobs:
14+
ci:
15+
runs-on: ${{ matrix.os }}
16+
17+
strategy:
18+
matrix:
19+
os: [ubuntu-latest]
20+
node: [12, 14]
21+
22+
steps:
23+
- uses: actions/setup-node@v1
24+
with:
25+
node-version: ${{ matrix.node }}
26+
27+
- name: checkout
28+
uses: actions/checkout@master
29+
30+
- name: cache node_modules
31+
uses: actions/cache@v1
32+
with:
33+
path: node_modules
34+
key: ${{ matrix.os }}-node-v${{ matrix.node }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
35+
36+
- name: Install dependencies
37+
if: steps.cache.outputs.cache-hit != 'true'
38+
run: yarn
39+
40+
- name: Lint
41+
run: yarn lint
42+
43+
- name: Test
44+
run: yarn jest
45+
46+
- name: Coverage
47+
uses: codecov/codecov-action@v1

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.vscode
2+
node_modules
3+
*.log
4+
.DS_Store
5+
coverage
6+
dist
7+
types

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# `@nuxt/theme`
2+
3+
Magically theme/extends support to Nuxt 2 projects!
4+
5+
## Features
6+
7+
- Forward compatible with nuxt3 multi app
8+
- Support neseted `extends`
9+
- Smartly merge config and hooks
10+
- Allow theme development to be like a normal nuxt project
11+
12+
## Usage
13+
14+
### Common Setup
15+
16+
Install `@nuxt/theme` as a dependency:
17+
18+
```sh
19+
# yarn
20+
yarn add @nuxt/theme
21+
22+
# npm
23+
npm i @nuxt/theme
24+
```
25+
26+
Update `nuxt.config` file:
27+
28+
```js
29+
import { resolveConfig } from '@nuxt/theme'
30+
31+
export default resolveConfig({
32+
})
33+
```
34+
35+
### Theme Consumer
36+
37+
Use `extends` key in `nuxt.config`:
38+
39+
```js
40+
import { resolveConfig } from '@nuxt/theme'
41+
42+
export default resolveConfig({
43+
extends: '@nuxt/docs-theme'
44+
})
45+
```
46+
47+
**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.
48+
49+
### Theme Author
50+
51+
- Update `nuxt.config` and ensure required `rootDir` and `name` properties are provided
52+
53+
```js
54+
import { resolveConfig } from '@nuxt/theme'
55+
56+
export default resolveConfig({
57+
name: 'myTheme'
58+
rootDir: __direname
59+
}
60+
61+
- Instead of using `~/` or `@/` aliases, use `~myTheme` or `@myTheme`
62+
63+
## License
64+
65+
MIT

jest.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
collectCoverage: true,
4+
testEnvironment: 'node'
5+
}

package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "@nuxt/theme",
3+
"version": "0.0.0",
4+
"description": "",
5+
"repository": "nuxt/theme",
6+
"license": "MIT",
7+
"main": "./dist/index.js",
8+
"types": "./dist/index.d.ts",
9+
"files": [
10+
"dist"
11+
],
12+
"scripts": {
13+
"build": "siroc build",
14+
"lint": "eslint --ext .ts src",
15+
"prepublish": "yarn build",
16+
"release": "yarn test && yarn build && standard-version && git push --follow-tags && npm publish",
17+
"test": "yarn lint && yarn jest"
18+
},
19+
"dependencies": {
20+
"defu": "^3.2.0",
21+
"hookable": "^4.3.1",
22+
"jiti": "^0.1.12"
23+
},
24+
"devDependencies": {
25+
"@nuxt/types": "^2.14.7",
26+
"@nuxtjs/eslint-config-typescript": "latest",
27+
"@types/jest": "latest",
28+
"@types/node": "latest",
29+
"eslint": "latest",
30+
"jest": "latest",
31+
"siroc": "^0.4.0",
32+
"standard-version": "latest",
33+
"ts-jest": "latest",
34+
"typescript": "latest"
35+
}
36+
}

src/index.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { dirname } from 'path'
2+
import Hookable, { configHooksT } from 'hookable'
3+
import defu from 'defu'
4+
import { NuxtConfig } from '@nuxt/types'
5+
6+
declare module '@nuxt/types' {
7+
interface NuxtConfig {
8+
hooks: configHooksT
9+
name?: string
10+
extends?: string
11+
alias?: { [key: string]: string }
12+
}
13+
}
14+
15+
export function extendConfig (base: NuxtConfig | string, target: NuxtConfig): NuxtConfig {
16+
// Resolve Configs
17+
base = resolveConfig(base)
18+
target = resolveConfig(target)
19+
20+
// Ensure base has require fileds
21+
if (!base.name) {
22+
throw new Error('Base config is missing `name` property')
23+
}
24+
if (!base.rootDir) {
25+
throw new Error('Base config is missing `rootDir` property')
26+
}
27+
if (!base.srcDir) {
28+
base.srcDir = base.rootDir
29+
}
30+
31+
// Ensure there is no name conflict
32+
if (target.alias && target.alias['~' + base.name]) {
33+
throw new Error('Theme name conflict: ' + base.name)
34+
}
35+
36+
// Assign aliases for base
37+
base.alias = base.alias || {}
38+
base.alias['~' + base.name] = base.srcDir
39+
base.alias['~~' + base.name] = base.rootDir
40+
base.alias['@' + base.name] = base.srcDir
41+
base.alias['@@' + base.name] = base.rootDir
42+
43+
// Custom merges
44+
const override = {
45+
hooks: Hookable.mergeHooks(base.hooks || {}, target.hooks || {})
46+
}
47+
48+
// Merge with defu
49+
return defu(override, target, base)
50+
}
51+
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+
}
68+
}
69+
70+
if (config.extends) {
71+
config = extendConfig(config.extends, config)
72+
}
73+
74+
return config
75+
}

test/index.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
it('pass', () => {
2+
3+
})

tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"module": "ES6",
5+
"moduleResolution": "node",
6+
"esModuleInterop": true,
7+
"declaration": true
8+
},
9+
"include": [
10+
"src"
11+
]
12+
}

0 commit comments

Comments
 (0)