-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
1,000 additions
and
1,074 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
const path = require('path') | ||
const { build } = require('../lib') | ||
const { serve, build } = require('../lib') | ||
|
||
build(path.resolve(__dirname, '../docs')).catch(err => { | ||
console.log(err) | ||
const sourceDir = path.resolve(__dirname, '../docs') | ||
|
||
serve(sourceDir).catch(err => { | ||
console.error(err) | ||
}) | ||
|
||
// build(sourceDir).catch(err => { | ||
// console.log(err) | ||
// }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
--- | ||
foo: 123 | ||
bar: 234 | ||
--- | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module.exports = async function build (sourceDir) { | ||
process.env.NODE_ENV = 'production' | ||
|
||
const prepare = require('./prepare') | ||
const path = require('path') | ||
const webpack = require('webpack') | ||
const { promisify } = require('util') | ||
const rimraf = promisify(require('rimraf')) | ||
const createClientConfig = require('./webpack/clientConfig') | ||
const createServerConfig = require('./webpack/serverConfig') | ||
|
||
const options = await prepare(sourceDir) | ||
|
||
const targetDir = path.resolve(sourceDir, '_dist') | ||
await rimraf(targetDir) | ||
|
||
const clientConfig = createClientConfig(options).toConfig() | ||
const serverConfig = createServerConfig(options).toConfig() | ||
|
||
await Promise.all([ | ||
compile(clientConfig), | ||
compile(serverConfig) | ||
]) | ||
|
||
function compile (config) { | ||
return new Promise((resolve, reject) => { | ||
webpack(config, (err, stats) => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
if (stats.hasErrors()) { | ||
reject(`Failed to compile with errors.`) | ||
stats.toJson().errors.forEach(err => { | ||
console.error(err) | ||
}) | ||
return | ||
} | ||
resolve() | ||
}) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title></title> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,2 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const rimraf = require('rimraf') | ||
const globby = require('globby') | ||
const webpack = require('webpack') | ||
const tempPath = path.resolve(__dirname, 'app/.temp') | ||
const createClientConfig = require('./webpack/clientConfig') | ||
const createServerConfig = require('./webpack/serverConfig') | ||
|
||
exports.build = async function build (sourceDir) { | ||
// 1. loadConfig | ||
// const config = await resolveConfig(sourceDir) | ||
|
||
// 2. generate dynamic component registration file | ||
await genComponentRegistrationFile(sourceDir) | ||
|
||
// 3. generate routes | ||
await genRoutesFile(sourceDir) | ||
|
||
// 4. client build | ||
const clientConfig = createClientConfig({ sourceDir }).toConfig() | ||
return new Promise((resolve, reject) => { | ||
rimraf.sync(clientConfig.output.path) | ||
webpack(clientConfig, (err, stats) => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
if (stats.hasErrors()) { | ||
return reject(stats.toJson().errors) | ||
} | ||
resolve() | ||
}) | ||
}) | ||
} | ||
|
||
async function genComponentRegistrationFile (sourceDir) { | ||
const pages = await globby(['**/*.md'], { cwd: sourceDir }) | ||
const components = (await resolveComponents(sourceDir)) || [] | ||
|
||
function genImport (file) { | ||
const isPage = /\.md$/.test(file) | ||
const name = (isPage ? `page-` : ``) + file.replace(/\.(vue|md)$/, '').replace(/\/|\\/, '-') | ||
const baseDir = isPage ? sourceDir : path.resolve(sourceDir, '_components') | ||
const absolutePath = path.resolve(baseDir, file) | ||
const code = `Vue.component(${JSON.stringify(name)}, () => import(${JSON.stringify(absolutePath)}))` | ||
return code | ||
} | ||
|
||
const all = [...pages, ...components] | ||
const file = `import Vue from 'vue'\n` + all.map(genImport).join('\n') | ||
fs.writeFileSync(path.join(tempPath, 'register-components.js'), file) | ||
} | ||
|
||
async function resolveComponents (sourceDir) { | ||
const componentDir = path.resolve(sourceDir, '_components') | ||
if (!fs.existsSync(componentDir)) { | ||
return | ||
} | ||
return await globby(['*.vue'], { cwd: componentDir }) | ||
} | ||
|
||
async function genRoutesFile (sourceDir) { | ||
const pages = await globby(['**/*.md'], { cwd: sourceDir }) | ||
|
||
function genRoute (file) { | ||
const name = file.replace(/\.md$/, '') | ||
const code = ` | ||
{ | ||
path: ${JSON.stringify('/' + (name === 'index' ? '' : name))}, | ||
component: Layout | ||
}` | ||
return code | ||
} | ||
|
||
const file = | ||
`import Layout from '~layout'\n` + | ||
`export default [${pages.map(genRoute).join(',')}\n]` | ||
fs.writeFileSync(path.join(tempPath, 'routes.js'), file) | ||
} | ||
exports.build = require('./build') | ||
exports.serve = require('./serve') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const globby = require('globby') | ||
const yaml = require('yaml-front-matter') | ||
const tempPath = path.resolve(__dirname, 'app/.temp') | ||
|
||
module.exports = async function prepare (sourceDir) { | ||
// 1. load options | ||
const options = await resolveOptions(sourceDir) | ||
|
||
// 2. generate dynamic component registration file | ||
await genComponentRegistrationFile(options) | ||
|
||
// 3. generate routes | ||
await genRoutesFile(options) | ||
|
||
return options | ||
} | ||
|
||
async function resolveOptions (sourceDir) { | ||
const configPath = path.resolve(sourceDir, 'vuepress.config.js') | ||
const siteConfig = fs.existsSync(configPath) ? require(configPath) : {} | ||
|
||
const options = { | ||
siteConfig, | ||
sourceDir, | ||
publicPath: siteConfig.baseUrl || '/', | ||
themePath: path.resolve(__dirname, 'default-theme/App.vue'), | ||
templatePath: path.resolve(__dirname, 'default-theme/index.html'), | ||
pages: await globby(['**/*.md'], { cwd: sourceDir }) | ||
} | ||
|
||
// resolve theme & index template | ||
const themeDir = path.resolve(sourceDir, '_theme') | ||
if (fs.existsSync(themeDir)) { | ||
const template = path.resolve(themeDir, 'index.html') | ||
if (fs.existsSync(template)) { | ||
options.templatePath = template | ||
} | ||
|
||
const app = path.resolve(themeDir, 'App.vue') | ||
if (fs.existsSync(app)) { | ||
options.themePath = app | ||
} | ||
} | ||
|
||
const pagesData = {} | ||
options.pages.forEach(file => { | ||
const name = file.replace(/\.md$/, '') | ||
const urlPath = '/' + (name === 'index' ? '' : name) | ||
const componentName = toComponentName(file) | ||
const content = fs.readFileSync(path.resolve(sourceDir, file), 'utf-8') | ||
const frontmatter = yaml.loadFront(content) | ||
delete frontmatter.__content | ||
pagesData[urlPath] = { | ||
name, | ||
path: urlPath, | ||
componentName, | ||
frontmatter | ||
} | ||
}) | ||
|
||
options.siteData = Object.assign({}, siteConfig.data, { | ||
pages: pagesData | ||
}) | ||
|
||
return options | ||
} | ||
|
||
function toComponentName (file) { | ||
const isPage = /\.md$/.test(file) | ||
return ( | ||
(isPage ? `page-` : ``) + | ||
file | ||
.replace(/\.(vue|md)$/, '') | ||
.replace(/\/|\\/, '-') | ||
) | ||
} | ||
|
||
async function genComponentRegistrationFile ({ sourceDir, pages }) { | ||
function genImport (file) { | ||
const name = toComponentName(file) | ||
const baseDir = /\.md$/.test(file) | ||
? sourceDir | ||
: path.resolve(sourceDir, '_components') | ||
const absolutePath = path.resolve(baseDir, file) | ||
const code = `Vue.component(${JSON.stringify(name)}, () => import(${JSON.stringify(absolutePath)}))` | ||
return code | ||
} | ||
|
||
const components = (await resolveComponents(sourceDir)) || [] | ||
const all = [...pages, ...components] | ||
const file = `import Vue from 'vue'\n` + all.map(genImport).join('\n') | ||
fs.writeFileSync(path.join(tempPath, 'register-components.js'), file) | ||
} | ||
|
||
async function resolveComponents (sourceDir) { | ||
const componentDir = path.resolve(sourceDir, '_components') | ||
if (!fs.existsSync(componentDir)) { | ||
return | ||
} | ||
return await globby(['*.vue'], { cwd: componentDir }) | ||
} | ||
|
||
async function genRoutesFile ({ sourceDir, pages }) { | ||
function genRoute (file) { | ||
const name = file.replace(/\.md$/, '') | ||
const code = ` | ||
{ | ||
path: ${JSON.stringify('/' + (name === 'index' ? '' : name))}, | ||
component: Theme | ||
}` | ||
return code | ||
} | ||
|
||
const file = | ||
`import Theme from '~theme'\n` + | ||
`export default [${pages.map(genRoute).join(',')}\n]` | ||
fs.writeFileSync(path.join(tempPath, 'routes.js'), file) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module.exports = async function serve (sourceDir) { | ||
const chalk = require('chalk') | ||
const prepare = require('./prepare') | ||
const webpack = require('webpack') | ||
const serve = require('webpack-serve') | ||
const HTMLPlugin = require('html-webpack-plugin') | ||
const convert = require('koa-connect') | ||
const history = require('connect-history-api-fallback') | ||
const createClientConfig = require('./webpack/clientConfig') | ||
const SiteDataPlugin = require('./webpack/SiteDataPlugin') | ||
|
||
const options = await prepare(sourceDir) | ||
|
||
const _config = createClientConfig(options) | ||
|
||
_config | ||
.plugin('html') | ||
.use(HTMLPlugin, [{ template: options.templatePath }]) | ||
|
||
_config | ||
.plugin('site-data') | ||
.use(SiteDataPlugin, [options.siteData]) | ||
|
||
const config = _config.toConfig() | ||
const compiler = webpack(config) | ||
const port = options.siteConfig.port || 8080 | ||
|
||
let isFirst = true | ||
compiler.hooks.done.tap('vuepress', () => { | ||
if (isFirst) { | ||
isFirst = false | ||
console.log( | ||
`\n VuePress dev server listening at ${ | ||
chalk.cyan(`http://localhost:${port}`) | ||
}\n` | ||
) | ||
} | ||
}) | ||
|
||
await serve({ | ||
compiler, | ||
dev: { logLevel: 'error' }, | ||
hot: { logLevel: 'error' }, | ||
logLevel: 'error', | ||
port, | ||
add: app => app.use(convert(history())) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
module.exports = class SiteDataPlugin { | ||
constructor (data) { | ||
this.data = data | ||
} | ||
|
||
apply (compiler) { | ||
compiler.hooks.compilation.tap('vuepress-site-data', compilation => { | ||
compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync('vuepress-site-data', (data, cb) => { | ||
try { | ||
data.head.push({ | ||
tagName: 'script', | ||
closeTag: true, | ||
innerHTML: `window.VUEPRESS_DATA = ${JSON.stringify(this.data)}` | ||
}) | ||
} catch (e) { | ||
return cb(e) | ||
} | ||
cb(null, data) | ||
}) | ||
}) | ||
} | ||
} |
Oops, something went wrong.