feat: migrate to ESM (#645) (#659)

close #645 

Co-authored-by: Kia King Ishii <kia.king.08@gmail.com>
pull/672/head
Anthony Fu 2 years ago committed by GitHub
parent bae47f7082
commit a0f81c9f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,14 +1,8 @@
{ {
"extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"module": "esnext", "types": ["node", "vitest/globals"],
"moduleResolution": "node",
"strict": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"types": ["node", "vitest/global"],
"paths": { "paths": {
"node/*": ["../src/node/*"], "node/*": ["../src/node/*"],
"client/*": ["../src/client/*"] "client/*": ["../src/client/*"]

@ -1,10 +0,0 @@
import path from 'path'
export default {
resolve: {
alias: {
node: path.resolve(__dirname, '../src/node'),
client: path.resolve(__dirname, '../src/client')
}
}
}

@ -0,0 +1,17 @@
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
import { defineConfig } from 'vite'
const dir = dirname(fileURLToPath(import.meta.url))
export default defineConfig({
resolve: {
alias: {
node: resolve(dir, '../src/node'),
client: resolve(dir, '../src/client')
}
},
test: {
globals: true
}
})

@ -1,53 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"projectFolder": "./src/client",
"mainEntryPointFilePath": "./dist/temp/index.d.ts",
"dtsRollup": {
"enabled": true,
"publicTrimmedFilePath": "./dist/client/index.d.ts"
},
"apiReport": {
"enabled": false
},
"docModel": {
"enabled": false
},
"tsdocMetadata": {
"enabled": false
},
"messages": {
"compilerMessageReporting": {
"default": {
"logLevel": "warning"
}
},
"extractorMessageReporting": {
"default": {
"logLevel": "warning",
"addToApiReportFile": true
},
"ae-missing-release-tag": {
"logLevel": "none"
}
},
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
},
"tsdoc-undefined-tag": {
"logLevel": "none"
}
}
}
}

@ -1,53 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"projectFolder": "./src/node",
"mainEntryPointFilePath": "./dist/temp/index.d.ts",
"dtsRollup": {
"enabled": true,
"publicTrimmedFilePath": "./dist/node/index.d.ts"
},
"apiReport": {
"enabled": false
},
"docModel": {
"enabled": false
},
"tsdocMetadata": {
"enabled": false
},
"messages": {
"compilerMessageReporting": {
"default": {
"logLevel": "warning"
}
},
"extractorMessageReporting": {
"default": {
"logLevel": "warning",
"addToApiReportFile": true
},
"ae-missing-release-tag": {
"logLevel": "none"
}
},
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
},
"tsdoc-undefined-tag": {
"logLevel": "none"
}
}
}
}

@ -1,2 +1,2 @@
#!/usr/bin/env node #!/usr/bin/env node
require('../dist/node/cli') import('../dist/node/cli.js')

