mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
chore: add build scripts
This commit is contained in:
parent
45e9b304dc
commit
fc86a4164d
@ -105,10 +105,12 @@
|
||||
"less-loader": "^2.2.0",
|
||||
"lesshint-antd": "^1.2.1",
|
||||
"lodash": "^4.1.0",
|
||||
"mark-twain": "^0.2.0-beta",
|
||||
"nico-jsx": "~0.8.2",
|
||||
"postcss-loader": "^0.8.0",
|
||||
"pre-commit": "1.x",
|
||||
"querystring": "^0.2.0",
|
||||
"ramda": "^0.19.1",
|
||||
"rc-scroll-anim": "^0.1.7",
|
||||
"rc-tween-one": "^0.1.8",
|
||||
"react": "0.14.x",
|
||||
@ -117,6 +119,7 @@
|
||||
"react-dom": "0.14.x",
|
||||
"react-router": "^2.0.0",
|
||||
"react-stateless-wrapper": "~1.0.2",
|
||||
"recast": "^0.11.2",
|
||||
"reqwest": "~2.0.5",
|
||||
"semver": "^5.1.0",
|
||||
"values.js": "^1.0.3",
|
||||
@ -127,7 +130,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"babel": "babel components index.js --out-dir lib",
|
||||
"start": "dora -p 8001 --plugins atool-build?config=webpack.website.config.js",
|
||||
"start": "npm run clean && ./scripts/build-website.js && dora -p 8001 --plugins atool-build?config=webpack.website.config.js",
|
||||
"clean": "rm -rf _site dist",
|
||||
"site": "npm run clean && webpack --config webpack.deploy.config.js && webpack --config webpack.antd.config.js && NODE_ENV=PRODUCTION nico build",
|
||||
"deploy": "rm -rf node_modules && node scripts/install.js && npm run just-deploy",
|
||||
|
20
scripts/build-components-list.js
Normal file
20
scripts/build-components-list.js
Normal file
@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const R = require('ramda');
|
||||
const utils = require('./utils');
|
||||
|
||||
module.exports = function buildComponentsList(indexes, outputPath) {
|
||||
const componentMetas = R.map((fileName) => {
|
||||
const fileContent = utils.parseFileContent(fileName);
|
||||
return utils.parseMeta(fileContent);
|
||||
}, indexes);
|
||||
|
||||
const groupByType = R.groupBy(R.compose(R.defaultTo('其它'), R.prop('type')));
|
||||
const componentsList = groupByType(componentMetas);
|
||||
|
||||
const content = 'module.exports = ' +
|
||||
JSON.stringify(componentsList, null, 2) + ';';
|
||||
|
||||
fs.writeFile(outputPath, content);
|
||||
};
|
70
scripts/build-demos-list.js
Normal file
70
scripts/build-demos-list.js
Normal file
@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const R = require('ramda');
|
||||
const devil = require('./devil'); // TODO: extract as a module?
|
||||
const utils = require('./utils');
|
||||
|
||||
const stringify = function stringify(data, d) {
|
||||
const depth = d || 1;
|
||||
const indent = ' '.repeat(depth);
|
||||
let output = '';
|
||||
if (Array.isArray(data)) {
|
||||
output += '[\n';
|
||||
data.forEach((item) => output += indent + stringify(item, depth + 1) + ',\n');
|
||||
output += indent + ']';
|
||||
} else if (typeof data === 'object') {
|
||||
output += '{\n';
|
||||
for (const key of Object.keys(data)) {
|
||||
output += indent + JSON.stringify(key) + ': ' + stringify(data[key], depth + 1) + ',\n';
|
||||
}
|
||||
output += indent + '}';
|
||||
} else if (typeof data === 'function') {
|
||||
output += data.toString();
|
||||
} else if (typeof data === 'string') {
|
||||
output += JSON.stringify(data);
|
||||
} else {
|
||||
output += data;
|
||||
}
|
||||
return output
|
||||
.replace(/var _antd = require\(['"]antd['"]\);/, '')
|
||||
.replace(/require\('antd\/lib/, 'require(\'../../components'); // TODO
|
||||
};
|
||||
|
||||
const isIntro = function isIntro(element) {
|
||||
const type = element.type;
|
||||
return type !== 'h1' && type !== 'ul' && type !== 'code' && type !== 'hr';
|
||||
};
|
||||
const isCode = R.whereEq({ type: 'code', props: { lang: 'jsx' } });
|
||||
const isStyle = R.whereEq({ type: 'code', props: { lang: 'css' } });
|
||||
const getChildren = R.compose(R.prop('children'), R.defaultTo({}));
|
||||
const sortByOrder = R.sortBy(R.prop('order'));
|
||||
module.exports = function buildDemosList(demoList, outputPath) {
|
||||
const demos = R.map((fileName) => {
|
||||
const data = utils.parseFileContent(fileName);
|
||||
const parts = fileName.split(path.sep);
|
||||
|
||||
const demo = {};
|
||||
demo.order = parseInt(utils.parseMeta(data).order);
|
||||
demo.parent = parts[parts.indexOf('components') + 1];
|
||||
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.style = getChildren(data.find(isStyle));
|
||||
|
||||
return demo;
|
||||
}, demoList);
|
||||
|
||||
const demosList = R.groupBy((demo) => demo.parent.replace('-', ''), demos);
|
||||
const sortedDemosList = R.mapObjIndexed(sortByOrder, demosList);
|
||||
const content = 'const React = require(\'react\');\n' +
|
||||
'const ReactDOM = require(\'react-dom\');\n' +
|
||||
'const _antd = require(\'../../\');\n' +
|
||||
'module.exports = ' +
|
||||
stringify(sortedDemosList, null, 2) + ';';
|
||||
|
||||
fs.writeFile(outputPath, content);
|
||||
};
|
26
scripts/build-docs-list.js
Normal file
26
scripts/build-docs-list.js
Normal file
@ -0,0 +1,26 @@
|
||||
'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);
|
||||
};
|
77
scripts/build-website.js
Executable file
77
scripts/build-website.js
Executable file
@ -0,0 +1,77 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
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');
|
||||
|
||||
// Ensure that data directory exist.
|
||||
try {
|
||||
fs.statSync('./_site');
|
||||
} catch (e) {
|
||||
fs.mkdir('./_site');
|
||||
}
|
||||
try {
|
||||
fs.statSync('./_site/data');
|
||||
} catch (e) {
|
||||
fs.mkdir('./_site/data');
|
||||
}
|
||||
|
||||
// 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);
|
||||
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');
|
||||
|
||||
const downloadPath = './docs/resource/download.md';
|
||||
buildDocsList([downloadPath], './_site/data/download.js')
|
||||
|
||||
const referencePath =
|
||||
'./docs/resource/reference.md';
|
||||
buildDocsList([referencePath], './_site/data/reference.js')
|
||||
|
||||
const specIntroPath =
|
||||
'./docs/spec/introduce.md'
|
||||
buildDocsList([specIntroPath], './_site/data/specIntro.js');
|
||||
|
||||
const fontPath =
|
||||
'./docs/spec/font.md'
|
||||
buildDocsList([fontPath], './_site/data/font.js');
|
||||
|
||||
const typographyPath =
|
||||
'./docs/spec/typography.md'
|
||||
buildDocsList([typographyPath], './_site/data/typography.js');
|
||||
|
||||
const easingPath =
|
||||
'./docs/spec/easing.md'
|
||||
buildDocsList([easingPath], './_site/data/easing.js');
|
||||
const pageTransitionPath =
|
||||
'./docs/spec/page-transition.md'
|
||||
buildDocsList([pageTransitionPath], './_site/data/page-transition.js');
|
||||
const motionPath =
|
||||
'./docs/spec/motion.md'
|
||||
buildDocsList([motionPath], './_site/data/motion.js');
|
31
scripts/devil.js
Normal file
31
scripts/devil.js
Normal file
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const babel = require('babel-core');
|
||||
const recast = require('recast');
|
||||
const builders = recast.types.builders;
|
||||
|
||||
const babelrc = {
|
||||
presets: ['es2015', 'react']
|
||||
};
|
||||
|
||||
// const demo = 'import { Button } from \'antd\';' +
|
||||
// 'ReactDOM.render(<div>' +
|
||||
// ' <Button type="primary">主按钮</Button>' +
|
||||
// ' <Button>次按钮</Button>' +
|
||||
// ' <Button type="ghost">幽灵按钮</Button>' +
|
||||
// '</div>,' +
|
||||
// 'document.getElementById(\'components-button-demo-basic\'));';
|
||||
// devil(demo);
|
||||
module.exports = function devil(demo, params) {
|
||||
const compiled = babel.transform(demo, babelrc).code;
|
||||
|
||||
const ast = recast.parse(compiled);
|
||||
const astProgramBody = ast.program.body;
|
||||
const lastIndex = astProgramBody.length - 1;
|
||||
astProgramBody[lastIndex] = builders.returnStatement(
|
||||
astProgramBody[lastIndex].expression.arguments[0]
|
||||
);
|
||||
|
||||
const code = recast.print(ast).code;
|
||||
return new Function((params || []).join(', '), code);
|
||||
}
|
47
scripts/utils.js
Normal file
47
scripts/utils.js
Normal file
@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const R = require('ramda');
|
||||
|
||||
const isMDFile = R.compose(R.equals('.md'), path.extname);
|
||||
exports.findMDFile = function findMDFile(dirPath) {
|
||||
let mds = [];
|
||||
|
||||
R.forEach((fileName) => {
|
||||
const filePath = path.join(dirPath, fileName);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isFile() && isMDFile(filePath)) {
|
||||
mds.push(filePath);
|
||||
}
|
||||
if (stat.isDirectory()) {
|
||||
mds = mds.concat(findMDFile(filePath));
|
||||
}
|
||||
}, fs.readdirSync(dirPath));
|
||||
|
||||
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(
|
||||
fs.readFileSync,
|
||||
R.toString,
|
||||
MT,
|
||||
R.prop('content')
|
||||
);
|
||||
|
||||
const parseBasicMeta = R.pipe(
|
||||
R.path(['1', 'children']),
|
||||
R.map((child) => R.split(/:\s?/, child.children[0].children)),
|
||||
R.fromPairs
|
||||
);
|
||||
const parseEnglishTitle = R.path(['0', 'children']);
|
||||
exports.parseMeta = function parseMeta(fileContent) {
|
||||
const meta = parseBasicMeta(fileContent);
|
||||
meta.english = parseEnglishTitle(fileContent);
|
||||
meta.title = `${meta.english} ${meta.chinese || ''}`;
|
||||
|
||||
return meta;
|
||||
};
|
Loading…
Reference in New Issue
Block a user