Skip to content

Commit f65a872

Browse files
committed
feat: typescript support for config file
1 parent 67e50a4 commit f65a872

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2417
-196
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
!.vuepress
55
packages/@vuepress/shared-utils/lib
66
packages/@vuepress/shared-utils/types
7+
packages/vuepress/types
114 KB
Loading
Loading
Loading
Loading

changelog-unpublished/1.9/index.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# TypeScript Support for Config file
2+
3+
## Overview
4+
5+
![](./assets/1.9-overview.png)
6+
7+
## Features
8+
9+
### Support `.vuepress/config.ts`
10+
11+
Previously, VuePress only supported these configurations
12+
13+
- `.vuepress/config.js`
14+
- `.vuepress/config.yml`
15+
- `.vuepress/config.toml`
16+
17+
From now on, `.vuepress/config.ts` get officially supported.
18+
19+
### `defineConfig` helper for config intellisense
20+
21+
A helper function exposed at `vuepress/config`, which helps you to have type prompt:
22+
23+
```ts
24+
import { defineConfig } from "vuepress/config";
25+
26+
export default defineConfig({
27+
title: "VuePress",
28+
description: "Vue-powered Static Site Generator"
29+
// ...
30+
});
31+
```
32+
33+
### `Typed` Theme Config
34+
35+
By default, `defineConfig` helper leverages the theme config type from default theme:
36+
37+
```js
38+
import { defineConfig } from "vuepress/config";
39+
40+
export default defineConfig({
41+
themeConfig: {
42+
repo: "vuejs/vuepress",
43+
editLinks: true,
44+
docsDir: "packages/docs/docs"
45+
// Type is `DefaultThemeConfig`
46+
}
47+
});
48+
```
49+
50+
If you use a custom theme, you can use the `defineConfig4CustomTheme` helper with ability to pass generic type for your theme:
51+
52+
```ts
53+
import { defineConfig4CustomTheme } from "vuepress/config";
54+
55+
interface MyThemeConfig {
56+
hello: string;
57+
}
58+
59+
export default defineConfig4CustomTheme<MyThemeConfig>(
60+
{
61+
themeConfig: {
62+
// Type is `MyThemeConfig`
63+
hello: "vuepress"
64+
}
65+
},
66+
```
67+
68+
### Type Inferences for Official Plugins
69+
70+
From now, you’ll be able to enjoy the type prompt of the official plugins:
71+
72+
![](./assets/1.9-official-plugin-tuple-usage.png)
73+
74+
Options of the official plugins certainly have type prompts, **Both [Tuple Style](https://vuepress.vuejs.org/plugin/using-a-plugin.html#plugin-options) and [Object Style](https://vuepress.vuejs.org/plugin/using-a-plugin.html#plugin-options), and [Plugin Shorthand](https://vuepress.vuejs.org/plugin/using-a-plugin.html#plugin-shorthand) support type inference**:
75+
76+
- Tuple Style:
77+
78+
![](./assets/1.9-official-plugin-options.png)
79+
80+
```ts
81+
import { defineConfig } from 'vuepress/config'
82+
83+
export default defineConfig({
84+
plugins: [
85+
[
86+
'@vuepress/pwa',
87+
{
88+
serviceWorker: true
89+
}
90+
]
91+
]
92+
})
93+
```
94+
95+
- Object Style:
96+
97+
```ts
98+
import { defineConfig } from 'vuepress/config'
99+
100+
export default defineConfig({
101+
plugins: {
102+
'@vuepress/pwa': {
103+
serviceWorker: true
104+
}
105+
}
106+
})
107+
```
108+
109+
The illustration snapshot is omitted here, you can try it yourself.
110+
111+
112+
### ISO Language Code
113+
114+
Type inference supports [ISO Language Code](http://www.lingoes.net/en/translator/langcode.htm)
115+
116+
![](./assets/1.9-lang.png)
117+
118+
119+
### Context API
120+
121+
VuePress's configuration can also be a function, while its first parameter is the current [app context](https://vuepress.vuejs.org/plugin/context-api.html#context-api):
122+
123+
```ts
124+
import { defineConfig } from "vuepress/config";
125+
126+
export default defineConfig(ctx => ({
127+
// do not execute babel compilation under development
128+
evergreen: ctx.isProd
129+
}));
130+
```
131+
132+
## Limitations
133+
134+
It is worth noting that third-party plugins do not support [Plugin Shorthand](../plugin/using-a-plugin.md#plugin-shorthand) if you're using [Tuple Style](../plugin/using-a-plugin.md#plugin-options) to write your config, this is because from the perspective of the type system, the unknown shortcut is equivalent to `string`, which results in the failure of type inference.
135+
136+
By default, only officially maintained and plugins under [VuePress Community](https://vuepress-community.netlify.app/en/) support shortcut, feel free to submit pull request to add your plugin at this [file](https://github.com/vuejs/vuepress/blob/master/packages/vuepress/types/third-party-plugins.ts).
137+
138+
139+
140+
## Credits
141+
142+
- [bundle-require](https://github.com/egoist/bundle-require) (by [@egoist](https://github.com/egoist)): we leverage it under the hood to resolve user's config, which is powered by `esbuild`.
143+
- [vscode-ts-in-markdown](https://github.com/Amour1688/vscode-ts-in-markdown) (by [@Amour1688](https://github.com/Amour1688)): this documentation is powered by this plugin, which make type checking possible in markdown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@
6868
"lint-staged": "^9.3.0",
6969
"minimist": "^1.2.0",
7070
"sort-package-json": "^1.24.0",
71-
"typescript": "^3.6.3"
71+
"typescript": "4.5.2"
7272
}
7373
}

packages/@vuepress/core/lib/node/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ module.exports = class App {
6161
if (this.options.siteConfig) {
6262
this.siteConfig = this.options.siteConfig
6363
} else {
64-
let siteConfig = loadConfig(this.vuepressDir)
64+
let siteConfig = await loadConfig(this.vuepressDir)
6565
if (isFunction(siteConfig)) {
6666
siteConfig = await siteConfig(this)
6767
}

packages/@vuepress/core/lib/node/loadConfig.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ const tomlParser = require('toml')
1212
* Expose loadConfig.
1313
*/
1414

15-
module.exports = function loadConfig (vuepressDir, bustCache = true) {
15+
module.exports = async function loadConfig (vuepressDir, bustCache = true) {
1616
const configPath = path.resolve(vuepressDir, 'config.js')
1717
const configYmlPath = path.resolve(vuepressDir, 'config.yml')
1818
const configTomlPath = path.resolve(vuepressDir, 'config.toml')
19+
const configTsPath = path.resolve(vuepressDir, 'config.ts')
1920

2021
if (bustCache) {
2122
delete require.cache[configPath]
@@ -25,6 +26,11 @@ module.exports = function loadConfig (vuepressDir, bustCache = true) {
2526
let siteConfig = {}
2627
if (fs.existsSync(configYmlPath)) {
2728
siteConfig = parseConfig(configYmlPath)
29+
} else if (fs.existsSync(configTsPath)) {
30+
const { mod } = await require('bundle-require').bundleRequire({
31+
filepath: configTsPath
32+
})
33+
siteConfig = mod.default || mod
2834
} else if (fs.existsSync(configTomlPath)) {
2935
siteConfig = parseConfig(configTomlPath)
3036
} else if (fs.existsSync(configPath)) {

packages/@vuepress/core/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@
3232
"@vuepress/shared-utils": "1.8.3",
3333
"autoprefixer": "^9.5.1",
3434
"babel-loader": "^8.0.4",
35+
"bundle-require": "2.1.8",
3536
"cache-loader": "^3.0.0",
3637
"chokidar": "^2.0.3",
3738
"connect-history-api-fallback": "^1.5.0",
3839
"copy-webpack-plugin": "^5.0.2",
3940
"core-js": "^3.6.4",
4041
"cross-spawn": "^6.0.5",
4142
"css-loader": "^2.1.1",
43+
"esbuild": "0.14.7",
4244
"file-loader": "^3.0.1",
4345
"js-yaml": "^3.13.1",
4446
"lru-cache": "^5.1.1",

packages/docs/docs/.vuepress/config.js

Lines changed: 0 additions & 182 deletions
This file was deleted.

0 commit comments

Comments
 (0)