@ -1,10 +1,19 @@
{ {
"name": "vitepress", "name": "vitepress",
"version": "1.0.0-draft.4", "version": "1.0.0-draft.4",
"type": "module",
"packageManager": "pnpm@7.0.1", "packageManager": "pnpm@7.0.1",
"description": "Vite & Vue powered static site generator", "description": "Vite & Vue powered static site generator",
"main": "dist/node/index.js", "main": "dist/node/index.js",
"typings": "types/index.d.ts", "types": "types/index.d.ts",
"exports": {
".": {
"types": "./types/index.d.ts",
"import": "./dist/node/index.js",
"require": "./dist/node-cjs/index.cjs"
},
"./dist/client/*": "./dist/client/*"
},
"bin": { "bin": {
"vitepress": "bin/vitepress.js" "vitepress": "bin/vitepress.js"
}, },
@ -31,27 +40,22 @@
"url": "https://github.com/vuejs/vitepress/issues" "url": "https://github.com/vuejs/vitepress/issues"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.6.0"
}, },
"scripts": { "scripts": {
"dev": "run-s dev-shared dev-start", "dev": "rimraf dist && run-s dev-shared dev-start",
"dev-start": "run-p dev-client dev-node dev-watch", "dev-start": "run-p dev-client dev-node dev-watch",
"dev-client": "tsc -w -p src/client", "dev-client": "tsc -w -p src/client",
"dev-node": "tsc -w -p src/node", "dev-node": "DEV=true pnpm run build-node -w",
"dev-shared": "node scripts/copyShared", "dev-shared": "node scripts/copyShared",
"dev-watch": "node scripts/watchAndCopy", "dev-watch": "node scripts/watchAndCopy",
"build": "run-s build-prepare build-client build-node build-types", "build": "run-s build-prepare build-client build-node",
"build-prepare": "rimraf -rf dist && node scripts/copyShared", "build-prepare": "rimraf dist && node scripts/copyShared",
"build-client": "tsc -p src/client && node scripts/copyClient", "build-client": "tsc -p src/client && node scripts/copyClient",
"build-node": "rollup -c scripts/rollup.config.js", "build-node": "rollup --config rollup.config.ts --configPlugin esbuild",
"build-types": "run-s build-types-client build-types-node", "format": "prettier --write .",
"build-types-client": "tsc -p src/client --declaration --emitDeclarationOnly --outDir dist/temp && api-extractor run -c api-extractor.client.json && rimraf dist/temp", "lint": "pnpm run format",
"build-types-node": "tsc -p src/node --declaration --emitDeclarationOnly --outDir dist/temp && api-extractor run -c api-extractor.node.json && rimraf dist/temp", "test": "vitest -r __tests__",
"lint": "run-s lint:js lint:ts",
"lint:js": "prettier --check --write \"{bin,docs,scripts,src}/**/*.js\"",
"lint:ts": "prettier --check --write --parser typescript \"{__tests__,src,docs,types}/**/*.ts\"",
"test": "vitest run __tests__ -c __tests__/vitest.config.js --global",
"test:all": "run-s lint test",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"release": "node scripts/release.js", "release": "node scripts/release.js",
"docs": "run-p dev docs-dev", "docs": "run-p dev docs-dev",
@ -60,18 +64,7 @@
"docs-build": "run-s build docs-build-only", "docs-build": "run-s build docs-build-only",
"docs-build-only": "node ./bin/vitepress build docs", "docs-build-only": "node ./bin/vitepress build docs",
"docs-serve": "node ./bin/vitepress serve docs", "docs-serve": "node ./bin/vitepress serve docs",
"ci-docs": "run-s build docs-build" "ci-docs": "run-s docs-build"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.js": [
"prettier --write"
],
"*.ts": [
"prettier --parser=typescript --write"
]
}, },
"dependencies": { "dependencies": {
"@docsearch/css": "^3.0.0", "@docsearch/css": "^3.0.0",
@ -84,11 +77,11 @@
"vue": "3.2.33" "vue": "3.2.33"
}, },
"devDependencies": { "devDependencies": {
"@microsoft/api-extractor": "^7.23.1",
"@rollup/plugin-alias": "^3.1.5", "@rollup/plugin-alias": "^3.1.5",
"@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-replace": "^4.0.0",
"@types/body-scroll-lock": "^3.1.0", "@types/body-scroll-lock": "^3.1.0",
"@types/compression": "^1.7.0", "@types/compression": "^1.7.0",
"@types/cross-spawn": "^6.0.2", "@types/cross-spawn": "^6.0.2",
@ -102,7 +95,7 @@
"@types/minimist": "^1.2.2", "@types/minimist": "^1.2.2",
"@types/node": "^15.6.1", "@types/node": "^15.6.1",
"@types/polka": "^0.5.3", "@types/polka": "^0.5.3",
"chalk": "^4.1.1", "@types/prompts": "^2.0.14",
"chokidar": "^3.5.1", "chokidar": "^3.5.1",
"compression": "^1.7.4", "compression": "^1.7.4",
"conventional-changelog-cli": "^2.1.1", "conventional-changelog-cli": "^2.1.1",
@ -112,10 +105,9 @@
"enquirer": "^2.3.6", "enquirer": "^2.3.6",
"esbuild": "^0.14.0", "esbuild": "^0.14.0",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"execa": "^5.0.0", "execa": "^6.1.0",
"fast-glob": "^3.2.7", "fast-glob": "^3.2.7",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"globby": "^11.0.3",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"lint-staged": "^11.0.0", "lint-staged": "^11.0.0",
"lru-cache": "^6.0.0", "lru-cache": "^6.0.0",
@ -129,16 +121,20 @@
"minimist": "^1.2.5", "minimist": "^1.2.5",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"ora": "^5.4.0", "ora": "^5.4.0",
"picocolors": "^1.0.0",
"polka": "^0.5.2", "polka": "^0.5.2",
"prettier": "^2.3.0", "prettier": "^2.3.0",
"prompts": "^2.4.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rollup": "^2.56.3", "rollup": "^2.56.3",
"rollup-plugin-dts": "^4.2.2",
"rollup-plugin-esbuild": "^4.8.2", "rollup-plugin-esbuild": "^4.8.2",
"semver": "^7.3.5", "semver": "^7.3.5",
"simple-git-hooks": "^2.7.0",
"sirv": "^1.0.12", "sirv": "^1.0.12",
"typescript": "^4.6.4", "supports-color": "^9.2.2",
"vitest": "^0.10.4", "typescript": "^4.7.2",
"yorkie": "^2.0.0" "vitest": "^0.10.4"
}, },
"pnpm": { "pnpm": {
"peerDependencyRules": { "peerDependencyRules": {
@ -149,5 +145,13 @@
"@types/react" "@types/react"
] ]
} }
},
"simple-git-hooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*": [
"prettier --write --ignore-unknown"
]
} }
} }

