Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 4, 2018
0 parents commit db62430
Show file tree
Hide file tree
Showing 23 changed files with 3,994 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
node_modules
*.log
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# VuePress

> Minimalistic docs generator with Vue component based layout system
## Goals

- Vue-powered: the layout system is a Vue app. It's also pre-rendered into static HTML. And you can register and use Vue components inside markdown content.

- Docs first: most of your content will be in Markdown.

- Largely gitbook compatible: should be easy to migrate existing gitbook docs over, and maintain original URLs.

- GitHub friendly: pages should be able to link to each other using relative links that ends in `.md`. Also should be able to infer relative position if a GitHub repo name is provided.

- Minimal: most of the additional things are expected to be done in your layout using plain Vue/JavaScript.
4 changes: 4 additions & 0 deletions bin/vuepress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const path = require('path')
const { build } = require('../lib')

build(path.resolve(__dirname, '../docs'))
15 changes: 15 additions & 0 deletions docs/_components/demo-1.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<div>
{{ msg }}
</div>
</template>

<script>
export default {
data () {
return {
msg: 'hello'
}
}
}
</script>
3 changes: 3 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# VuePress

> Minimalistic docs generator with Vue component based layout system
9 changes: 9 additions & 0 deletions docs/kitchen-sink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
foo: 123
bar: 234
---

``` js
const a = 123
```

<demo-1 vue></demo-1>
21 changes: 21 additions & 0 deletions docs/layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Custom Layout

VuePress uses Vue single file components for custom layouts. To use a custom layout, create a `_layout` directory under `docs`, and then create a `Layout.vue` file:

```
- docs
- _layout
- Layout.vue
```

From there it's the same as developing a normal Vue application. There are only a few special things to note:

## Site and Page Metadata

The `Layout` component will be invoked once for every `.md` file in `docs`, and the metadata for the entire site and that specific page will be exposed respectively in `$site` and `$page` properties which are injected into every component in the app.

// TODO details about $site & $page

## Content Outlet

The compiled content of the current `.md` file being rendered will be available as a special `<Content/>` global component. You will need to render it somewhere in your layout in order to display the content of the page.
Empty file added docs/recipes.md
Empty file.
14 changes: 14 additions & 0 deletions docs/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Setup

## Quickstart

``` bash
npm install -D vuepress
mkdir docs
echo '# Hello VuePress!' > docs/index.md
./node_modules/.bin/vuepress build
```

## Configuration

`_config.yml`
1 change: 1 addition & 0 deletions lib/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.temp
40 changes: 40 additions & 0 deletions lib/app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

// layout is resolved dynamically and set as an alias
import Layout from '~layout'

// dynamically generated files:

// register-commponents.js registers all *.vue files found in _components
// as global async components
import './.temp/register-components'

// routes are generated from md files
import routes from './.temp/routes'

const router = new Router({
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes
})

// expose Vue Press data
const g = typeof window !== 'undefined' ? window : global
const $site = Vue.prototype.$site = g.VUE_PRESS_DATA

Vue.mixin({
computed: {
$page () {
return $site.pages[this.$route.path]
}
}
})

const app = new Vue({
router,
render: h => h(Layout)
})

export { app, router }
5 changes: 5 additions & 0 deletions lib/app/clientEntry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { app, router } from './app'

router.onReady(() => {
app.$mount('#app')
})
13 changes: 13 additions & 0 deletions lib/app/serverEntry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { app, router } from './app'

export default context => new Promise((resolve, reject) => {
const { url } = context
const { fullPath } = router.resolve(url).route

if (fullPath !== url) {
return reject({ url: fullPath })
}

router.push(url)
router.onReady(() => resolve(app))
})
5 changes: 5 additions & 0 deletions lib/default-layout/Index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="index">
<Content/>
</div>
</template>
15 changes: 15 additions & 0 deletions lib/default-layout/Layout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<div id="container">
<Index v-if="$page.isIndex" />
<Page v-else />
</div>
</template>

<script>
import Index from './Index.vue'
import Page from './Page.vue'
export default {
components: { Index, Page }
}
</script>
5 changes: 5 additions & 0 deletions lib/default-layout/Page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="content">
<Content/>
</div>
</template>
Empty file added lib/default-layout/index.html
Empty file.
43 changes: 43 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const fs = require('fs')
const path = require('path')
const globby = require('globby')
const webpack = require('webpack')
const tempPath = path.resolve(__dirname, 'app/.temp')

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. build
}

