diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce9f2fcc..9fc16d76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+## [0.22.2](https://github.com/vuejs/vitepress/compare/v0.22.1...v0.22.2) (2022-02-14)
+
+### Features
+
+- improve default chunk strategy + page hash stability ([1ef69e2](https://github.com/vuejs/vitepress/commit/1ef69e212f91e43431b4fe4bdba17ca4f29a7b49))
+
+## [0.22.1](https://github.com/vuejs/vitepress/compare/v0.22.0...v0.22.1) (2022-02-14)
+
+### Features
+
+- automatically update hash map + retry on failed page fetch ([2324948](https://github.com/vuejs/vitepress/commit/23249483d60da1952c64a1f764873652b587c2dc))
+- use git-based lastUpdated data ([d32d8d4](https://github.com/vuejs/vitepress/commit/d32d8d441917dcb480a6735da78c2d6fc3e589c0))
+
+ Note: lastUpdated data is now disabled by default due to the performance overhead of retrieving the git information. This also means each page's metadata object no longer contains the `lastUpdated` property by default - it will only be present if the new `lastUpdated: true` config option is enabled.
+
+# [0.22.0](https://github.com/vuejs/vitepress/compare/v0.21.6...v0.22.0) (2022-02-11)
+
+- Upgrade to Vite 2.8
+
## [0.21.6](https://github.com/vuejs/vitepress/compare/v0.21.5...v0.21.6) (2022-01-19)
### Perf
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index 0c326ba5..cfb87e63 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -4,6 +4,7 @@ export default defineConfig({
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
+ lastUpdated: true,
themeConfig: {
repo: 'vuejs/vitepress',
diff --git a/package.json b/package.json
index 7a848579..6c6e963a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vitepress",
- "version": "0.21.6",
+ "version": "0.22.2",
"description": "Vite & Vue powered static site generator",
"main": "dist/node/index.js",
"typings": "types/index.d.ts",
@@ -38,6 +38,7 @@
"docs-dev": "node ./bin/vitepress dev docs",
"docs-debug": "node --inspect-brk ./bin/vitepress dev docs",
"docs-build": "npm run build && node ./bin/vitepress build docs",
+ "docs-build-only": "node ./bin/vitepress build docs",
"docs-serve": "node ./bin/vitepress serve docs",
"ci-docs": "run-s build docs-build"
},
@@ -73,10 +74,10 @@
"dependencies": {
"@docsearch/css": "^3.0.0-alpha.41",
"@docsearch/js": "^3.0.0-alpha.41",
- "@vitejs/plugin-vue": "^2.0.0",
+ "@vitejs/plugin-vue": "^2.2.0",
"prismjs": "^1.25.0",
- "vite": "^2.7.12",
- "vue": "^3.2.27"
+ "vite": "^2.8.1",
+ "vue": "^3.2.31"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.18.9",
@@ -85,6 +86,7 @@
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@types/compression": "^1.7.0",
+ "@types/cross-spawn": "^6.0.2",
"@types/debug": "^4.1.7",
"@types/fs-extra": "^9.0.11",
"@types/koa": "^2.13.1",
@@ -98,6 +100,7 @@
"chokidar": "^3.5.1",
"compression": "^1.7.4",
"conventional-changelog-cli": "^2.1.1",
+ "cross-spawn": "^7.0.3",
"debug": "^4.3.2",
"diacritics": "^1.3.0",
"enquirer": "^2.3.6",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 39615105..bfdad189 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,6 +12,7 @@ importers:
'@rollup/plugin-json': ^4.1.0
'@rollup/plugin-node-resolve': ^13.0.4
'@types/compression': ^1.7.0
+ '@types/cross-spawn': ^6.0.2
'@types/debug': ^4.1.7
'@types/fs-extra': ^9.0.11
'@types/koa': ^2.13.1
@@ -21,11 +22,12 @@ importers:
'@types/micromatch': ^4.0.2
'@types/node': ^15.6.1
'@types/polka': ^0.5.3
- '@vitejs/plugin-vue': ^2.0.0
+ '@vitejs/plugin-vue': ^2.2.0
chalk: ^4.1.1
chokidar: ^3.5.1
compression: ^1.7.4
conventional-changelog-cli: ^2.1.1
+ cross-spawn: ^7.0.3
debug: ^4.3.2
diacritics: ^1.3.0
enquirer: ^2.3.6
@@ -57,17 +59,17 @@ importers:
semver: ^7.3.5
sirv: ^1.0.12
typescript: ^4.3.2
- vite: ^2.7.12
+ vite: ^2.8.1
vitest: ^0.1.19
- vue: ^3.2.27
+ vue: ^3.2.31
yorkie: ^2.0.0
dependencies:
'@docsearch/css': 3.0.0-alpha.41
'@docsearch/js': 3.0.0-alpha.41
- '@vitejs/plugin-vue': 2.0.0_vite@2.7.12+vue@3.2.27
+ '@vitejs/plugin-vue': 2.2.0_vite@2.8.1+vue@3.2.31
prismjs: 1.25.0
- vite: 2.7.12
- vue: 3.2.27
+ vite: 2.8.1
+ vue: 3.2.31
devDependencies:
'@microsoft/api-extractor': 7.18.11
'@rollup/plugin-alias': 3.1.5_rollup@2.57.0
@@ -75,6 +77,7 @@ importers:
'@rollup/plugin-json': 4.1.0_rollup@2.57.0
'@rollup/plugin-node-resolve': 13.0.5_rollup@2.57.0
'@types/compression': 1.7.2
+ '@types/cross-spawn': 6.0.2
'@types/debug': 4.1.7
'@types/fs-extra': 9.0.13
'@types/koa': 2.13.4
@@ -88,6 +91,7 @@ importers:
chokidar: 3.5.2
compression: 1.7.4
conventional-changelog-cli: 2.1.1
+ cross-spawn: 7.0.3
debug: 4.3.2
diacritics: 1.3.0
enquirer: 2.3.6
@@ -544,6 +548,12 @@ packages:
'@types/node': 15.14.9
dev: true
+ /@types/cross-spawn/6.0.2:
+ resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==}
+ dependencies:
+ '@types/node': 15.14.9
+ dev: true
+
/@types/debug/4.1.7:
resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
dependencies:
@@ -713,98 +723,98 @@ packages:
resolution: {integrity: sha512-4LPNrqSJknLzILMVXn2P/mh0djNgFvom4T9Y1hmhaB8OBm1cY71bMMSrGRu1q5qF4JZzY6iaGT11BHmCMY/NZg==}
dev: true
- /@vitejs/plugin-vue/2.0.0_vite@2.7.12+vue@3.2.27:
- resolution: {integrity: sha512-4Xn1h9OcaAf7KYrvz2oEi52fCCCLcCzyr3pDOrzYTWrs0DrzNOXt9fT5IiGb1f/uoNTdX3aAkXVGNXrGkzF/zw==}
+ /@vitejs/plugin-vue/2.2.0_vite@2.8.1+vue@3.2.31:
+ resolution: {integrity: sha512-wXigM1EwN2G7rZcwG6kLk9ivvIMhx2363tCEvMBiXcTu5nePM/12hUPVzPb83Uugt6U+zom1gTpJopi/Ow/jwg==}
engines: {node: '>=12.0.0'}
peerDependencies:
vite: ^2.5.10
vue: ^3.2.25
dependencies:
- vite: 2.7.12
- vue: 3.2.27
+ vite: 2.8.1
+ vue: 3.2.31
dev: false
- /@vue/compiler-core/3.2.27:
- resolution: {integrity: sha512-JyxAglSM/pb9paG5ZNuKrf5IUpzLzQA3khjWGF9oESELCLQlt6O3YyPMR2A69wIpYWrf5mScZ8YY8TJKOI/1kQ==}
+ /@vue/compiler-core/3.2.31:
+ resolution: {integrity: sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==}
dependencies:
'@babel/parser': 7.16.4
- '@vue/shared': 3.2.27
+ '@vue/shared': 3.2.31
estree-walker: 2.0.2
source-map: 0.6.1
dev: false
- /@vue/compiler-dom/3.2.27:
- resolution: {integrity: sha512-NyQ7nEbopUBPUMHM4c3FPCbFbnQwptoPjW5Y5qfJ7hfiCNhOuhQsDNqi5JYKBxfpxiFNwjcN9F8t1AsnLrDloQ==}
+ /@vue/compiler-dom/3.2.31:
+ resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==}
dependencies:
- '@vue/compiler-core': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/compiler-core': 3.2.31
+ '@vue/shared': 3.2.31
dev: false
- /@vue/compiler-sfc/3.2.27:
- resolution: {integrity: sha512-WyecUhLN5UAQAr2QlmG2nA56OEnhZJaBnSw0G1tazb9rwDuK0V9tnbIXbQgmQlx+x4sJxgg61yWGcIXfilTl3A==}
+ /@vue/compiler-sfc/3.2.31:
+ resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==}
dependencies:
'@babel/parser': 7.16.4
- '@vue/compiler-core': 3.2.27
- '@vue/compiler-dom': 3.2.27
- '@vue/compiler-ssr': 3.2.27
- '@vue/reactivity-transform': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/compiler-core': 3.2.31
+ '@vue/compiler-dom': 3.2.31
+ '@vue/compiler-ssr': 3.2.31
+ '@vue/reactivity-transform': 3.2.31
+ '@vue/shared': 3.2.31
estree-walker: 2.0.2
magic-string: 0.25.7
- postcss: 8.4.5
+ postcss: 8.4.6
source-map: 0.6.1
dev: false
- /@vue/compiler-ssr/3.2.27:
- resolution: {integrity: sha512-+l09t319iV7HVSrXfBw9OLwMZIPOFTXmHjZ61Bc5ZcwKqOYAR4uTurKpoXAfcSc5qs/q6WdE9jY3nrP0LUEMQQ==}
+ /@vue/compiler-ssr/3.2.31:
+ resolution: {integrity: sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==}
dependencies:
- '@vue/compiler-dom': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/compiler-dom': 3.2.31
+ '@vue/shared': 3.2.31
dev: false
- /@vue/reactivity-transform/3.2.27:
- resolution: {integrity: sha512-67//61ObGxGnVrPhjygocb24eYUh+TFMhkm7szm8v5XdKXjkNl7qgIOflwGvUnwuIRJmr9nZ7+PvY0fL+H2upA==}
+ /@vue/reactivity-transform/3.2.31:
+ resolution: {integrity: sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==}
dependencies:
'@babel/parser': 7.16.4
- '@vue/compiler-core': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/compiler-core': 3.2.31
+ '@vue/shared': 3.2.31
estree-walker: 2.0.2
magic-string: 0.25.7
dev: false
- /@vue/reactivity/3.2.27:
- resolution: {integrity: sha512-QPfIQEJidRGIu/mPexhcB4csp1LEg2Nr+/QE72MnXs/OYDtFErhC9FxIyymkxp/xvAgL5wsnSOuDD6zWF42vRQ==}
+ /@vue/reactivity/3.2.31:
+ resolution: {integrity: sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==}
dependencies:
- '@vue/shared': 3.2.27
+ '@vue/shared': 3.2.31
dev: false
- /@vue/runtime-core/3.2.27:
- resolution: {integrity: sha512-NJrjuViHJyrT4bwIocbE4XDaDlA1Pj61pQlneZZdFEvgdMLlhzCCiJ4WZnWcohYQeisUAZjEFKK8GjQieDPFbw==}
+ /@vue/runtime-core/3.2.31:
+ resolution: {integrity: sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==}
dependencies:
- '@vue/reactivity': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/reactivity': 3.2.31
+ '@vue/shared': 3.2.31
dev: false
- /@vue/runtime-dom/3.2.27:
- resolution: {integrity: sha512-tlnKkvBSkV7MPUp/wRFsYcv67U1rUeZTPfpPzq5Kpmw5NNGkY6J075fFBH2k0MNxDucXS+qfStNrxAyGTUMkSA==}
+ /@vue/runtime-dom/3.2.31:
+ resolution: {integrity: sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==}
dependencies:
- '@vue/runtime-core': 3.2.27
- '@vue/shared': 3.2.27
+ '@vue/runtime-core': 3.2.31
+ '@vue/shared': 3.2.31
csstype: 2.6.18
dev: false
- /@vue/server-renderer/3.2.27_vue@3.2.27:
- resolution: {integrity: sha512-dZnzkFCDe6A/GIe/F1LcG6lWpprHVh62DjTv8wubtkHwfJWOmOeHp+KvPDRrswL/L3ghsm+E31xY+pvkgM3pbQ==}
+ /@vue/server-renderer/3.2.31_vue@3.2.31:
+ resolution: {integrity: sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==}
peerDependencies:
- vue: 3.2.27
+ vue: 3.2.31
dependencies:
- '@vue/compiler-ssr': 3.2.27
- '@vue/shared': 3.2.27
- vue: 3.2.27
+ '@vue/compiler-ssr': 3.2.31
+ '@vue/shared': 3.2.31
+ vue: 3.2.31
dev: false
- /@vue/shared/3.2.27:
- resolution: {integrity: sha512-rpAn9k6O08Lvo7ekBIAnkOukX/4EsEQLPrRJBKhIEasMsOI5eX0f6mq1sDUSY7cgAqWw2d7QtP74CWxdXoyKxA==}
+ /@vue/shared/3.2.31:
+ resolution: {integrity: sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==}
dev: false
/JSONStream/1.3.5:
@@ -1537,8 +1547,9 @@ packages:
is-symbol: 1.0.4
dev: true
- /esbuild-android-arm64/0.13.15:
- resolution: {integrity: sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==}
+ /esbuild-android-arm64/0.14.21:
+ resolution: {integrity: sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ==}
+ engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
@@ -1552,8 +1563,9 @@ packages:
dev: true
optional: true
- /esbuild-darwin-64/0.13.15:
- resolution: {integrity: sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==}
+ /esbuild-darwin-64/0.14.21:
+ resolution: {integrity: sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
@@ -1567,8 +1579,9 @@ packages:
dev: true
optional: true
- /esbuild-darwin-arm64/0.13.15:
- resolution: {integrity: sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==}
+ /esbuild-darwin-arm64/0.14.21:
+ resolution: {integrity: sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ==}
+ engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
@@ -1582,8 +1595,9 @@ packages:
dev: true
optional: true
- /esbuild-freebsd-64/0.13.15:
- resolution: {integrity: sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==}
+ /esbuild-freebsd-64/0.14.21:
+ resolution: {integrity: sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
@@ -1597,8 +1611,9 @@ packages:
dev: true
optional: true
- /esbuild-freebsd-arm64/0.13.15:
- resolution: {integrity: sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==}
+ /esbuild-freebsd-arm64/0.14.21:
+ resolution: {integrity: sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA==}
+ engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
@@ -1612,8 +1627,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-32/0.13.15:
- resolution: {integrity: sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==}
+ /esbuild-linux-32/0.14.21:
+ resolution: {integrity: sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg==}
+ engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
@@ -1627,8 +1643,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-64/0.13.15:
- resolution: {integrity: sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==}
+ /esbuild-linux-64/0.14.21:
+ resolution: {integrity: sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
@@ -1642,8 +1659,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-arm/0.13.15:
- resolution: {integrity: sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==}
+ /esbuild-linux-arm/0.14.21:
+ resolution: {integrity: sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w==}
+ engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
@@ -1657,8 +1675,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-arm64/0.13.15:
- resolution: {integrity: sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==}
+ /esbuild-linux-arm64/0.14.21:
+ resolution: {integrity: sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g==}
+ engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
@@ -1672,8 +1691,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-mips64le/0.13.15:
- resolution: {integrity: sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==}
+ /esbuild-linux-mips64le/0.14.21:
+ resolution: {integrity: sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A==}
+ engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
@@ -1687,8 +1707,9 @@ packages:
dev: true
optional: true
- /esbuild-linux-ppc64le/0.13.15:
- resolution: {integrity: sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==}
+ /esbuild-linux-ppc64le/0.14.21:
+ resolution: {integrity: sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ==}
+ engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
@@ -1702,8 +1723,25 @@ packages:
dev: true
optional: true
- /esbuild-netbsd-64/0.13.15:
- resolution: {integrity: sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==}
+ /esbuild-linux-riscv64/0.14.21:
+ resolution: {integrity: sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /esbuild-linux-s390x/0.14.21:
+ resolution: {integrity: sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /esbuild-netbsd-64/0.14.21:
+ resolution: {integrity: sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
@@ -1717,8 +1755,9 @@ packages:
dev: true
optional: true
- /esbuild-openbsd-64/0.13.15:
- resolution: {integrity: sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==}
+ /esbuild-openbsd-64/0.14.21:
+ resolution: {integrity: sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
@@ -1732,8 +1771,9 @@ packages:
dev: true
optional: true
- /esbuild-sunos-64/0.13.15:
- resolution: {integrity: sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==}
+ /esbuild-sunos-64/0.14.21:
+ resolution: {integrity: sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
@@ -1747,8 +1787,9 @@ packages:
dev: true
optional: true
- /esbuild-windows-32/0.13.15:
- resolution: {integrity: sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==}
+ /esbuild-windows-32/0.14.21:
+ resolution: {integrity: sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A==}
+ engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
@@ -1762,8 +1803,9 @@ packages:
dev: true
optional: true
- /esbuild-windows-64/0.13.15:
- resolution: {integrity: sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==}
+ /esbuild-windows-64/0.14.21:
+ resolution: {integrity: sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA==}
+ engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
@@ -1777,8 +1819,9 @@ packages:
dev: true
optional: true
- /esbuild-windows-arm64/0.13.15:
- resolution: {integrity: sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==}
+ /esbuild-windows-arm64/0.14.21:
+ resolution: {integrity: sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw==}
+ engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
@@ -1792,28 +1835,31 @@ packages:
dev: true
optional: true
- /esbuild/0.13.15:
- resolution: {integrity: sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==}
+ /esbuild/0.14.21:
+ resolution: {integrity: sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A==}
+ engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
- esbuild-android-arm64: 0.13.15
- esbuild-darwin-64: 0.13.15
- esbuild-darwin-arm64: 0.13.15
- esbuild-freebsd-64: 0.13.15
- esbuild-freebsd-arm64: 0.13.15
- esbuild-linux-32: 0.13.15
- esbuild-linux-64: 0.13.15
- esbuild-linux-arm: 0.13.15
- esbuild-linux-arm64: 0.13.15
- esbuild-linux-mips64le: 0.13.15
- esbuild-linux-ppc64le: 0.13.15
- esbuild-netbsd-64: 0.13.15
- esbuild-openbsd-64: 0.13.15
- esbuild-sunos-64: 0.13.15
- esbuild-windows-32: 0.13.15
- esbuild-windows-64: 0.13.15
- esbuild-windows-arm64: 0.13.15
+ esbuild-android-arm64: 0.14.21
+ esbuild-darwin-64: 0.14.21
+ esbuild-darwin-arm64: 0.14.21
+ esbuild-freebsd-64: 0.14.21
+ esbuild-freebsd-arm64: 0.14.21
+ esbuild-linux-32: 0.14.21
+ esbuild-linux-64: 0.14.21
+ esbuild-linux-arm: 0.14.21
+ esbuild-linux-arm64: 0.14.21
+ esbuild-linux-mips64le: 0.14.21
+ esbuild-linux-ppc64le: 0.14.21
+ esbuild-linux-riscv64: 0.14.21
+ esbuild-linux-s390x: 0.14.21
+ esbuild-netbsd-64: 0.14.21
+ esbuild-openbsd-64: 0.14.21
+ esbuild-sunos-64: 0.14.21
+ esbuild-windows-32: 0.14.21
+ esbuild-windows-64: 0.14.21
+ esbuild-windows-arm64: 0.14.21
/esbuild/0.14.3:
resolution: {integrity: sha512-zyEC5hkguW2oieXRXp8VJzQdcO/1FxCS5GjzqOHItRlojXnx/cTavsrkxdWvBH9li2lUq0bN+LeeVEmyCwiR/Q==}
@@ -2271,6 +2317,12 @@ packages:
resolution: {integrity: sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==}
dependencies:
has: 1.0.3
+ dev: true
+
+ /is-core-module/2.8.1:
+ resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
+ dependencies:
+ has: 1.0.3
/is-date-object/1.0.5:
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
@@ -2769,8 +2821,8 @@ packages:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
- /nanoid/3.1.30:
- resolution: {integrity: sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==}
+ /nanoid/3.2.0:
+ resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
@@ -2791,7 +2843,7 @@ packages:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
dependencies:
hosted-git-info: 2.8.9
- resolve: 1.20.0
+ resolve: 1.22.0
semver: 5.7.1
validate-npm-package-license: 3.0.4
dev: true
@@ -2801,7 +2853,7 @@ packages:
engines: {node: '>=10'}
dependencies:
hosted-git-info: 4.0.2
- is-core-module: 2.6.0
+ is-core-module: 2.8.1
semver: 7.3.5
validate-npm-package-license: 3.0.4
dev: true
@@ -3054,13 +3106,13 @@ packages:
trouter: 2.0.1
dev: true
- /postcss/8.4.5:
- resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==}
+ /postcss/8.4.6:
+ resolution: {integrity: sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
- nanoid: 3.1.30
+ nanoid: 3.2.0
picocolors: 1.0.0
- source-map-js: 1.0.1
+ source-map-js: 1.0.2
/preact/10.5.15:
resolution: {integrity: sha512-5chK29n6QcJc3m1lVrKQSQ+V7K1Gb8HeQY6FViQ5AxCAEGu3DaHffWNDkC9+miZgsLvbvU9rxbV1qinGHMHzqA==}
@@ -3194,7 +3246,7 @@ packages:
/resolve/1.19.0:
resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
dependencies:
- is-core-module: 2.6.0
+ is-core-module: 2.8.1
path-parse: 1.0.7
dev: true
@@ -3203,6 +3255,15 @@ packages:
dependencies:
is-core-module: 2.6.0
path-parse: 1.0.7
+ dev: true
+
+ /resolve/1.22.0:
+ resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.8.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
/restore-cursor/3.1.0:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
@@ -3380,8 +3441,8 @@ packages:
is-fullwidth-code-point: 3.0.0
dev: true
- /source-map-js/1.0.1:
- resolution: {integrity: sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==}
+ /source-map-js/1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
/source-map/0.6.1:
@@ -3545,6 +3606,10 @@ packages:
has-flag: 4.0.0
dev: true
+ /supports-preserve-symlinks-flag/1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
/temp-dir/2.0.0:
resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
engines: {node: '>=8'}
@@ -3717,8 +3782,8 @@ packages:
engines: {node: '>= 0.8'}
dev: true
- /vite/2.7.12:
- resolution: {integrity: sha512-KvPYToRQWhRfBeVkyhkZ5hASuHQkqZUUdUcE3xyYtq5oYEPIJ0h9LWiWTO6v990glmSac2cEPeYeXzpX5Z6qKQ==}
+ /vite/2.8.1:
+ resolution: {integrity: sha512-Typ8qjUnW0p53gBsJpisrKcZlEbUPZATja9BG6Z09QZjg9YrnEn/htkr/VH4WhnH7eNUQeSD+wKI1lHzQRWskw==}
engines: {node: '>=12.2.0'}
hasBin: true
peerDependencies:
@@ -3733,9 +3798,9 @@ packages:
stylus:
optional: true
dependencies:
- esbuild: 0.13.15
- postcss: 8.4.5
- resolve: 1.20.0
+ esbuild: 0.14.21
+ postcss: 8.4.6
+ resolve: 1.22.0
rollup: 2.60.1
optionalDependencies:
fsevents: 2.3.2
@@ -3765,21 +3830,21 @@ packages:
local-pkg: 0.4.1
tinypool: 0.1.1
tinyspy: 0.2.8
- vite: 2.7.12
+ vite: 2.8.1
transitivePeerDependencies:
- less
- sass
- stylus
dev: true
- /vue/3.2.27:
- resolution: {integrity: sha512-p1cH8Q6eaPwvANCjFQj497a914cxXKKwOG3Lg9USddTOrn4/zFMKjn9dnovkx+L8VtFaNgbVqW8mLJS/eTA6xw==}
+ /vue/3.2.31:
+ resolution: {integrity: sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==}
dependencies:
- '@vue/compiler-dom': 3.2.27
- '@vue/compiler-sfc': 3.2.27
- '@vue/runtime-dom': 3.2.27
- '@vue/server-renderer': 3.2.27_vue@3.2.27
- '@vue/shared': 3.2.27
+ '@vue/compiler-dom': 3.2.31
+ '@vue/compiler-sfc': 3.2.31
+ '@vue/runtime-dom': 3.2.31
+ '@vue/server-renderer': 3.2.31_vue@3.2.31
+ '@vue/shared': 3.2.31
dev: false
/wcwidth/1.0.1:
diff --git a/scripts/release.js b/scripts/release.js
index ba93a43e..8e5cef88 100644
--- a/scripts/release.js
+++ b/scripts/release.js
@@ -9,7 +9,6 @@ const currentVersion = require('../package.json').version
const versionIncrements = ['patch', 'minor', 'major']
const inc = (i) => semver.inc(currentVersion, i)
-const bin = (name) => path.resolve(__dirname, `../node_modules/.bin/${name}`)
const run = (bin, args, opts = {}) =>
execa(bin, args, { stdio: 'inherit', ...opts })
const step = (msg) => console.log(chalk.cyan(msg))
diff --git a/src/client/app/router.ts b/src/client/app/router.ts
index 0b3d523f..f7c2a397 100644
--- a/src/client/app/router.ts
+++ b/src/client/app/router.ts
@@ -58,7 +58,7 @@ export function createRouter(
let latestPendingPath: string | null = null
- async function loadPage(href: string, scrollPosition = 0) {
+ async function loadPage(href: string, scrollPosition = 0, isRetry = false) {
const targetLoc = new URL(href, fakeHost)
const pendingPath = (latestPendingPath = targetLoc.pathname)
try {
@@ -106,6 +106,19 @@ export function createRouter(
if (!err.message.match(/fetch/)) {
console.error(err)
}
+
+ // retry on fetch fail: the page to hash map may have been invalidated
+ // because a new deploy happened while the page is open. Try to fetch
+ // the updated pageToHash map and fetch again.
+ if (!isRetry) {
+ try {
+ const res = await fetch(siteDataRef.value.base + 'hashmap.json')
+ ;(window as any).__VP_HASH_MAP__ = await res.json()
+ await loadPage(href, scrollPosition, true)
+ return
+ } catch (e) {}
+ }
+
if (latestPendingPath === pendingPath) {
latestPendingPath = null
route.path = pendingPath
@@ -185,7 +198,7 @@ function scrollTo(el: HTMLElement, hash: string, smooth = false) {
let target: Element | null = null
try {
- target = el.classList.contains('.header-anchor')
+ target = el.classList.contains('header-anchor')
? el
: document.querySelector(decodeURIComponent(hash))
} catch (e) {
diff --git a/src/client/theme-default/Layout.vue b/src/client/theme-default/Layout.vue
index f14ed8ee..26ba9b4c 100644
--- a/src/client/theme-default/Layout.vue
+++ b/src/client/theme-default/Layout.vue
@@ -4,12 +4,11 @@ import { useRoute, useData } from 'vitepress'
import { isSideBarEmpty, getSideBarConfig } from './support/sideBar'
// components
+import Home from './components/Home.vue'
import NavBar from './components/NavBar.vue'
import SideBar from './components/SideBar.vue'
import Page from './components/Page.vue'
-const Home = defineAsyncComponent(() => import('./components/Home.vue'))
-
const NoopComponent = () => null
const CarbonAds = __CARBON__
diff --git a/src/client/theme-default/components/LastUpdated.vue b/src/client/theme-default/components/LastUpdated.vue
index ab888fbc..f495a083 100644
--- a/src/client/theme-default/components/LastUpdated.vue
+++ b/src/client/theme-default/components/LastUpdated.vue
@@ -1,5 +1,5 @@
diff --git a/src/client/theme-default/components/PageFooter.vue b/src/client/theme-default/components/PageFooter.vue
index 41e1dded..93c7ce60 100644
--- a/src/client/theme-default/components/PageFooter.vue
+++ b/src/client/theme-default/components/PageFooter.vue
@@ -1,6 +1,9 @@
@@ -9,7 +12,7 @@ import LastUpdated from './LastUpdated.vue'
-
+
diff --git a/src/node/build/build.ts b/src/node/build/build.ts
index 7ed05aea..6dd1d2b2 100644
--- a/src/node/build/build.ts
+++ b/src/node/build/build.ts
@@ -5,6 +5,7 @@ import { resolveConfig } from '../config'
import { renderPage } from './render'
import { OutputChunk, OutputAsset } from 'rollup'
import ora from 'ora'
+import path from 'path'
export async function build(
root: string,
@@ -68,6 +69,13 @@ export async function build(
spinner.stopAndPersist({
symbol: okMark
})
+
+ // emit page hash map for the case where a user session is open
+ // when the site got redeployed (which invalidates current hash map)
+ fs.writeJSONSync(
+ path.join(siteConfig.outDir, 'hashmap.json'),
+ pageToHashMap
+ )
} finally {
await fs.remove(siteConfig.tempDir)
}
diff --git a/src/node/build/bundle.ts b/src/node/build/bundle.ts
index bb736847..7a5a46f1 100644
--- a/src/node/build/bundle.ts
+++ b/src/node/build/bundle.ts
@@ -73,13 +73,25 @@ export async function bundle(
...(ssr
? {}
: {
- chunkFileNames(chunk): string {
- if (!chunk.isEntry && /runtime/.test(chunk.name)) {
- return `assets/framework.[hash].js`
+ chunkFileNames(chunk) {
+ // avoid ads chunk being intercepted by adblock
+ return /(?:Carbon|BuySell)Ads/.test(chunk.name)
+ ? `assets/chunks/ui-custom.[hash].js`
+ : `assets/chunks/[name].[hash].js`
+ },
+ manualChunks(id, ctx) {
+ // move known framework code into a stable chunk so that
+ // custom theme changes do not invalidate hash for all pages
+ if (id.includes('plugin-vue:export-helper')) {
+ return 'framework'
+ }
+ if (
+ isEagerChunk(id, ctx) &&
+ (/@vue\/(runtime|shared|reactivity)/.test(id) ||
+ /vitepress\/dist\/client/.test(id))
+ ) {
+ return 'framework'
}
- return adComponentRE.test(chunk.name)
- ? `assets/ui-custom.[hash].js`
- : `assets/[name].[hash].js`
}
})
}
@@ -133,4 +145,53 @@ export async function bundle(
return { clientResult, serverResult, pageToHashMap }
}
-const adComponentRE = /(?:Carbon|BuySell)Ads/
+const cache = new Map()
+
+/**
+ * Check if a module is statically imported by at least one entry.
+ */
+function isEagerChunk(id: string, { getModuleInfo }: any) {
+ if (
+ id.includes('node_modules') &&
+ !/\.css($|\\?)/.test(id) &&
+ staticImportedByEntry(id, getModuleInfo, cache)
+ ) {
+ return 'vendor'
+ }
+}
+
+function staticImportedByEntry(
+ id: string,
+ getModuleInfo: any,
+ cache: Map,
+ importStack: string[] = []
+): boolean {
+ if (cache.has(id)) {
+ return cache.get(id) as boolean
+ }
+ if (importStack.includes(id)) {
+ // circular deps!
+ cache.set(id, false)
+ return false
+ }
+ const mod = getModuleInfo(id)
+ if (!mod) {
+ cache.set(id, false)
+ return false
+ }
+
+ if (mod.isEntry) {
+ cache.set(id, true)
+ return true
+ }
+ const someImporterIs = mod.importers.some((importer: string) =>
+ staticImportedByEntry(
+ importer,
+ getModuleInfo,
+ cache,
+ importStack.concat(id)
+ )
+ )
+ cache.set(id, someImporterIs)
+ return someImporterIs
+}
diff --git a/src/node/config.ts b/src/node/config.ts
index f2453951..a9277b85 100644
--- a/src/node/config.ts
+++ b/src/node/config.ts
@@ -37,6 +37,7 @@ export interface UserConfig {
themeConfig?: ThemeConfig
locales?: Record
markdown?: MarkdownOptions
+ lastUpdated?: boolean
/**
* Options to pass on to `@vitejs/plugin-vue`
*/
@@ -72,7 +73,7 @@ export type RawConfigExports =
export interface SiteConfig
extends Pick<
UserConfig,
- 'markdown' | 'vue' | 'vite' | 'shouldPreload' | 'mpa'
+ 'markdown' | 'vue' | 'vite' | 'shouldPreload' | 'mpa' | 'lastUpdated'
> {
root: string
srcDir: string
@@ -145,6 +146,7 @@ export async function resolveConfig(
outDir,
tempDir: resolve(root, '.temp'),
markdown: userConfig.markdown,
+ lastUpdated: userConfig.lastUpdated,
alias: resolveAliases(root, themeDir),
vue: userConfig.vue,
vite: userConfig.vite,
diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts
index 4f3e0b7e..46cbff35 100644
--- a/src/node/markdown/markdown.ts
+++ b/src/node/markdown/markdown.ts
@@ -50,7 +50,8 @@ export type { Header }
export const createMarkdownRenderer = (
srcDir: string,
- options: MarkdownOptions = {}
+ options: MarkdownOptions = {},
+ base: string
): MarkdownRenderer => {
const md = MarkdownIt({
html: true,
@@ -68,11 +69,15 @@ export const createMarkdownRenderer = (
.use(containerPlugin)
.use(headingPlugin)
.use(imagePlugin)
- .use(linkPlugin, {
- target: '_blank',
- rel: 'noopener noreferrer',
- ...options.externalLinks
- })
+ .use(
+ linkPlugin,
+ {
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ ...options.externalLinks
+ },
+ base
+ )
// 3rd party plugins
.use(attrs, options.attrs)
.use(anchor, {
diff --git a/src/node/markdown/plugins/link.ts b/src/node/markdown/plugins/link.ts
index e44c043a..d1448bc8 100644
--- a/src/node/markdown/plugins/link.ts
+++ b/src/node/markdown/plugins/link.ts
@@ -11,7 +11,8 @@ const indexRE = /(^|.*\/)index.md(#?.*)$/i
export const linkPlugin = (
md: MarkdownIt,
- externalAttrs: Record
+ externalAttrs: Record,
+ base: string
) => {
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx]
@@ -76,6 +77,11 @@ export const linkPlugin = (
// export it for existence check
pushLink(url.replace(/\.html$/, ''))
+ // append base to internal (non-relative) urls
+ if (url.startsWith('/')) {
+ url = `${base}${url}`.replace(/\/+/g, '/')
+ }
+
// markdown-it encodes the uri
hrefAttr[1] = decodeURI(url)
}
diff --git a/src/node/markdownToVue.ts b/src/node/markdownToVue.ts
index a596e22b..29db7461 100644
--- a/src/node/markdownToVue.ts
+++ b/src/node/markdownToVue.ts
@@ -8,6 +8,7 @@ import { PageData, HeadConfig, EXTERNAL_URL_RE } from './shared'
import { slash } from './utils/slash'
import chalk from 'chalk'
import _debug from 'debug'
+import { getGitTimestamp } from './utils/getGitTimestamp'
const debug = _debug('vitepress:md')
const cache = new LRUCache({ max: 1024 })
@@ -25,9 +26,11 @@ export function createMarkdownToVueRenderFn(
options: MarkdownOptions = {},
pages: string[],
userDefines: Record | undefined,
- isBuild = false
+ isBuild = false,
+ base: string,
+ includeLastUpdatedData = false
) {
- const md = createMarkdownRenderer(srcDir, options)
+ const md = createMarkdownRenderer(srcDir, options, base)
pages = pages.map((p) => slash(p.replace(/\.md$/, '')))
const userDefineRegex = userDefines
@@ -39,11 +42,11 @@ export function createMarkdownToVueRenderFn(
)
: null
- return (
+ return async (
src: string,
file: string,
publicDir: string
- ): MarkdownCompileResult => {
+ ): Promise => {
const relativePath = slash(path.relative(srcDir, file))
const dir = path.dirname(file)
@@ -132,9 +135,11 @@ export function createMarkdownToVueRenderFn(
description: inferDescription(frontmatter),
frontmatter,
headers: data.headers || [],
- relativePath,
- // TODO use git timestamp?
- lastUpdated: Math.round(fs.statSync(file).mtimeMs)
+ relativePath
+ }
+
+ if (includeLastUpdatedData) {
+ pageData.lastUpdated = await getGitTimestamp(file)
}
const vueSrc =
diff --git a/src/node/plugin.ts b/src/node/plugin.ts
index fc6d8e6f..7f6e6f33 100644
--- a/src/node/plugin.ts
+++ b/src/node/plugin.ts
@@ -1,10 +1,7 @@
import path from 'path'
import { defineConfig, mergeConfig, Plugin, ResolvedConfig } from 'vite'
import { SiteConfig, resolveSiteData } from './config'
-import {
- createMarkdownToVueRenderFn,
- MarkdownCompileResult
-} from './markdownToVue'
+import { createMarkdownToVueRenderFn } from './markdownToVue'
import { DIST_CLIENT_PATH, APP_PATH, SITE_DATA_REQUEST_PATH } from './alias'
import { slash } from './utils/slash'
import { OutputAsset, OutputChunk } from 'rollup'
@@ -49,11 +46,7 @@ export function createVitePressPlugin(
pages
} = siteConfig
- let markdownToVue: (
- src: string,
- file: string,
- publicDir: string
- ) => MarkdownCompileResult
+ let markdownToVue: ReturnType
// lazy require plugin-vue to respect NODE_ENV in @vue/compiler-x
const vuePlugin = require('@vitejs/plugin-vue')({
@@ -84,7 +77,9 @@ export function createVitePressPlugin(
markdown,
pages,
config.define,
- config.command === 'build'
+ config.command === 'build',
+ config.base,
+ siteConfig.lastUpdated
)
},
@@ -131,12 +126,12 @@ export function createVitePressPlugin(
}
},
- transform(code, id) {
+ async transform(code, id) {
if (id.endsWith('.vue')) {
return processClientJS(code, id)
} else if (id.endsWith('.md')) {
// transform .md files into vueSrc so plugin-vue can handle it
- const { vueSrc, deadLinks, includes } = markdownToVue(
+ const { vueSrc, deadLinks, includes } = await markdownToVue(
code,
id,
config.publicDir
@@ -257,7 +252,7 @@ export function createVitePressPlugin(
// hot reload .md files as .vue files
if (file.endsWith('.md')) {
const content = await read()
- const { pageData, vueSrc } = markdownToVue(
+ const { pageData, vueSrc } = await markdownToVue(
content,
file,
config.publicDir
diff --git a/src/node/utils/getGitTimestamp.ts b/src/node/utils/getGitTimestamp.ts
new file mode 100644
index 00000000..07c4d820
--- /dev/null
+++ b/src/node/utils/getGitTimestamp.ts
@@ -0,0 +1,13 @@
+import { spawn } from 'cross-spawn'
+
+export function getGitTimestamp(file: string) {
+ return new Promise((resolve, reject) => {
+ const child = spawn('git', ['log', '-1', '--pretty="%ci"', file])
+ let output = ''
+ child.stdout.on('data', (d) => (output += String(d)))
+ child.on('close', () => {
+ resolve(+new Date(output))
+ })
+ child.on('error', reject)
+ })
+}
diff --git a/types/shared.d.ts b/types/shared.d.ts
index 8f41bc5e..645c0114 100644
--- a/types/shared.d.ts
+++ b/types/shared.d.ts
@@ -8,7 +8,7 @@ export interface PageData {
description: string
headers: Header[]
frontmatter: Record
- lastUpdated: number
+ lastUpdated?: number
}
export interface SiteData {