File diff suppressed because it is too large Load Diff

@ -0,0 +1,109 @@
import { RollupOptions, defineConfig } from 'rollup'
import { promises as fs } from 'fs'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import esbuild from 'rollup-plugin-esbuild'
import json from '@rollup/plugin-json'
import replace from '@rollup/plugin-replace'
import dts from 'rollup-plugin-dts'
import alias from '@rollup/plugin-alias'
import { resolve } from 'path'
import { fileURLToPath } from 'url'
import pkg from './package.json'
const DEV = !!process.env.DEV
const PROD = !DEV
const ROOT = fileURLToPath(import.meta.url)
const r = (p: string) => resolve(ROOT, '..', p)
const external = [...Object.keys(pkg.dependencies), 'buffer', 'punycode']
const plugins = [
alias({
entries: {
'readable-stream': 'stream'
}
}),
replace({
// polyfill broken browser check from bundled deps
'navigator.userAgentData': 'undefined',
'navigator.userAgent': 'undefined',
preventAssignment: true
}),
commonjs(),
nodeResolve(),
esbuild({ target: 'node14' }),
json()
]
const esmBuild: RollupOptions = {
input: [r('src/node/index.ts'), r('src/node/cli.ts')],
output: {
format: 'esm',
entryFileNames: `[name].js`,
chunkFileNames: 'serve-[hash].js',
dir: r('dist/node')
},
external,
plugins,
onwarn(warning, warn) {
if (warning.code !== 'EVAL') warn(warning)
}
}
const cjsBuild: RollupOptions = {
input: [r('src/node/index.ts'), r('src/node/cli.ts')],
output: {
format: 'cjs',
dir: r('dist/node-cjs'),
entryFileNames: `[name].cjs`,
chunkFileNames: 'serve-[hash].cjs'
},
external,
plugins,
onwarn(warning, warn) {
if (warning.code !== 'EVAL') warn(warning)
}
}
const nodeTypes: RollupOptions = {
input: r('src/node/index.ts'),
output: {
format: 'esm',
file: 'dist/node/index.d.ts'
},
plugins: [dts()]
}
const clientTypes: RollupOptions = {
input: r('dist/client-types/index.d.ts'),
output: {
format: 'esm',
file: 'dist/client/index.d.ts'
},
plugins: [
dts(),
{
name: 'cleanup',
async closeBundle() {
if (PROD) {
await fs.rm(r('dist/client-types'), { recursive: true })
}
}
}
]
}
const config = defineConfig([])
config.push(esmBuild)
if (PROD) {
config.push(cjsBuild)
}
config.push(nodeTypes)
config.push(clientTypes)
export default config