async function genComponentRegistrationFile (sourceDir) {
const componentDir = path.resolve(sourceDir, '_components')
if (!fs.existsSync(componentDir)) {
return
}

const components = await globby(['*.vue'], { cwd: componentDir })
if (!components.length) {
return
}

const file = `import Vue from 'vue'\n` + components.map(file => {
const name = file.replace(/\.vue$/, '')
const absolutePath = path.resolve(componentDir, file)
const code = `Vue.component(${JSON.stringify(name)}, () => import(${JSON.stringify(absolutePath)}))`
return code
}).join('\n')

fs.writeFileSync(path.join(tempPath, 'register-components.js'), file)
}

async function genRoutesFile () {

}
115 changes: 115 additions & 0 deletions lib/webpack/baseConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const path = require('path')

module.exports = function createBaseConfig ({
sourceDir,
publicPath = '/',
layoutPath = path.resolve(__dirname, '../default-layout/Layout.vue')
}) {
const Config = require('webpack-chain')
const { VueLoaderPlugin } = require('vue-loader')
const CSSExtractPlugin = require('mini-css-extract-plugin')

const isProd = process.env.NODE_ENV === 'production'

const config = new Config()

config
.set('mode', isProd ? 'production' : 'development')
.output
.path(path.resolve(sourceDir, 'dist'))
.filename('[name].[chunkhash].js')
.publicPath(publicPath)

config.alias
.set('~layout', layoutPath)

config.resolve
.set('symlinks', true)
.extensions
.merge(['.js', '.jsx', '.vue', '.json'])
.end()
.modules
.add('node_modules')
.add(path.resolve(sourceDir, '../node_modules'))
.add(path.resolve(__dirname, '../../node_modules'))

config.resolveLoader
.set('symlinks', true)
.modules
.add('node_modules')
.add(path.resolve(sourceDir, '../node_modules'))
.add(path.resolve(__dirname, '../../node_modules'))

config.module
.noParse(/^(vue|vue-router|vuex|vuex-router-sync)$/)

config.module
.rule('vue')
.test(/\.vue$/)
.use('vue-loader')
.loader('vue-loader')
.options({
compilerOptions: {
preserveWhitespace: false
}
})

config.module
.rule('images')
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 10000,
name: `img/[name].[hash:8].[ext]`
})

// do not base64-inline SVGs.
// https://github.com/facebookincubator/create-react-app/pull/1180
config.module
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader('file-loader')
.options({
name: `img/[name].[hash:8].[ext]`
})

config.module
.rule('media')
.test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: inlineLimit,
name: `media/[name].[hash:8].[ext]`
})

config.module
.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
.use('url-loader')
.loader('url-loader')
.options({
limit: inlineLimit,
name: `fonts/[name].[hash:8].[ext]`
})

createCSSRule(config, 'css', /\.css$/)
createCSSRule(config, 'scss', /\.scss$/, 'sass-loader')
createCSSRule(config, 'sass', /\.sass$/, 'sass-loader', { indentedSyntax: true })
createCSSRule(config, 'less', /\.less$/, 'less-loader')
createCSSRule(config, 'stylus', /\.styl(us)?$/, 'stylus-loader')

config
.plugin('vue-loader')
.use(VueLoaderPlugin)

if (isProd) {
config
.plugin('extract-css')
.use(CSSExtractPlugin, [{ filename: 'styles.css' }])
}

return config
}
38 changes: 38 additions & 0 deletions lib/webpack/clientConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = function createClientConfig (options) {
const path = require('path')
const createBaseConfig = require('./baseConfig')

const config = createBaseConfig(options)

config
.entry('app')
.add(path.resolve(__dirname, '../app/clientEntry.js'))

config.node
.merge({
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
global: false,
// process is injected via DefinePlugin, although some 3rd party
// libraries may require a mock to work properly (#934)
process: 'mock',
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
})

// generate client manifest only during build
if (process.env.NODE_ENV === 'production') {
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
config
.plugin('ssr-client')
.use(VueSSRClientPlugin)
}

return config
}
Loading

0 comments on commit db62430

Please sign in to comment.