Skip to content

Commit

Permalink
Chore: use vitepress instead of vuepress (#2044)
Browse files Browse the repository at this point in the history
* Chore: use vitepress instead of vuepress

* fix

* fix dev deps

* Update docs/.vitepress/build-system/build.ts

Co-authored-by: Flo Edelmann <florian-edelmann@online.de>

* Update docs/.vitepress/build-system/build.ts

Co-authored-by: Flo Edelmann <florian-edelmann@online.de>

* Update docs/.vitepress/config.ts

Co-authored-by: Flo Edelmann <florian-edelmann@online.de>

* Update docs/.vitepress/build-system/build.ts

Co-authored-by: Flo Edelmann <florian-edelmann@online.de>

Co-authored-by: Flo Edelmann <florian-edelmann@online.de>
  • Loading branch information
ota-meshi and FloEdelmann committed Nov 23, 2022
1 parent 1d669d3 commit 55daf43
Show file tree
Hide file tree
Showing 30 changed files with 527 additions and 324 deletions.
7 changes: 5 additions & 2 deletions .eslintignore
Expand Up @@ -4,5 +4,8 @@
/tests/fixtures
/tests/integrations/eslint-plugin-import

!.vuepress
/docs/.vuepress/dist
!.vitepress
/docs/.vitepress/dist
/docs/.vitepress/build-system/shim/eslint.mjs
/docs/.vitepress/build-system/shim/assert.mjs
/docs/.vitepress/.temp
5 changes: 4 additions & 1 deletion .gitignore
Expand Up @@ -7,5 +7,8 @@
/test.*
yarn.lock
yarn-error.log
docs/.vuepress/dist
/docs/.vitepress/dist
/docs/.vitepress/build-system/shim/eslint.mjs
/docs/.vitepress/build-system/shim/assert.mjs
/docs/.vitepress/.temp
typings/eslint/lib/rules
66 changes: 66 additions & 0 deletions docs/.vitepress/build-system/build.ts
@@ -0,0 +1,66 @@
/**
* Pre-build cjs packages that cannot be bundled well.
*/
import esbuild from 'esbuild'
import path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'

const dirname = path.dirname(
fileURLToPath(
// @ts-expect-error -- Cannot change `module` option
import.meta.url
)
)

build(
path.join(dirname, './src/eslint.mjs'),
path.join(dirname, './shim/eslint.mjs'),
['path', 'assert', 'util']
)
build(
path.join(dirname, '../../../node_modules/assert'),
path.join(dirname, './shim/assert.mjs'),
['path']
)

function build(input: string, out: string, injects: string[] = []) {
// eslint-disable-next-line no-console -- ignore
console.log(`build@ ${input}`)
let code = bundle(input, injects)
code = transform(code, injects)
fs.mkdirSync(path.dirname(out), { recursive: true })
fs.writeFileSync(out, code, 'utf8')
}

function bundle(entryPoint: string, externals: string[]) {
const result = esbuild.buildSync({
entryPoints: [entryPoint],
format: 'esm',
bundle: true,
external: externals,
write: false,
inject: [path.join(dirname, './src/process-shim.mjs')]
})

return `${result.outputFiles[0].text}`
}

function transform(code: string, injects: string[]) {
const newCode = code.replace(/"[a-z]+" = "[a-z]+";/u, '')
return `
${injects
.map(
(inject) =>
`import $inject_${inject.replace(/-/gu, '_')}$ from '${inject}';`
)
.join('\n')}
const $_injects_$ = {${injects
.map((inject) => `${inject.replace(/-/gu, '_')}:$inject_${inject}$`)
.join(',\n')}};
function require(module, ...args) {
return $_injects_$[module] || {}
}
${newCode}
`
}
2 changes: 2 additions & 0 deletions docs/.vitepress/build-system/shim/globby.mjs
@@ -0,0 +1,2 @@
export {}
export default {}
38 changes: 38 additions & 0 deletions docs/.vitepress/build-system/shim/path.mjs
@@ -0,0 +1,38 @@
// @ts-nocheck
export const sep = '/'
export function basename(path, ext) {
const b = (/[^\/]*$/u.exec(path) || [''])[0]
return ext && b.endsWith(ext) ? b.slice(0, -ext.length) : b
}
export function extname(path) {
return (/[^.\/]*$/u.exec(path) || [''])[0]
}
export function isAbsolute() {
return false
}
export function join(...args) {
return args.length > 0 ? normalize(args.join('/')) : '.'
}

function normalize(path) {
const result = []
for (const part of path.replace(/\/+/gu, '/').split('/')) {
if (part === '..') {
if (result[0] && result[0] !== '..' && result[0] !== '.') result.shift()
} else if (part === '.' && result.length > 0) {
// noop
} else {
result.unshift(part)
}
}
return result.reverse().join('/')
}
const posix = {
sep,
basename,
extname,
isAbsolute,
join
}
posix.posix = posix
export default posix
5 changes: 5 additions & 0 deletions docs/.vitepress/build-system/src/eslint.mjs
@@ -0,0 +1,5 @@
// @ts-nocheck
import * as all from '../../../../node_modules/eslint/lib/linter/linter.js'
const Linter = all.Linter
export { Linter }
export default { Linter }
10 changes: 10 additions & 0 deletions docs/.vitepress/build-system/src/process-shim.mjs
@@ -0,0 +1,10 @@
/* globals window */
// @ts-nocheck
export const process = {
env: {},
cwd: () => '',
stdout: {}
}
if (typeof window !== 'undefined') {
window.process = process
}
222 changes: 222 additions & 0 deletions docs/.vitepress/config.ts
@@ -0,0 +1,222 @@
import type { DefaultTheme } from 'vitepress'
import { defineConfig } from 'vitepress'
import { BUNDLED_LANGUAGES } from 'shiki'
import path from 'path'
import { fileURLToPath } from 'url'
import rules from '../../tools/lib/rules'
import { viteCommonjs, vitePluginRequireResolve } from './vite-plugin'

// Pre-build cjs packages that cannot be bundled well.
import './build-system/build'

const dirname = path.dirname(
fileURLToPath(
// @ts-expect-error -- Cannot change `module` option
import.meta.url
)
)

// Include `json5` as alias for jsonc
const jsonc = BUNDLED_LANGUAGES.find((lang) => lang.id === 'jsonc')
if (jsonc) {
jsonc.aliases = [...(jsonc.aliases ?? []), 'json5']
}

const uncategorizedRules = rules.filter(
(rule) =>
!rule.meta.docs.categories &&
!rule.meta.docs.extensionRule &&
!rule.meta.deprecated
)
const uncategorizedExtensionRule = rules.filter(
(rule) =>
!rule.meta.docs.categories &&
rule.meta.docs.extensionRule &&
!rule.meta.deprecated
)
const deprecatedRules = rules.filter((rule) => rule.meta.deprecated)

const sidebarCategories = [
{ title: 'Base Rules', categoryIds: ['base'] },
{
title: 'Priority A: Essential',
categoryIds: ['vue3-essential', 'essential']
},
{
title: 'Priority A: Essential for Vue.js 3.x',
categoryIds: ['vue3-essential']
},
{ title: 'Priority A: Essential for Vue.js 2.x', categoryIds: ['essential'] },
{
title: 'Priority B: Strongly Recommended',
categoryIds: ['vue3-strongly-recommended', 'strongly-recommended']
},
{
title: 'Priority B: Strongly Recommended for Vue.js 3.x',
categoryIds: ['vue3-strongly-recommended']
},
{
title: 'Priority B: Strongly Recommended for Vue.js 2.x',
categoryIds: ['strongly-recommended']
},
{
title: 'Priority C: Recommended',
categoryIds: ['vue3-recommended', 'recommended']
},
{
title: 'Priority C: Recommended for Vue.js 3.x',
categoryIds: ['vue3-recommended']
},
{
title: 'Priority C: Recommended for Vue.js 2.x',
categoryIds: ['recommended']
}
]

const categorizedRules: DefaultTheme.SidebarGroup[] = []
for (const { title, categoryIds } of sidebarCategories) {
const categoryRules = rules
.filter((rule) => rule.meta.docs.categories && !rule.meta.deprecated)
.filter((rule) =>
categoryIds.every((categoryId) =>
rule.meta.docs.categories.includes(categoryId)
)
)
const children: DefaultTheme.SidebarItem[] = categoryRules
.filter(({ ruleId }) => {
const exists = categorizedRules.some(({ items }) =>
items.some(({ text: alreadyRuleId }) => alreadyRuleId === ruleId)
)
return !exists
})
.map(({ ruleId, name }) => {
return {
text: ruleId,
link: `/rules/${name}`
}
})

if (children.length === 0) {
continue
}
categorizedRules.push({
text: title,
collapsible: false,
items: children
})
}

const extraCategories: DefaultTheme.SidebarGroup[] = []
if (uncategorizedRules.length > 0) {
extraCategories.push({
text: 'Uncategorized',
collapsible: false,
items: uncategorizedRules.map(({ ruleId, name }) => ({
text: ruleId,
link: `/rules/${name}`
}))
})
}
if (uncategorizedExtensionRule.length > 0) {
extraCategories.push({
text: 'Extension Rules',
collapsible: false,
items: uncategorizedExtensionRule.map(({ ruleId, name }) => ({
text: ruleId,
link: `/rules/${name}`
}))
})
}
if (deprecatedRules.length > 0) {
extraCategories.push({
text: 'Deprecated',
collapsible: false,
items: deprecatedRules.map(({ ruleId, name }) => ({
text: ruleId,
link: `/rules/${name}`
}))
})
}

export default defineConfig({
base: '/',
title: 'eslint-plugin-vue',
description: 'Official ESLint plugin for Vue.js',
head: [['link', { rel: 'icon', href: '/favicon.png' }]],

vite: {
publicDir: path.resolve(dirname, './public'),
plugins: [vitePluginRequireResolve(), viteCommonjs()],
resolve: {
alias: {
eslint: path.join(dirname, './build-system/shim/eslint.mjs'),
assert: path.join(dirname, './build-system/shim/assert.mjs'),
path: path.join(dirname, './build-system/shim/path.mjs'),

tslib: path.join(dirname, '../../node_modules/tslib/tslib.es6.js'),
globby: path.join(dirname, './build-system/shim/globby.mjs')
}
},
define: {
'process.env.NODE_DEBUG': 'false',
'require.cache': '{}'
}
},

lastUpdated: true,
themeConfig: {
editLink: {
pattern:
'https://github.com/vuejs/eslint-plugin-vue/edit/master/docs/:path'
},
socialLinks: [
{
icon: 'github',
link: 'https://github.com/vuejs/eslint-plugin-vue'
}
],

nav: [
{ text: 'User Guide', link: '/user-guide/' },
{ text: 'Developer Guide', link: '/developer-guide/' },
{ text: 'Rules', link: '/rules/' },
{
text: 'Demo',
link: 'https://ota-meshi.github.io/eslint-plugin-vue-demo/'
}
],

sidebar: {
'/rules/': [
{
text: 'Rules',
items: [{ text: 'Available Rules', link: '/rules/' }]
},

// Rules in each category.
...categorizedRules,

// Rules in no category.
...extraCategories
],

'/': [
{
text: 'Guide',
items: [
{ text: 'Introduction', link: '/' },
{ text: 'User Guide', link: '/user-guide/' },
{ text: 'Developer Guide', link: '/developer-guide/' },
{ text: 'Rules', link: '/rules/' }
]
}
]
},

algolia: {
appId: '2L4MGZSULB',
apiKey: 'fdf57932b27a6c230d01a890492ab76d',
indexName: 'eslint-plugin-vue'
}
}
})
File renamed without changes
21 changes: 21 additions & 0 deletions docs/.vitepress/theme/Layout.vue
@@ -0,0 +1,21 @@
<script setup>
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { computed } from 'vue'
const BaseLayout = DefaultTheme.Layout
const { frontmatter } = useData()
const pageClass = computed(() => frontmatter.value.pageClass || '')
</script>

<template>
<div :class="pageClass">
<BaseLayout />
</div>
</template>

<style scoped>
/* Rule Page */
.rule-details :deep(.main h1 + blockquote ::first-letter) {
text-transform: uppercase;
}
</style>

0 comments on commit 55daf43

Please sign in to comment.