mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
chore: add build scripts
This commit is contained in:
parent
45e9b304dc
commit
fc86a4164d
@ -105,10 +105,12 @@
|
|||||||
"less-loader": "^2.2.0",
|
"less-loader": "^2.2.0",
|
||||||
"lesshint-antd": "^1.2.1",
|
"lesshint-antd": "^1.2.1",
|
||||||
"lodash": "^4.1.0",
|
"lodash": "^4.1.0",
|
||||||
|
"mark-twain": "^0.2.0-beta",
|
||||||
"nico-jsx": "~0.8.2",
|
"nico-jsx": "~0.8.2",
|
||||||
"postcss-loader": "^0.8.0",
|
"postcss-loader": "^0.8.0",
|
||||||
"pre-commit": "1.x",
|
"pre-commit": "1.x",
|
||||||
"querystring": "^0.2.0",
|
"querystring": "^0.2.0",
|
||||||
|
"ramda": "^0.19.1",
|
||||||
"rc-scroll-anim": "^0.1.7",
|
"rc-scroll-anim": "^0.1.7",
|
||||||
"rc-tween-one": "^0.1.8",
|
"rc-tween-one": "^0.1.8",
|
||||||
"react": "0.14.x",
|
"react": "0.14.x",
|
||||||
@ -117,6 +119,7 @@
|
|||||||
"react-dom": "0.14.x",
|
"react-dom": "0.14.x",
|
||||||
"react-router": "^2.0.0",
|
"react-router": "^2.0.0",
|
||||||
"react-stateless-wrapper": "~1.0.2",
|
"react-stateless-wrapper": "~1.0.2",
|
||||||
|
"recast": "^0.11.2",
|
||||||
"reqwest": "~2.0.5",
|
"reqwest": "~2.0.5",
|
||||||
"semver": "^5.1.0",
|
"semver": "^5.1.0",
|
||||||
"values.js": "^1.0.3",
|
"values.js": "^1.0.3",
|
||||||
@ -127,7 +130,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"babel": "babel components index.js --out-dir lib",
|
"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",
|
"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",
|
"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",
|
"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