chore: normalize build procedure

This commit is contained in:
Benjy Cui 2016-03-04 18:06:34 +08:00
parent b33b91a166
commit 4e3f446279
16 changed files with 61 additions and 232 deletions

View File

@ -1,6 +1,6 @@
# 更新日志
- category: 4
- order: 4
---

View File

@ -1,6 +1,5 @@
# 快速上手
- category: 1
- order: 1
---

View File

@ -1,6 +1,5 @@
# 安装
- category: 2
- order: 2
---

View File

@ -1,6 +1,5 @@
# Ant Design of React
- category: 0
- order: 0
---

View File

@ -1,6 +1,5 @@
# 升级指南
- category: 3
- order: 3
---

View File

@ -1,45 +1,12 @@
'use strict';
const fs = require('fs');
const path = require('path');
const R = require('ramda');
const buildDemosList = require('./build-demos-list');
const devil = require('./devil');
const utils = require('./utils');
const isMeta = R.complement(R.propEq('type', 'hr'));
const getMeta = R.prop('meta');
const getOrder = R.compose(parseInt, R.path(['meta', 'order']));
const getMenuItems = R.compose(
R.groupBy(R.compose(R.defaultTo('topLevel'), R.prop('category'))),
R.map(getMeta)
);
const sortByOrder = R.sortBy(getOrder);
const parseDemos = function parseDemos(fileName) {
const demosPath = path.join(path.dirname(fileName), 'demo');
const demosMDFild = utils.findMDFile(demosPath);
return buildDemosList.parse(demosMDFild).docs; // TODO
};
const parse = function parse(fileName) {
const fileContent = utils.parseFileContent(fileName);
const meta = utils.parseMeta(fileContent);
const description = R.map(
(node) => {
if (node.type === 'code' && node.props.lang === '__react') {
return devil(node.children, ['React', 'antd']);
}
return node;
},
R.tail(R.dropWhile(isMeta, fileContent))
);
const demos = !utils.isIndex(fileName) ? null : parseDemos(fileName);
return { meta, description, demos };
};
module.exports = function buildCommon(inputDir, outputFile) {
const mds = utils.findMDFile(inputDir, true);
module.exports = function buildCommon(dirs, outputFile) {
const mds = utils.findMDFile(dirs, true)
.filter((file) => !/install_en\.md$/gi.test(file)); // TODO
let content = 'module.exports = {';
mds.forEach((md) => {

View File

@ -21,12 +21,13 @@ const parseDemosList = function parseDemosList(demoList) {
const demo = {};
demo.order = parseInt(utils.parseMeta(data).order);
demo.parent = parts[parts.indexOf('components') + 1];
const demoIndex = parts.indexOf('demo');
demo.parent = parts.slice(0, demoIndex).join('/') + '/index.md';
demo.id = 'components-' + demo.parent + '-demo-' + path.basename(fileName, '.md');
demo.title = data[0].children;
demo.intro = data.filter(isIntro);
demo.code = getChildren(data.find(isCode));
demo.preview = devil(demo.code);
demo.preview = devil(demo.code, ['React', 'ReactDOM', '_antd', 'BrowserDemo']);
demo.style = getChildren(data.find(isStyle));
return demo;
@ -39,11 +40,7 @@ const parseDemosList = function parseDemosList(demoList) {
module.exports = function buildDemosList(demoList, outputPath) {
const parsedDemosList = parseDemosList(demoList);
const content = 'const React = require(\'react\');\n' +
'const ReactDOM = require(\'react-dom\');\n' +
'const _antd = require(\'../../\');\n' +
'module.exports = ' +
utils.stringify(parsedDemosList, null, 2) + ';';
const content = 'module.exports = ' + utils.stringify(parsedDemosList) + ';';
fs.writeFile(outputPath, content);
};

View File

@ -1,26 +0,0 @@
'use strict';
const fs = require('fs');
const R = require('ramda');
const utils = require('./utils');
const isMeta = R.complement(R.propEq('type', 'hr'));
const isDescription = R.complement(R.propEq('children', 'API'));
module.exports = function buildDocsList(indexes, outputPath) {
const indexesList = R.map((fileName) => {
const fileContent = utils.parseFileContent(fileName);
const meta = utils.parseMeta(fileContent);
const description = R.tail(R.dropWhile(
isMeta,
R.takeWhile(isDescription, fileContent)
));
const api = R.dropWhile(isDescription, fileContent);
return { meta, description, api };
}, indexes);
const content = 'module.exports = ' +
JSON.stringify(indexesList, null, 2) + ';';
fs.writeFile(outputPath, content);
};

View File

@ -6,39 +6,22 @@
require('mkdirp').sync('./_site/data');
const fs = require('fs');
const path = require('path');
const R = require('ramda');
const utils = require('./utils');
const buildComponentsList = require('./build-components-list');
const buildDocsList = require('./build-docs-list');
const buildDemosList = require('./build-demos-list');
const buildCommon = require('./build-common');
// TODO: configurable
const componentPath = './components';
const mds = utils.findMDFile(componentPath);
const indexes = R.filter(utils.isIndex, mds);
buildComponentsList(indexes, './_site/data/components-list.js');
buildDocsList(indexes, './_site/data/component-docs-list.js');
const demos = R.filter(utils.isDemo, mds);
const mds = utils.findMDFile(['./components', './docs']);
const isDemo = R.compose(R.test(/\/demo$/i), path.dirname);
const demos = R.filter(isDemo, mds);
buildDemosList(demos, './_site/data/demos-list.js');
const changelogPath = './CHANGELOG.md';
buildDocsList([changelogPath], './_site/data/changelog.js');
const introducePath = './docs/react/introduce.md';
buildDocsList([introducePath], './_site/data/introduce.js');
const gettingStartedPath = './docs/react/getting-started.md';
buildDocsList([gettingStartedPath], './_site/data/getting-started.js');
const installPath = './docs/react/install.md';
buildDocsList([installPath], './_site/data/install.js');
const upgradeNotesPath = './docs/react/upgrade-notes.md';
buildDocsList([upgradeNotesPath], './_site/data/upgrade-notes.js');
buildCommon([
'./components',
'./docs/react',
'./CHANGELOG.md',
], './_site/data/react-components.js');
buildCommon('./docs/practice', './_site/data/practice.js');
buildCommon('./docs/pattern', './_site/data/pattern.js');

View File

@ -5,29 +5,35 @@ const path = require('path');
const R = require('ramda');
const isMDFile = R.compose(R.equals('.md'), path.extname);
exports.findMDFile = function findMDFile(dirPath, shallow) {
exports.findMDFile = function findMDFile(fileName, shallow) {
const filePaths = Array.isArray(fileName) ? fileName : [fileName];
let mds = [];
R.forEach((fileName) => {
const filePath = path.join(dirPath, fileName);
R.forEach((filePath) => {
const stat = fs.statSync(filePath);
if (stat.isFile() && isMDFile(filePath)) {
mds.push(filePath);
}
if (stat.isDirectory()) {
const indexFile = path.join(filePath, 'index.md');
if (shallow && fs.statSync(indexFile).isFile()) {
let hasIndexFile = false;
try {
hasIndexFile = fs.statSync(indexFile).isFile();
} catch (e) {}
if (shallow && hasIndexFile) {
mds.push(indexFile);
} else {
mds = mds.concat(findMDFile(filePath));
const subFiles = fs.readdirSync(filePath)
.map((subFile) => path.join(filePath, subFile));
mds = mds.concat(findMDFile(subFiles, shallow));
}
}
}, fs.readdirSync(dirPath));
}, filePaths);
return mds;
};
exports.isIndex = R.compose(R.equals('index.md'), R.unary(path.basename));
exports.isDemo = R.complement(exports.isIndex);
const MT = require('mark-twain');
exports.parseFileContent = R.pipe(

View File

@ -3,6 +3,7 @@ import classNames from 'classnames';
import { Row, Col, Icon } from '../../../';
import Demo from '../Demo';
import * as utils from '../utils';
import demosList from '../../../_site/data/demos-list';
export default class ComponentDoc extends React.Component {
constructor(props) {
@ -20,7 +21,8 @@ export default class ComponentDoc extends React.Component {
}
render() {
const { demos = [], doc } = this.props;
const { doc } = this.props;
const demos = demosList[doc.meta.fileName] || [];
const expand = this.state.expandAll;
const isSingleCol = doc.meta.cols === '1';

View File

@ -1,5 +1,7 @@
import React from 'react';
import { Collapse } from '../../../';
import ReactDOM from 'react-dom';
import antd, { Collapse } from '../../../';
import BrowserDemo from '../BrowserDemo';
import * as utils from '../utils';
import hljs from 'highlight.js';
@ -26,7 +28,7 @@ export default class Demo extends React.Component {
return (
<section className="code-box" id={id}>
<section className="code-box-demo">
{ preview() }
{ preview(React, ReactDOM, antd, BrowserDemo) }
{
!!style ?
<style dangerouslySetInnerHTML={{ __html: style }} /> :

View File

@ -5,7 +5,7 @@ const Option = Select.Option;
import './index.less';
import componentsList from '../../../_site/data/components-list';
import componentsList from '../../../_site/data/react-components';
export default class Header extends React.Component {
handleSearch(value) {
console.log(value);
@ -16,18 +16,18 @@ export default class Header extends React.Component {
const activeMenuItem = routes[1].path || 'home';
const options = [];
for (let key of Object.keys(componentsList)) {
componentsList[key].forEach((item) => {
const url = `/components/${item.english.toLowerCase()}`;
Object.keys(componentsList).map((key) => {
return componentsList[key];
}).forEach(({ meta }) => {
const url = `/components/${meta.english.toLowerCase()}`;
options.push(
<Option value={url} key={key}>
<strong>{item.english}</strong>
<span className="ant-component-decs">{item.chinese}</span>
</Option>
);
});
}
options.push(
<Option value={url} key={url}>
<strong>{meta.english}</strong>
<span className="ant-component-decs">{meta.chinese}</span>
</Option>
);
});
return (
<header id="header" className="clearfix">

View File

@ -1,77 +0,0 @@
import React from 'react';
import { Link } from 'react-router';
import { Row, Col, Menu } from '../../../';
import * as utils from '../utils';
import componentsList from '../../../_site/data/components-list';
const componentMenuItems = [];
['基本', '表单', '展示', '导航', '其它'].forEach((category) => {
const grandChildren = componentsList[category].map((item) => {
const key = item.english.toLowerCase();
return (
<Menu.Item key={key}>
<Link to={`/components/${key}`}>{item.english}<span className="chinese">{item.chinese}</span></Link>
</Menu.Item>
);
});
componentMenuItems.push(
<Menu.ItemGroup title={category} key={category} mode="vertical">
{ grandChildren }
</Menu.ItemGroup>
);
});
export default class ReactComponents extends React.Component {
getTopLevelMenuItems() {
return [
<Menu.Item key="introduce">
<Link to="/components/introduce">Ant Design of React</Link>
</Menu.Item>,
<Menu.Item key="getting-started">
<Link to="/components/getting-started">快速上手</Link>
</Menu.Item>,
<Menu.Item key="install">
<Link to="/components/install">安装</Link>
</Menu.Item>,
<Menu.Item key="upgrade-notes">
<Link to="/components/upgrade-notes">升级指南</Link>
</Menu.Item>,
<Menu.Item key="changelog">
<Link to="/components/changelog">更新日志</Link>
</Menu.Item>,
];
}
render() {
const activeMenuItem = utils.getActiveMenuItem(this.props, 'introduce');
const topLevelMenuItems = this.getTopLevelMenuItems();
const menuItems = topLevelMenuItems.concat(
utils.flattenMenu(componentMenuItems)
);
const { prev, next } = utils.getFooterNav(menuItems, activeMenuItem);
return (
<Row className="main-wrapper">
<Col span="4">
<Menu className="sidebar" mode="inline"
defaultOpenKeys={['components']}
selectedKeys={[activeMenuItem]}>
{ topLevelMenuItems }
<Menu.SubMenu title={<h4>Components</h4>} key="components">
{ componentMenuItems }
</Menu.SubMenu>
</Menu>
</Col>
<Col span="20" className="main-container">
{ this.props.children }
<section className="prev-next-nav">
{ !!prev ? React.cloneElement(prev.props.children, { className: 'prev-page' }) : null }
{ !!next ? React.cloneElement(next.props.children, { className: 'next-page' }) : null }
</section>
</Col>
</Row>
);
}
}

View File

@ -2,39 +2,24 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, hashHistory } from 'react-router';
import * as utils from './utils';
import '../common/lib';
import App from '../component/App';
import Home from '../component/Home';
import Article from '../component/Article';
import introduce from '../../_site/data/introduce';
import gettingStarted from '../../_site/data/getting-started';
import install from '../../_site/data/install';
import upgradeNotes from '../../_site/data/upgrade-notes';
import changelog from '../../_site/data/changelog';
import ReactComponents from '../component/ReactComponents';
import ComponentDoc from '../component/ComponentDoc';
import componentDocsList from '../../_site/data/component-docs-list';
import demosList from '../../_site/data/demos-list';
import practice from '../../_site/data/practice';
import pattern from '../../_site/data/pattern';
import reactComponents from '../../_site/data/react-components';
import spec from '../../_site/data/spec';
import resource from '../../_site/data/resource';
const Introduce = () => <Article content={introduce[0]} />;
const GettingStarted = () => <Article content={gettingStarted[0]} />;
const Install = () => <Article content={install[0]} />;
const UpgradeNotes = () => <Article content={upgradeNotes[0]} />;
const Changelog = () => <Article content={changelog[0]} />;
function addFileNameToMeta(data) {
Object.keys(data).forEach((key) => {
data[key].meta.fileName = key;
});
return data;
}
const demosListChildren = componentDocsList.map((componentDoc) => {
const key = componentDoc.meta.english.toLowerCase();
const ComponentDocWrapper =
() => <ComponentDoc doc={componentDoc} demos={demosList[key]} />;
return <Route path={key} component={ComponentDocWrapper} key={key} />;
});
const ReactComponents = utils.generateContainer('components', reactComponents);
const reactComponentsChildren = utils.generateChildren(addFileNameToMeta(reactComponents));
const Practice = utils.generateContainer('practice', practice);
const practiceChildren = utils.generateChildren(practice);
@ -43,7 +28,7 @@ const Pattern = utils.generateContainer('pattern', pattern);
const patternChildren = utils.generateChildren(pattern);
const Spec = utils.generateContainer('spec', spec);
const specChildren = utils.generateChildren(spec);
const specChildren = utils.generateChildren(addFileNameToMeta(spec));
const Resource = utils.generateContainer('resource', resource);
const resourceChildren = utils.generateChildren(resource);
@ -53,13 +38,7 @@ ReactDOM.render(
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="components" component={ReactComponents}>
<IndexRoute component={Introduce} />
<Route path="introduce" component={Introduce} />
<Route path="getting-started" component={GettingStarted} />
<Route path="install" component={Install} />
<Route path="upgrade-notes" component={UpgradeNotes} />
<Route path="changelog" component={Changelog} />
{ demosListChildren }
{ reactComponentsChildren }
</Route>
<Route path="practice" component={Practice}>
{ practiceChildren }

View File

@ -49,7 +49,7 @@ export function generateChildren(data) {
const children = pagesData.map((pageData, index) => {
const Wrapper = !pageData.meta.hasDemos ?
() => <Article content={pageData} /> :
() => <ComponentDoc doc={pageData} demos={pageData.demos} />;
() => <ComponentDoc doc={pageData} />;
return (
<Route key={index}
path={dashed(pageData.meta.english)}