feat: prototype blog post generation in dev server

This commit is contained in:
endiliey 2018-07-30 01:35:35 +08:00
parent 8cbd23d690
commit 7ecd4c9bef
9 changed files with 112 additions and 31 deletions

13
lib/core/blogPost.js Normal file
View file

@ -0,0 +1,13 @@
const React = require('react');
import blogDatas from '@generated/blogDatas';
// inner blog component for the article itself, without sidebar/header/footer
class BlogPost extends React.Component {
render() {
const {match} = this.props;
const post = blogDatas.find(blog => blog.path === match.path);
return <div className="post">{post && post.content}</div>;
}
}
module.exports = BlogPost;

View file

@ -1,30 +1,30 @@
import React from 'react';
import {render} from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Hello from '@theme/hello';
import Layout from '@theme/layout';
import {BrowserRouter, Route, Switch, Link} from 'react-router-dom';
import BlogPost from './blogPost';
import blogDatas from '@generated/blogDatas';
class App extends React.Component {
render() {
const routes = [
{
path: '/',
component: Hello
},
{
path: '/layout',
component: Layout
}
];
return (
<BrowserRouter>
<div>
<Switch>
{routes.map(({path, component}) => (
<Route key={path} exact path={path} component={component} />
{blogDatas.map(({path}) => (
<Route key={path} exact path={path} component={BlogPost} />
))}
</Switch>
<div>
{blogDatas.map(({path}) => {
return (
<div>
<Link key={path} to={path}>
{path}
</Link>
</div>
);
})}
</div>
</div>
</BrowserRouter>
);

View file

@ -3,11 +3,22 @@ const fs = require('fs-extra');
const chalk = require('chalk');
const webpack = require('webpack');
const chokidar = require('chokidar');
const convert = require('koa-connect')
const range = require('koa-range')
const history = require('connect-history-api-fallback')
const portfinder = require('portfinder')
const serve = require('webpack-serve');
const webpackNiceLog = require('webpack-nicelog');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const load = require('./loader');
const createDevConfig = require('./webpack/dev');
async function getPort (port) {
portfinder.basePort = parseInt(port) || 8080
port = await portfinder.getPortPromise()
return port
}
module.exports = async function dev(sourceDir, cliOptions = {}) {
// load site props from preprocessed files in source directory
const props = await load(sourceDir);
@ -18,7 +29,7 @@ module.exports = async function dev(sourceDir, cliOptions = {}) {
console.error(chalk.red(err.stack));
});
};
const fsWatcher = chokidar.watch(['**/*.md'], {
const fsWatcher = chokidar.watch(['**/*.md', '.blogi/config.js'], {
cwd: sourceDir,
ignoreInitial: true
});
@ -31,7 +42,7 @@ module.exports = async function dev(sourceDir, cliOptions = {}) {
// resolve webpack config
let config = createDevConfig(props);
const port = cliOptions.port || 8080;
const port = await getPort(cliOptions.port);
const {publicPath} = props;
config.plugin('WebpackNiceLog').use(webpackNiceLog, [
@ -46,6 +57,15 @@ module.exports = async function dev(sourceDir, cliOptions = {}) {
}
]);
config.plugin('html-webpack-plugin').use(HtmlWebpackPlugin, [
{
inject: false,
hash: true,
template: path.resolve(__dirname, 'core/index.html'),
filename: 'index.html'
}
]);
// create compiler from generated webpack config
config = config.toConfig();
const compiler = webpack(config);
@ -65,7 +85,15 @@ module.exports = async function dev(sourceDir, cliOptions = {}) {
logLevel: 'error'
},
logLevel: 'error',
port
port,
add: app => {
app.use(range) // enable range request https://tools.ietf.org/html/rfc7233
app.use(convert(history({
rewrites: [
{ from: /\.html$/, to: '/' }
]
})))
}
}
);
};

View file

@ -10,6 +10,15 @@ module.exports = async function load(sourceDir) {
// extract data from all blog files
const blogDatas = await loadBlog(sourceDir);
fs.writeFile(
path.resolve(__dirname, '../generated/blogDatas.js'),
`${'/**\n' +
' * @' +
'generated\n' +
' */\n' +
'module.exports = '}${JSON.stringify(blogDatas, null, 2)};\n`
);
// resolve outDir
const outDir = siteConfig.dest
? path.resolve(siteConfig.dest)

View file

@ -1,6 +1,5 @@
const Config = require('webpack-chain');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = function createBaseConfig(props) {
const {outDir, themePath, sourceDir, publicPath} = props;
@ -43,14 +42,5 @@ module.exports = function createBaseConfig(props) {
presets: ['env', 'react']
});
config.plugin('html-webpack-plugin').use(HtmlWebpackPlugin, [
{
inject: false,
hash: true,
template: path.resolve(__dirname, '../core/index.html'),
filename: 'index.html'
}
]);
return config;
};