@ -1,11 +1,11 @@
const fs = require('fs-extra') import { copy } from 'fs-extra'
const glob = require('globby') import fg from 'fast-glob'
function toDest(file) { function toDest(file) {
return file.replace(/^src\//, 'dist/') return file.replace(/^src\//, 'dist/')
} }
glob.sync('src/client/**').forEach((file) => { fg.sync('src/client/**').forEach((file) => {
if (/(\.ts|tsconfig\.json)$/.test(file)) return if (/(\.ts|tsconfig\.json)$/.test(file)) return
fs.copy(file, toDest(file)) copy(file, toDest(file))
}) })

@ -1,7 +1,7 @@
const fs = require('fs-extra') import { copy } from 'fs-extra'
const glob = require('globby') import fg from 'fast-glob'
glob.sync('src/shared/**/*.ts').forEach((file) => { fg.sync('src/shared/**/*.ts').map(async (file) => {
fs.copy(file, file.replace(/^src\/shared\//, 'src/node/')) await copy(file, file.replace(/^src\/shared\//, 'src/node/'))
fs.copy(file, file.replace(/^src\/shared\//, 'src/client/')) await copy(file, file.replace(/^src\/shared\//, 'src/client/'))
}) })

@ -1,22 +1,24 @@
const fs = require('fs') import { readFileSync, writeFileSync } from 'fs'
const path = require('path') import { resolve } from 'path'
const chalk = require('chalk') import c from 'picocolors'
const semver = require('semver') import { inc as _inc, valid } from 'semver'
const { prompt } = require('enquirer') import prompts from 'prompts'
const execa = require('execa') import { execa } from 'execa'
const currentVersion = require('../package.json').version import { version as currentVersion } from '../package.json'
import { fileURLToPath } from 'url'
const versionIncrements = ['patch', 'minor', 'major'] const versionIncrements = ['patch', 'minor', 'major']
const inc = (i) => semver.inc(currentVersion, i) const dir = dirname(fileURLToPath(import.meta.url))
const inc = (i) => _inc(currentVersion, i)
const run = (bin, args, opts = {}) => const run = (bin, args, opts = {}) =>
execa(bin, args, { stdio: 'inherit', ...opts }) execa(bin, args, { stdio: 'inherit', ...opts })
const step = (msg) => console.log(chalk.cyan(msg)) const step = (msg) => console.log(c.cyan(msg))
async function main() { async function main() {
let targetVersion let targetVersion
const { release } = await prompt({ const { release } = await prompts({
type: 'select', type: 'select',
name: 'release', name: 'release',
message: 'Select release type', message: 'Select release type',
@ -25,7 +27,7 @@ async function main() {
if (release === 'custom') { if (release === 'custom') {
targetVersion = ( targetVersion = (
await prompt({ await prompts({
type: 'input', type: 'input',
name: 'version', name: 'version',
message: 'Input custom version', message: 'Input custom version',
@ -36,11 +38,11 @@ async function main() {
targetVersion = release.match(/\((.*)\)/)[1] targetVersion = release.match(/\((.*)\)/)[1]
} }
if (!semver.valid(targetVersion)) { if (!valid(targetVersion)) {
throw new Error(`Invalid target version: ${targetVersion}`) throw new Error(`Invalid target version: ${targetVersion}`)
} }
const { yes: tagOk } = await prompt({ const { yes: tagOk } = await prompts({
type: 'confirm', type: 'confirm',
name: 'yes', name: 'yes',
message: `Releasing v${targetVersion}. Confirm?` message: `Releasing v${targetVersion}. Confirm?`
@ -63,7 +65,7 @@ async function main() {
await run('pnpm', ['changelog']) await run('pnpm', ['changelog'])
await run('pnpm', ['prettier', '--write', 'CHANGELOG.md']) await run('pnpm', ['prettier', '--write', 'CHANGELOG.md'])
const { yes: changelogOk } = await prompt({ const { yes: changelogOk } = await prompts({
type: 'confirm', type: 'confirm',
name: 'yes', name: 'yes',
message: `Changelog generated. Does it look good?` message: `Changelog generated. Does it look good?`
@ -90,12 +92,12 @@ async function main() {
} }
function updatePackage(version) { function updatePackage(version) {
const pkgPath = path.resolve(path.resolve(__dirname, '..'), 'package.json') const pkgPath = resolve(resolve(dir, '..'), 'package.json')
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))
pkg.version = version pkg.version = version
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
} }
main().catch((err) => console.error(err)) main().catch((err) => console.error(err))

@ -1,35 +0,0 @@
import { defineConfig } from 'rollup'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import esbuild from 'rollup-plugin-esbuild'
import json from '@rollup/plugin-json'
import alias from '@rollup/plugin-alias'
import { resolve } from 'path'
const r = (p) => resolve(__dirname, '../', p)
const pkg = require('../package.json')
export default defineConfig({
input: [r('src/node/index.ts'), r('src/node/cli.ts')],
output: {
format: 'cjs',
dir: r('dist/node')
},
external: [...Object.keys(pkg.dependencies), 'buffer', 'punycode'],
plugins: [
alias({
entries: {
'readable-stream': 'stream'
}
}),
commonjs(),
nodeResolve(),
esbuild({
target: 'node12'
}),
json()
],
onwarn(warning, warn) {
if (warning.code !== 'EVAL') warn(warning)
}
})

@ -1,15 +1,15 @@
const fs = require('fs-extra') import { copy, remove } from 'fs-extra'
const chokidar = require('chokidar') import { watch } from 'chokidar'
const { normalizePath } = require('vite') import { normalizePath } from 'vite'
function toClientAndNode(method, file) { function toClientAndNode(method, file) {
file = normalizePath(file) file = normalizePath(file)
if (method === 'copy') { if (method === 'copy') {
fs.copy(file, file.replace(/^src\/shared\//, 'src/node/')) copy(file, file.replace(/^src\/shared\//, 'src/node/'))
fs.copy(file, file.replace(/^src\/shared\//, 'src/client/')) copy(file, file.replace(/^src\/shared\//, 'src/client/'))
} else if (method === 'remove') { } else if (method === 'remove') {
fs.remove(file.replace(/^src\/shared\//, 'src/node/')) remove(file.replace(/^src\/shared\//, 'src/node/'))
fs.remove(file.replace(/^src\/shared\//, 'src/client/')) remove(file.replace(/^src\/shared\//, 'src/client/'))
} }
} }
@ -18,16 +18,14 @@ function toDist(file) {
} }
// copy shared files to the client and node directory whenever they change. // copy shared files to the client and node directory whenever they change.
chokidar watch('src/shared/**/*.ts')
.watch('src/shared/**/*.ts')
.on('change', (file) => toClientAndNode('copy', file)) .on('change', (file) => toClientAndNode('copy', file))
.on('add', (file) => toClientAndNode('copy', file)) .on('add', (file) => toClientAndNode('copy', file))
.on('unlink', (file) => toClientAndNode('remove', file)) .on('unlink', (file) => toClientAndNode('remove', file))
// copy non ts files, such as an html or css, to the dist directory whenever // copy non ts files, such as an html or css, to the dist directory whenever
// they change. // they change.
chokidar watch('src/client/**/!(*.ts|tsconfig.json)')
.watch('src/client/**/!(*.ts|tsconfig.json)') .on('change', (file) => copy(file, toDist(file)))
.on('change', (file) => fs.copy(file, toDist(file))) .on('add', (file) => copy(file, toDist(file)))
.on('add', (file) => fs.copy(file, toDist(file))) .on('unlink', (file) => remove(toDist(file)))
.on('unlink', (file) => fs.remove(toDist(file)))

@ -107,16 +107,11 @@ function newRouter(): Router {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js') pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
} }
// in browser: native dynamic import
if (inBrowser) { if (inBrowser) {
isInitialPageLoad = false isInitialPageLoad = false
return import(/*@vite-ignore*/ pageFilePath)
} }
// SSR: sync require return import(/*@vite-ignore*/ pageFilePath)
// @ts-ignore
return require(pageFilePath)
}, NotFound) }, NotFound)
} }

@ -25,7 +25,5 @@ export { inBrowser, withBase } from './app/utils'
// components // components
export { Content } from './app/components/Content' export { Content } from './app/components/Content'
import { ComponentOptions } from 'vue'
import _Debug from './app/components/Debug.vue' import _Debug from './app/components/Debug.vue'
const Debug = _Debug as ComponentOptions export const Debug = _Debug as import('vue').ComponentOptions
export { Debug }

@ -1,10 +1,12 @@
{ {
"extends": "../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"outDir": "../../dist/client", "outDir": "../../dist/client",
"target": "esnext", "target": "esnext",
"module": "esnext", "module": "esnext",
"declaration": true,
"declarationDir": "../../dist/client-types",
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"types": ["vite/client"], "types": ["vite/client"],
"paths": { "paths": {

@ -1,11 +1,14 @@
import path from 'path' import { createRequire } from 'module'
import { resolve, join } from 'path'
import { fileURLToPath } from 'url'
import { Alias, AliasOptions } from 'vite' import { Alias, AliasOptions } from 'vite'
const PKG_ROOT = path.join(__dirname, '../../') const require = createRequire(import.meta.url)
export const DIST_CLIENT_PATH = path.join(__dirname, '../client') const PKG_ROOT = resolve(fileURLToPath(import.meta.url), '../..')
export const APP_PATH = path.join(DIST_CLIENT_PATH, 'app') export const DIST_CLIENT_PATH = resolve(PKG_ROOT, 'client')
export const SHARED_PATH = path.join(DIST_CLIENT_PATH, 'shared') export const APP_PATH = join(DIST_CLIENT_PATH, 'app')
export const DEFAULT_THEME_PATH = path.join(DIST_CLIENT_PATH, 'theme-default') export const SHARED_PATH = join(DIST_CLIENT_PATH, 'shared')
export const DEFAULT_THEME_PATH = join(DIST_CLIENT_PATH, 'theme-default')
// special virtual file // special virtual file
// we can't directly import '/@siteData' because // we can't directly import '/@siteData' because
@ -39,11 +42,11 @@ export function resolveAliases(root: string, themeDir: string): AliasOptions {
})), })),
{ {
find: /^vitepress$/, find: /^vitepress$/,
replacement: path.join(__dirname, '../client/index') replacement: join(DIST_CLIENT_PATH, '/index')
}, },
{ {
find: /^vitepress\/theme$/, find: /^vitepress\/theme$/,
replacement: path.join(__dirname, '../client/theme-default/index') replacement: join(DIST_CLIENT_PATH, '/theme-default/index')
}, },
// alias for local linked development // alias for local linked development
{ find: /^vitepress\//, replacement: PKG_ROOT + '/' }, { find: /^vitepress\//, replacement: PKG_ROOT + '/' },

@ -6,6 +6,9 @@ import { normalizePath, transformWithEsbuild } from 'vite'
import { RollupOutput, OutputChunk, OutputAsset } from 'rollup' import { RollupOutput, OutputChunk, OutputAsset } from 'rollup'
import { slash } from '../utils/slash' import { slash } from '../utils/slash'
import escape from 'escape-html' import escape from 'escape-html'
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
export async function renderPage( export async function renderPage(
config: SiteConfig, config: SiteConfig,
@ -16,7 +19,7 @@ export async function renderPage(
pageToHashMap: Record<string, string>, pageToHashMap: Record<string, string>,
hashMapString: string hashMapString: string
) { ) {
const { createApp } = require(path.join(config.tempDir, `app.js`)) const { createApp } = await import(path.join(config.tempDir, `app.js`))
const { app, router } = createApp() const { app, router } = createApp()
const routePath = `/${page.replace(/\.md$/, '')}` const routePath = `/${page.replace(/\.md$/, '')}`
const siteData = resolveSiteDataByRoute(config.site, routePath) const siteData = resolveSiteDataByRoute(config.site, routePath)
@ -34,7 +37,7 @@ export async function renderPage(
} }
// render page // render page
const content = await require(rendererPath).renderToString(app) const content = await import(rendererPath).then((r) => r.renderToString(app))
const pageName = page.replace(/\//g, '_') const pageName = page.replace(/\//g, '_')
// server build doesn't need hash // server build doesn't need hash
@ -45,10 +48,9 @@ export async function renderPage(
const pageClientJsFileName = `assets/${pageName}.${pageHash}.lean.js` const pageClientJsFileName = `assets/${pageName}.${pageHash}.lean.js`
// resolve page data so we can render head tags // resolve page data so we can render head tags
const { __pageData } = require(path.join( const { __pageData } = await import(
config.tempDir, path.join(config.tempDir, pageServerJsFileName)
pageServerJsFileName )
))
const pageData = JSON.parse(__pageData) const pageData = JSON.parse(__pageData)
let preloadLinks = config.mpa let preloadLinks = config.mpa

@ -1,10 +1,11 @@
import chalk from 'chalk' import c from 'picocolors'
import minimist from 'minimist' import minimist from 'minimist'
import { createServer, build, serve } from '.' import { createServer, build, serve } from '.'
import { version } from '../../package.json'
const argv: any = minimist(process.argv.slice(2)) const argv: any = minimist(process.argv.slice(2))
console.log(chalk.cyan(`vitepress v${require('../../package.json').version}`)) console.log(c.cyan(`vitepress v${version}`))
const command = argv._[0] const command = argv._[0]
const root = argv._[command ? 1 : 0] const root = argv._[command ? 1 : 0]
@ -20,20 +21,20 @@ if (!command || command === 'dev') {
server.printUrls() server.printUrls()
}) })
.catch((err) => { .catch((err) => {
console.error(chalk.red(`failed to start server. error:\n`), err) console.error(c.red(`failed to start server. error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else if (command === 'build') { } else if (command === 'build') {
build(root, argv).catch((err) => { build(root, argv).catch((err) => {
console.error(chalk.red(`build error:\n`), err) console.error(c.red(`build error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else if (command === 'serve') { } else if (command === 'serve') {
serve(argv).catch((err) => { serve(argv).catch((err) => {
console.error(chalk.red(`failed to start server. error:\n`), err) console.error(c.red(`failed to start server. error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else { } else {
console.log(chalk.red(`unknown command "${command}".`)) console.log(c.red(`unknown command "${command}".`))
process.exit(1) process.exit(1)
} }

@ -1,7 +1,7 @@
import path from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import chalk from 'chalk' import c from 'picocolors'
import globby from 'globby' import fg from 'fast-glob'
import { import {
normalizePath, normalizePath,
AliasOptions, AliasOptions,
@ -23,7 +23,6 @@ import { MarkdownOptions } from './markdown/markdown'
import _debug from 'debug' import _debug from 'debug'
export { resolveSiteDataByRoute } from './shared' export { resolveSiteDataByRoute } from './shared'
export type { MarkdownOptions }
const debug = _debug('vitepress:config') const debug = _debug('vitepress:config')
@ -125,14 +124,14 @@ export async function resolveConfig(
? userThemeDir ? userThemeDir
: DEFAULT_THEME_PATH : DEFAULT_THEME_PATH
// Important: globby/fast-glob doesn't guarantee order of the returned files. // Important: fast-glob doesn't guarantee order of the returned files.
// We must sort the pages so the input list to rollup is stable across // We must sort the pages so the input list to rollup is stable across
// builds - otherwise different input order could result in different exports // builds - otherwise different input order could result in different exports
// order in shared chunks which in turns invalidates the hash of every chunk! // order in shared chunks which in turns invalidates the hash of every chunk!
// JavaScript built-in sort() is mandated to be stable as of ES2019 and // JavaScript built-in sort() is mandated to be stable as of ES2019 and
// supported in Node 12+, which is required by Vite. // supported in Node 12+, which is required by Vite.
const pages = ( const pages = (
await globby(['**.md'], { await fg(['**.md'], {
cwd: srcDir, cwd: srcDir,
ignore: ['**/node_modules', ...(userConfig.srcExclude || [])] ignore: ['**/node_modules', ...(userConfig.srcExclude || [])]
}) })
@ -190,7 +189,7 @@ async function resolveUserConfig(
: {} : {}
if (configPath) { if (configPath) {
debug(`loaded config at ${chalk.yellow(configPath)}`) debug(`loaded config at ${c.yellow(configPath)}`)
} else { } else {
debug(`no config file found.`) debug(`no config file found.`)
} }

@ -6,7 +6,7 @@ import { createMarkdownRenderer, MarkdownOptions } from './markdown/markdown'
import { deeplyParseHeader } from './utils/parseHeader' import { deeplyParseHeader } from './utils/parseHeader'
import { PageData, HeadConfig, EXTERNAL_URL_RE } from './shared' import { PageData, HeadConfig, EXTERNAL_URL_RE } from './shared'
import { slash } from './utils/slash' import { slash } from './utils/slash'
import chalk from 'chalk' import c from 'picocolors'
import _debug from 'debug' import _debug from 'debug'
import { getGitTimestamp } from './utils/getGitTimestamp' import { getGitTimestamp } from './utils/getGitTimestamp'
@ -96,10 +96,8 @@ export async function createMarkdownToVueRenderFn(
const deadLinks: string[] = [] const deadLinks: string[] = []
const recordDeadLink = (url: string) => { const recordDeadLink = (url: string) => {
console.warn( console.warn(
chalk.yellow( c.yellow(
`\n(!) Found dead link ${chalk.cyan(url)} in file ${chalk.white.dim( `\n(!) Found dead link ${c.cyan(url)} in file ${c.white(c.dim(file))}`
file
)}`
) )
) )
deadLinks.push(url) deadLinks.push(url)

@ -30,7 +30,7 @@ const isPageChunk = (
chunk.facadeModuleId.endsWith('.md') chunk.facadeModuleId.endsWith('.md')
) )
export function createVitePressPlugin( export async function createVitePressPlugin(
root: string, root: string,
siteConfig: SiteConfig, siteConfig: SiteConfig,
ssr = false, ssr = false,
@ -51,10 +51,12 @@ export function createVitePressPlugin(
let markdownToVue: Awaited<ReturnType<typeof createMarkdownToVueRenderFn>> let markdownToVue: Awaited<ReturnType<typeof createMarkdownToVueRenderFn>>
// lazy require plugin-vue to respect NODE_ENV in @vue/compiler-x // lazy require plugin-vue to respect NODE_ENV in @vue/compiler-x
const vuePlugin = require('@vitejs/plugin-vue')({ const vuePlugin = await import('@vitejs/plugin-vue').then((r) =>
include: [/\.vue$/, /\.md$/], r.default({
...userVuePluginOptions include: [/\.vue$/, /\.md$/],
}) ...userVuePluginOptions
})
)
const processClientJS = (code: string, id: string) => { const processClientJS = (code: string, id: string) => {
return scriptClientRE.test(code) return scriptClientRE.test(code)

@ -12,7 +12,7 @@ export async function createServer(
root: config.srcDir, root: config.srcDir,
base: config.site.base, base: config.site.base,
// logLevel: 'warn', // logLevel: 'warn',
plugins: createVitePressPlugin(root, config), plugins: await createVitePressPlugin(root, config),
server: serverOptions server: serverOptions
}) })
} }

@ -1,10 +1,10 @@
{ {
"extends": "../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "es2019", "target": "es2020",
"baseUrl": ".", "baseUrl": ".",
"outDir": "../../dist/node", "outDir": "../../dist/node",
"module": "commonjs", "module": "esnext",
"types": ["node"], "types": ["node"],
"sourceMap": true "sourceMap": true
}, },

@ -14,7 +14,7 @@ import emojiData from 'markdown-it-emoji/lib/data/full.json'
const parseEmojis = (str: string) => { const parseEmojis = (str: string) => {
return str.replace( return str.replace(
/:(.+?):/g, /:(.+?):/g,
(placeholder, key) => emojiData[key] || placeholder (placeholder, key) => (emojiData as any)[key] || placeholder
) )
} }

@ -1,12 +1,17 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "esnext", "module": "esnext",
"target": "esnext",
"moduleResolution": "node", "moduleResolution": "node",
"esModuleInterop": true,
"strict": true, "strict": true,
"noUnusedLocals": true,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": true, "noUnusedLocals": true,
"lib": ["ESNext"] "resolveJsonModule": true,
"lib": ["ESNext", "DOM"]
}, },
"include": ["../types/shared.d.ts"] "exclude": [
"**/node_modules/**",
"**/dist/**"
]
} }
Loading…
Cancel
Save