diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d65527..c0ba3f45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,68 @@ +## [0.10.6](https://github.com/vuejs/vitepress/compare/v0.10.5...v0.10.6) (2021-01-04) + +### Bug Fixes + +- bump vite and fix win32 path resolving ([#198](https://github.com/vuejs/vitepress/issues/198)) ([da2c4f6](https://github.com/vuejs/vitepress/commit/da2c4f694e6dd2d11ff061b8eb7cae2354ae930d)) + +## [0.10.5](https://github.com/vuejs/vitepress/compare/v0.10.4...v0.10.5) (2021-01-02) + +### Bug Fixes + +- vite 2.0.0-beta.2 compat ([991a443](https://github.com/vuejs/vitepress/commit/991a443c70c6173aa0100fcccf57f3565e9e38d9)) + +## [0.10.4](https://github.com/vuejs/vitepress/compare/v0.10.3...v0.10.4) (2021-01-01) + +### Bug Fixes + +- ensure the same vue dep in all cases ([d6b8568](https://github.com/vuejs/vitepress/commit/d6b8568c52d51d66423a32293879f8bb57756954)) +- respect root during build ([055e3fd](https://github.com/vuejs/vitepress/commit/055e3fd043b6ec425f1b0a0cf529bc1ff66acda5)) + +## [0.10.3](https://github.com/vuejs/vitepress/compare/v0.10.2...v0.10.3) (2021-01-01) + +### Bug Fixes + +- always define theme globals ([8769b4b](https://github.com/vuejs/vitepress/commit/8769b4b49f398c5244354fbb93fcbecdb9b9c638)) +- avoid unexpected vite define replacements in markdown content ([a41928e](https://github.com/vuejs/vitepress/commit/a41928ef83eaf9dcb68be26b1e1f8a3edadfb74a)) +- loosen navLink active matching ([8a2ff33](https://github.com/vuejs/vitepress/commit/8a2ff33bf8043b5b0ec21826d7962d7e6337e394)) + +### Features + +- **theme-default:** nav.item.activeMatch ([e262ef6](https://github.com/vuejs/vitepress/commit/e262ef63d89b2bc90c7e42bfc302ba6c602fab16)) +- add altAction for home ([9a17ddf](https://github.com/vuejs/vitepress/commit/9a17ddfdfb3cf7afd70d28d697245a298de090e1)) + +## [0.10.2](https://github.com/vuejs/vitepress/compare/v0.10.1...v0.10.2) (2020-12-31) + +### Bug Fixes + +- adjust multi sidebar matching logic ([7e4b16e](https://github.com/vuejs/vitepress/commit/7e4b16ee524efc87c150a3d57a3215aac76b3669)) + +## [0.10.1](https://github.com/vuejs/vitepress/compare/v0.10.0...v0.10.1) (2020-12-30) + +### Bug Fixes + +- disable css code split ([04dc058](https://github.com/vuejs/vitepress/commit/04dc058cd9977b47eb29c6d2d043e33d92802af8)) +- minify ([e3d7fc0](https://github.com/vuejs/vitepress/commit/e3d7fc035376d6d73e350be661925058c84828a8)) + +### Features + +- production ready serve ([2d77eaf](https://github.com/vuejs/vitepress/commit/2d77eafe3b05e9fe76031af9a6c5386c4c6586ac)) + +### Performance Improvements + +- avoid including optional features in build when not used ([c878e6d](https://github.com/vuejs/vitepress/commit/c878e6d3b56ecbd71bd75ff4360446d6dacbd70b)) + +# [0.10.0](https://github.com/vuejs/vitepress/compare/v0.9.2...v0.10.0) (2020-12-30) + +- Upgrade to Vite 2.0 + +### Bug Fixes + +- port fixes to parseHeader utils from vuepress ([#172](https://github.com/vuejs/vitepress/issues/172)) ([dd312ce](https://github.com/vuejs/vitepress/commit/dd312ce86bf9daf4b169e025d4215c05e2ad63c5)) +- revert datetime handling ([a1daf2b](https://github.com/vuejs/vitepress/commit/a1daf2b8a012a8a248b3a832d80d6933778087d0)) +- style pollution on custom theme ([#190](https://github.com/vuejs/vitepress/issues/190)) ([46e99ba](https://github.com/vuejs/vitepress/commit/46e99babc2d1a0e456d47081c2e7beb961bcd1d5)) +- temporarily disable slot usage causing hydration mismatch ([0239159](https://github.com/vuejs/vitepress/commit/02391593bcdd21b621a60aaa0ea2c8cf2ef450d8)) +- **md:** avoid normalising markdown "mailto:" links ([#173](https://github.com/vuejs/vitepress/issues/173)) ([18d18d2](https://github.com/vuejs/vitepress/commit/18d18d2eb15a569113ca68ccbb9ba52dfd46c80a)) + ## [0.9.2](https://github.com/vuejs/vitepress/compare/v0.9.1...v0.9.2) (2020-12-10) Fix build files diff --git a/__tests__/client/theme-default/support/sideBar.spec.ts b/__tests__/client/theme-default/support/sideBar.spec.ts index a1d0ea82..033daced 100644 --- a/__tests__/client/theme-default/support/sideBar.spec.ts +++ b/__tests__/client/theme-default/support/sideBar.spec.ts @@ -16,8 +16,8 @@ describe('client/theme-default/support/sideBar', () => { it('gets the correct sidebar items from the given path', () => { const sidebar = { - '/': [{ text: 'R', link: 'r' }], - '/guide/': [{ text: 'G', link: 'g' }] + '/guide/': [{ text: 'G', link: 'g' }], + '/': [{ text: 'R', link: 'r' }] } expect(getSideBarConfig(sidebar, '/')).toEqual(sidebar['/']) @@ -31,7 +31,8 @@ describe('client/theme-default/support/sideBar', () => { } expect(getSideBarConfig(s, '/guide/')).toEqual(s['/guide/']) - expect(getSideBarConfig(s, '/guide')).toEqual(s['/guide/']) + // no ending slash should not match + expect(getSideBarConfig(s, '/guide')).not.toEqual(s['/guide/']) expect(getSideBarConfig(s, 'guide/')).toEqual(s['/guide/']) expect(getSideBarConfig(s, 'guide/nested')).toEqual(s['/guide/']) expect(getSideBarConfig(s, '/guide/nested')).toEqual(s['/guide/']) diff --git a/__tests__/node/utils/deeplyParseHeader.spec.ts b/__tests__/node/utils/deeplyParseHeader.spec.ts new file mode 100644 index 00000000..ded20eac --- /dev/null +++ b/__tests__/node/utils/deeplyParseHeader.spec.ts @@ -0,0 +1,33 @@ +import { deeplyParseHeader } from 'node/utils/parseHeader' + +test('deeplyParseHeader', () => { + const asserts: Record = { + // Remove tail html + '# `H1` ': '# H1', + '# *H1* ': '# H1', + + // Reserve code-wrapped tail html + '# `H1` ``': '# H1 ', + '# *H1* ``': '# H1 ', + + // Remove leading html + '# `H1`': '# H1', + '# *H1*': '# H1', + + // Reserve code-wrapped leading html + '# `` `H1`': '# H1', + '# `` *H1*': '# H1', + + // Remove middle html + '# `H1` `H2`': '# H1 H2', + '# `H1` `H2`': '# H1 H2', + + // Reserve middle html + '# `H1` `` `H2`': '# H1 H2', + '# `H1` `` `H2`': '# H1 H2' + } + + Object.keys(asserts).forEach((input) => { + expect(deeplyParseHeader(input)).toBe(asserts[input]) + }) +}) diff --git a/__tests__/node/utils/parseHeader.spec.ts b/__tests__/node/utils/parseHeader.spec.ts new file mode 100644 index 00000000..a150cff0 --- /dev/null +++ b/__tests__/node/utils/parseHeader.spec.ts @@ -0,0 +1,38 @@ +import { parseHeader } from 'node/utils/parseHeader' + +describe('parseHeader', () => { + test('should unescape html', () => { + const input = `<div :id="'app'">` + expect(parseHeader(input)).toBe(`
`) + }) + + test('should remove markdown tokens correctly', () => { + const asserts: Record = { + // vuepress #238 + '[vue](vuejs.org)': 'vue', + '`vue`': 'vue', + '*vue*': 'vue', + '**vue**': 'vue', + '***vue***': 'vue', + _vue_: 'vue', + '\\_vue\\_': '_vue_', + '\\*vue\\*': '*vue*', + '\\!vue\\!': '!vue!', + + // vuepress #2688 + '[vue](vuejs.org) / [vue](vuejs.org)': 'vue / vue', + '[\\](vuejs.org)': '', + + // vuepress #564 For multiple markdown tokens + '`a` and `b`': 'a and b', + '***bold and italic***': 'bold and italic', + '**bold** and *italic*': 'bold and italic', + + // escaping \$ + '\\$vue': '$vue' + } + Object.keys(asserts).forEach((input) => { + expect(parseHeader(input)).toBe(asserts[input]) + }) + }) +}) diff --git a/__tests__/node/utils/removeNonCodeWrappedHTML.spec.ts b/__tests__/node/utils/removeNonCodeWrappedHTML.spec.ts new file mode 100644 index 00000000..d5481ad8 --- /dev/null +++ b/__tests__/node/utils/removeNonCodeWrappedHTML.spec.ts @@ -0,0 +1,56 @@ +import { removeNonCodeWrappedHTML } from 'node/utils/parseHeader' + +test('removeNonCodeWrappedHTML', () => { + const asserts: Record = { + // Remove tail html + '# H1 ': '# H1 ', + '# H1': '# H1', + '# H1 ': '# H1 ', + '# H1': '# H1', + '# H1 ': '# H1 ', + '# H1': '# H1', + '# H1 ': '# H1 ', + '# H1': '# H1', + + // Reserve code-wrapped tail html + '# H1 ``': '# H1 ``', + '# H1 ``': '# H1 ``', + '# H1 ``': '# H1 ``', + '# H1 ``': '# H1 ``', + + // Remove leading html + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + '# H1': '# H1', + + // Reserve code-wrapped leading html + '# `` H1': '# `` H1', + '# `` H1': '# `` H1', + '# `` H1': '# `` H1', + '# `` H1': '# `` H1', + + // Remove middle html + '# H1 H2': '# H1 H2', + '# H1 H2': '# H1 H2', + '# H1 H2': '# H1 H2', + '# H1 H2': '# H1 H2', + + // Reserve code-wrapped middle html + '# H1 `` H2': '# H1 `` H2', + '# H1 `` H2': '# H1 `` H2', + '# H1 `` H2': '# H1 `` H2', + '# H1 `` H2': '# H1 `` H2', + + // vuepress #2688 + '# \\': '# \\' + } + + Object.keys(asserts).forEach((input) => { + expect(removeNonCodeWrappedHTML(input)).toBe(asserts[input]) + }) +}) diff --git a/bin/vitepress.js b/bin/vitepress.js index a5b135eb..0aafe1a3 100755 --- a/bin/vitepress.js +++ b/bin/vitepress.js @@ -1,44 +1,2 @@ #!/usr/bin/env node -const chalk = require('chalk') -const argv = require('minimist')(process.argv.slice(2)) - -console.log(chalk.cyan(`vitepress v${require('../package.json').version}`)) -console.log(chalk.cyan(`vite v${require('vite/package.json').version}`)) - -const command = argv._[0] -const root = argv._[command ? 1 : 0] -if (root) { - argv.root = root -} - -if (!command || command === 'dev') { - const port = argv.port || 3000 - require('../dist/node') - .createServer(argv) - .then((server) => { - server.listen(port, () => { - console.log(`listening at http://localhost:${port}`) - }) - }) - .catch((err) => { - console.error(chalk.red(`failed to start server. error:\n`), err) - process.exit(1) - }) -} else if (command === 'build') { - require('../dist/node') - .build(argv) - .catch((err) => { - console.error(chalk.red(`build error:\n`), err) - process.exit(1) - }) -} else if (command === 'serve') { - require('../dist/node') - .serve(argv) - .catch((err) => { - console.error(chalk.red(`failed to start server. error:\n`), err) - process.exit(1) - }) -} else { - console.log(chalk.red(`unknown command "${command}".`)) - process.exit(1) -} +require('../dist/node/cli') diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 0344926b..14c5bd69 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -23,8 +23,12 @@ module.exports = { }, nav: [ - { text: 'Guide', link: '/' }, - { text: 'Config Reference', link: '/config/basics' }, + { text: 'Guide', link: '/', activeMatch: '^/$|^/guide/' }, + { + text: 'Config Reference', + link: '/config/basics', + activeMatch: '^/config/' + }, { text: 'Release Notes', link: 'https://github.com/vuejs/vitepress/releases' @@ -32,9 +36,9 @@ module.exports = { ], sidebar: { - '/': getGuideSidebar(), '/guide/': getGuideSidebar(), - '/config/': getConfigSidebar() + '/config/': getConfigSidebar(), + '/': getGuideSidebar() } } } diff --git a/docs/index.md b/docs/index.md index 8b5fe887..ccf67e64 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ Now, with Vite and Vue 3, it is time to rethink what a "Vue-powered static site ## Improvements Over VuePress -There're couple of things that are improved from VuePress. +There're couple of things that are improved from VuePress.... ### It Uses Vue 3 diff --git a/docs/public/_headers b/docs/public/_headers new file mode 100644 index 00000000..f7fa3afc --- /dev/null +++ b/docs/public/_headers @@ -0,0 +1,3 @@ +/assets/* + cache-control: max-age=31536000 + cache-control: immutable \ No newline at end of file diff --git a/package.json b/package.json index 55a24fa9..e918272e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vitepress", - "version": "0.9.2", + "version": "0.10.6", "description": "Vite & Vue powered static site generator", "main": "dist/node/index.js", "typings": "types/index.d.ts", @@ -29,11 +29,12 @@ "release": "node scripts/release.js", "docs": "run-p dev docs-dev", "docs-dev": "node ./bin/vitepress dev docs", + "docs-debug": "node --inspect-brk ./bin/vitepress dev docs", "docs-build": "yarn build && node ./bin/vitepress build docs", - "docs-serve": "yarn docs-build && node ./bin/vitepress serve --root docs" + "docs-serve": "yarn docs-build && node ./bin/vitepress serve docs" }, "engines": { - "node": ">=10.0.0" + "node": ">=12.0.0" }, "gitHooks": { "pre-commit": "lint-staged" @@ -64,9 +65,11 @@ "dependencies": { "@docsearch/css": "^1.0.0-alpha.28", "@docsearch/js": "^1.0.0-alpha.28", - "@vue/compiler-sfc": "^3.0.3", - "@vue/server-renderer": "^3.0.3", + "@vitejs/plugin-vue": "^1.0.3", + "@vue/compiler-sfc": "^3.0.5", + "@vue/server-renderer": "^3.0.5", "chalk": "^4.1.0", + "compression": "^1.7.4", "debug": "^4.1.1", "diacritics": "^1.3.0", "escape-html": "^1.0.3", @@ -81,12 +84,15 @@ "markdown-it-table-of-contents": "^0.4.4", "minimist": "^1.2.5", "ora": "^5.1.0", + "polka": "^0.5.2", "prismjs": "^1.20.0", + "sirv": "^1.0.10", "slash": "^3.0.0", - "vite": "^1.0.0-rc.13", - "vue": "^3.0.3" + "vite": "^2.0.0-beta.4", + "vue": "^3.0.5" }, "devDependencies": { + "@types/compression": "^1.7.0", "@types/fs-extra": "^9.0.1", "@types/jest": "^26.0.15", "@types/koa": "^2.11.6", @@ -100,8 +106,6 @@ "enquirer": "^2.3.6", "execa": "^4.1.0", "jest": "^26.6.3", - "koa": "^2.13.0", - "koa-static": "^5.0.0", "lint-staged": "^10.3.0", "npm-run-all": "^4.1.5", "prettier": "^2.0.5", @@ -109,7 +113,7 @@ "rollup": "^2.33.3", "semver": "^7.3.2", "ts-jest": "^26.4.4", - "typescript": "^3.8.3", + "typescript": "^4.1.3", "yorkie": "^2.0.0" } } diff --git a/src/client/app/components/Debug.vue b/src/client/app/components/Debug.vue index 71034d9c..c20ea7dd 100644 --- a/src/client/app/components/Debug.vue +++ b/src/client/app/components/Debug.vue @@ -8,24 +8,15 @@
- diff --git a/src/client/app/composables/siteData.ts b/src/client/app/composables/siteData.ts index 26643166..7829e317 100644 --- a/src/client/app/composables/siteData.ts +++ b/src/client/app/composables/siteData.ts @@ -16,7 +16,7 @@ function parse(data: string): SiteData { // hmr if (import.meta.hot) { - import.meta.hot!.acceptDeps('/@siteData', (m) => { + import.meta.hot!.accept('/@siteData', (m) => { siteDataRef.value = parse(m.default) }) } diff --git a/src/client/app/exports.ts b/src/client/app/exports.ts deleted file mode 100644 index 29242136..00000000 --- a/src/client/app/exports.ts +++ /dev/null @@ -1,29 +0,0 @@ -// exports in this file are exposed to themes and md files via 'vitepress' -// so the user can do `import { useRoute, useSiteData } from 'vitepress'` - -// generic types -export type { Router, Route } from './router' - -// theme types -export * from './theme' - -// composables -export { useRouter, useRoute } from './router' -export { useSiteData } from './composables/siteData' -export { useSiteDataByRoute } from './composables/siteDataByRoute' -export { usePageData } from './composables/pageData' -export { useFrontmatter } from './composables/frontmatter' - -// utilities -export { inBrowser, joinPath } from './utils' - -// components -export { Content } from './components/Content' - -import { ComponentOptions } from 'vue' -import _Debug from './components/Debug.vue' -const Debug = _Debug as ComponentOptions -export { Debug } - -// default theme -export { default as defaultTheme } from '/@default-theme/index' diff --git a/src/client/app/index.html b/src/client/app/index.html deleted file mode 100644 index 69e2efbb..00000000 --- a/src/client/app/index.html +++ /dev/null @@ -1,2 +0,0 @@ -
- diff --git a/src/client/app/mixin.ts b/src/client/app/mixin.ts index 95dc8863..9fb29376 100644 --- a/src/client/app/mixin.ts +++ b/src/client/app/mixin.ts @@ -1,9 +1,8 @@ -import { App } from 'vue' +import { App, defineAsyncComponent } from 'vue' import { joinPath } from './utils' import { SiteDataRef } from './composables/siteData' import { PageDataRef } from './composables/pageData' import { Content } from './components/Content' -import Debug from './components/Debug.vue' import { ClientOnly } from './components/ClientOnly' export function mixinGlobalComputed( @@ -70,5 +69,10 @@ export function mixinGlobalComponents(app: App) { app.component('Content', Content) app.component('ClientOnly', ClientOnly) - app.component('Debug', isProd ? () => null : Debug) + app.component( + 'Debug', + isProd + ? () => null + : defineAsyncComponent(() => import('./components/Debug.vue')) + ) } diff --git a/src/client/app/utils.ts b/src/client/app/utils.ts index 0509668a..0eee7e11 100644 --- a/src/client/app/utils.ts +++ b/src/client/app/utils.ts @@ -29,7 +29,7 @@ export function pathToFile(path: string): string { // client production build needs to account for page hash, which is // injected directly in the page's html const pageHash = __VP_HASH_MAP__[pagePath] - pagePath = `${base}_assets/${pagePath}.${pageHash}.js` + pagePath = `${base}assets/${pagePath}.${pageHash}.js` } else { // ssr build uses much simpler name mapping pagePath = `./${pagePath.slice(1).replace(/\//g, '_')}.md.js` diff --git a/src/client/index.ts b/src/client/index.ts new file mode 100644 index 00000000..8dc04483 --- /dev/null +++ b/src/client/index.ts @@ -0,0 +1,29 @@ +// exports in this file are exposed to themes and md files via 'vitepress' +// so the user can do `import { useRoute, useSiteData } from 'vitepress'` + +// generic types +export type { Router, Route } from './app/router' + +// theme types +export * from './app/theme' + +// composables +export { useRouter, useRoute } from './app/router' +export { useSiteData } from './app/composables/siteData' +export { useSiteDataByRoute } from './app/composables/siteDataByRoute' +export { usePageData } from './app/composables/pageData' +export { useFrontmatter } from './app/composables/frontmatter' + +// utilities +export { inBrowser, joinPath } from './app/utils' + +// components +export { Content } from './app/components/Content' + +import { ComponentOptions } from 'vue' +import _Debug from './app/components/Debug.vue' +const Debug = _Debug as ComponentOptions +export { Debug } + +// default theme +export { default as DefaultTheme } from './theme-default' diff --git a/src/client/shim.d.ts b/src/client/shim.d.ts index 4c240a37..c6c262e5 100644 --- a/src/client/shim.d.ts +++ b/src/client/shim.d.ts @@ -1,5 +1,7 @@ declare const __VP_HASH_MAP__: Record - +declare const __CARBON__: boolean +declare const __BSA__: boolean +declare const __ALGOLIA__: boolean declare module '*.vue' { import { ComponentOptions } from 'vue' const comp: ComponentOptions @@ -18,5 +20,6 @@ declare module '@docsearch/js' { } declare module '@docsearch/css' { - export default string + const css: string + export default css } diff --git a/src/client/theme-default/Layout.vue b/src/client/theme-default/Layout.vue index c7b820ee..7cd3b565 100644 --- a/src/client/theme-default/Layout.vue +++ b/src/client/theme-default/Layout.vue @@ -76,16 +76,20 @@ import type { DefaultTheme } from './config' 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 CarbonAds = defineAsyncComponent( + +const NoopComponent = () => null + +const CarbonAds = __CARBON__ ? defineAsyncComponent( () => import('./components/CarbonAds.vue') -) -const BuySellAds = defineAsyncComponent( +) : NoopComponent +const BuySellAds = __BSA__ ? defineAsyncComponent( () => import('./components/BuySellAds.vue') -) -const AlgoliaSearchBox = defineAsyncComponent( +) : NoopComponent +const AlgoliaSearchBox = __ALGOLIA__ ? defineAsyncComponent( () => import('./components/AlgoliaSearchBox.vue') -) +) : NoopComponent // generic state const route = useRoute() diff --git a/src/client/theme-default/components/AlgoliaSearchBox.vue b/src/client/theme-default/components/AlgoliaSearchBox.vue index 112660ba..14e66873 100644 --- a/src/client/theme-default/components/AlgoliaSearchBox.vue +++ b/src/client/theme-default/components/AlgoliaSearchBox.vue @@ -2,13 +2,8 @@