mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-29 04:35:36 +08:00
Initial version of the website and docs.
This commit is contained in:
117
website/server/convert.js
Normal file
117
website/server/convert.js
Normal file
@@ -0,0 +1,117 @@
|
||||
var fs = require('fs')
|
||||
var glob = require('glob');
|
||||
var mkdirp = require('mkdirp');
|
||||
var optimist = require('optimist');
|
||||
var path = require('path');
|
||||
var argv = optimist.argv;
|
||||
|
||||
function splitHeader(content) {
|
||||
var lines = content.split('\n');
|
||||
for (var i = 1; i < lines.length - 1; ++i) {
|
||||
if (lines[i] === '---') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
header: lines.slice(1, i + 1).join('\n'),
|
||||
content: lines.slice(i + 1).join('\n')
|
||||
};
|
||||
}
|
||||
|
||||
function backtickify(str) {
|
||||
var escaped = '`' + str.replace(/\\/g, '\\\\').replace(/`/g, '\\`') + '`';
|
||||
// Replace require( with require\( so node-haste doesn't replace example
|
||||
// require calls in the docs
|
||||
return escaped.replace(/require\(/g, 'require\\(');
|
||||
}
|
||||
|
||||
function execute() {
|
||||
var MD_DIR = '../docs/';
|
||||
|
||||
glob('src/react-native/docs/*.*', function(er, files) {
|
||||
files.forEach(function(file) {
|
||||
try {
|
||||
fs.unlinkSync(file);
|
||||
} catch(e) {
|
||||
/* seriously, unlink throws when the file doesn't exist :( */
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var metadatas = {
|
||||
files: [],
|
||||
};
|
||||
|
||||
glob(MD_DIR + '**/*.*', function (er, files) {
|
||||
files.forEach(function(file) {
|
||||
var extension = path.extname(file);
|
||||
if (extension === '.md' || extension === '.markdown') {
|
||||
var content = fs.readFileSync(file, {encoding: 'utf8'});
|
||||
var metadata = {};
|
||||
|
||||
// Extract markdown metadata header
|
||||
var both = splitHeader(content);
|
||||
var lines = both.header.split('\n');
|
||||
for (var i = 0; i < lines.length - 1; ++i) {
|
||||
var keyvalue = lines[i].split(':');
|
||||
var key = keyvalue[0].trim();
|
||||
var value = keyvalue.slice(1).join(':').trim();
|
||||
// Handle the case where you have "Community #10"
|
||||
try { value = JSON.parse(value); } catch(e) { }
|
||||
metadata[key] = value;
|
||||
}
|
||||
metadatas.files.push(metadata);
|
||||
|
||||
if (metadata.permalink.match(/^https?:/)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a dummy .js version that just calls the associated layout
|
||||
var layout = metadata.layout[0].toUpperCase() + metadata.layout.substr(1) + 'Layout';
|
||||
|
||||
var content = (
|
||||
'/**\n' +
|
||||
' * @generated\n' +
|
||||
' * @jsx React.DOM\n' +
|
||||
' */\n' +
|
||||
'var React = require("React");\n' +
|
||||
'var layout = require("' + layout + '");\n' +
|
||||
'var content = ' + backtickify(both.content) + '\n' +
|
||||
'var Post = React.createClass({\n' +
|
||||
' render: function() {\n' +
|
||||
' return layout({metadata: ' + JSON.stringify(metadata) + '}, content);\n' +
|
||||
' }\n' +
|
||||
'});\n' +
|
||||
// TODO: Use React statics after upgrading React
|
||||
'Post.content = content;\n' +
|
||||
'module.exports = Post;\n'
|
||||
);
|
||||
|
||||
var targetFile = 'src/react-native/' + metadata.permalink.replace(/\.html$/, '.js');
|
||||
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), ''));
|
||||
fs.writeFileSync(targetFile, content);
|
||||
}
|
||||
|
||||
if (extension === '.json') {
|
||||
var content = fs.readFileSync(file, {encoding: 'utf8'});
|
||||
metadatas[path.basename(file, '.json')] = JSON.parse(content);
|
||||
}
|
||||
});
|
||||
|
||||
fs.writeFileSync(
|
||||
'core/metadata.js',
|
||||
'/**\n' +
|
||||
' * @generated\n' +
|
||||
' * @providesModule Metadata\n' +
|
||||
' */\n' +
|
||||
'module.exports = ' + JSON.stringify(metadatas, null, 2) + ';'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (argv.convert) {
|
||||
console.log('convert!')
|
||||
execute();
|
||||
}
|
||||
|
||||
module.exports = execute;
|
||||
61
website/server/generate.js
Normal file
61
website/server/generate.js
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
var request = require('request');
|
||||
var glob = require('glob');
|
||||
var fs = require('fs.extra');
|
||||
var mkdirp = require('mkdirp');
|
||||
var server = require('./server.js');
|
||||
|
||||
// Sadly, our setup fatals when doing multiple concurrent requests
|
||||
// I don't have the time to dig into why, it's easier to just serialize
|
||||
// requests.
|
||||
var queue = (function() {
|
||||
var is_executing = false;
|
||||
var queue = [];
|
||||
function push(fn) {
|
||||
queue.push(fn);
|
||||
execute();
|
||||
}
|
||||
function execute() {
|
||||
if (is_executing) {
|
||||
return;
|
||||
}
|
||||
if (queue.length === 0) {
|
||||
return;
|
||||
}
|
||||
var fn = queue.shift();
|
||||
is_executing = true;
|
||||
fn(function() {
|
||||
is_executing = false;
|
||||
execute()
|
||||
});
|
||||
}
|
||||
return {push: push};
|
||||
})();
|
||||
|
||||
glob('src/**/*.*', function(er, files) {
|
||||
files.forEach(function(file) {
|
||||
var targetFile = file.replace(/^src/, 'build');
|
||||
|
||||
if (file.match(/\.js$/)) {
|
||||
targetFile = targetFile.replace(/\.js$/, '.html');
|
||||
queue.push(function(cb) {
|
||||
request('http://localhost:8079/' + targetFile.replace(/^build\//, ''), function(error, response, body) {
|
||||
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), ''));
|
||||
fs.writeFileSync(targetFile, body);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
queue.push(function(cb) {
|
||||
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), ''));
|
||||
fs.copy(file, targetFile, cb);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
queue.push(function(cb) {
|
||||
server.close();
|
||||
console.log('It is live at: http://facebook.github.io/react-native/')
|
||||
cb();
|
||||
});
|
||||
});
|
||||
53
website/server/server.js
Normal file
53
website/server/server.js
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
var connect = require('connect');
|
||||
var http = require('http');
|
||||
var optimist = require('optimist');
|
||||
var path = require('path');
|
||||
var reactMiddleware = require('react-page-middleware');
|
||||
var convert = require('./convert.js');
|
||||
|
||||
var argv = optimist.argv;
|
||||
|
||||
var PROJECT_ROOT = path.resolve(__dirname, '..');
|
||||
var FILE_SERVE_ROOT = path.join(PROJECT_ROOT, 'src');
|
||||
|
||||
var port = argv.port;
|
||||
if (argv.$0 === 'node ./server/generate.js') {
|
||||
// Using a different port so that you can publish the website
|
||||
// and keeping the server up at the same time.
|
||||
port = 8079;
|
||||
}
|
||||
|
||||
var buildOptions = {
|
||||
projectRoot: PROJECT_ROOT,
|
||||
pageRouteRoot: FILE_SERVE_ROOT,
|
||||
useBrowserBuiltins: false,
|
||||
logTiming: true,
|
||||
useSourceMaps: true,
|
||||
ignorePaths: function(p) {
|
||||
return p.indexOf('__tests__') !== -1;
|
||||
},
|
||||
serverRender: true,
|
||||
dev: argv.dev !== 'false',
|
||||
static: true
|
||||
};
|
||||
|
||||
var app = connect()
|
||||
.use(function(req, res, next) {
|
||||
// convert all the md files on every request. This is not optimal
|
||||
// but fast enough that we don't really need to care right now.
|
||||
convert();
|
||||
next();
|
||||
})
|
||||
.use(reactMiddleware.provide(buildOptions))
|
||||
.use(connect['static'](FILE_SERVE_ROOT))
|
||||
.use(connect.favicon(path.join(FILE_SERVE_ROOT, 'elements', 'favicon', 'favicon.ico')))
|
||||
.use(connect.logger())
|
||||
.use(connect.compress())
|
||||
.use(connect.errorHandler());
|
||||
|
||||
var portToUse = port || 8080;
|
||||
var server = http.createServer(app);
|
||||
server.listen(portToUse);
|
||||
console.log('Open http://localhost:' + portToUse + '/react-native/index.html');
|
||||
module.exports = server;
|
||||
Reference in New Issue
Block a user