mirror of https://gitee.com/antv-l7/antv-l7
185 lines
6.0 KiB
JavaScript
185 lines
6.0 KiB
JavaScript
|
process.env.DEBUG = 'app:*';
|
||
|
const debug = require('debug')('app:demos');
|
||
|
const commander = require('commander');
|
||
|
const connect = require('connect');
|
||
|
const getPort = require('get-port');
|
||
|
const http = require('http');
|
||
|
const open = require('open');
|
||
|
const serveStatic = require('serve-static');
|
||
|
const bodyParser = require('body-parser');
|
||
|
const parseurl = require('parseurl');
|
||
|
const url = require('url');
|
||
|
const assign = require('lodash').assign;
|
||
|
const path = require('path');
|
||
|
const resolve = path.resolve;
|
||
|
const join = path.join;
|
||
|
const fs = require('fs');
|
||
|
const JSZip = require('jszip');
|
||
|
const readFileSync = fs.readFileSync;
|
||
|
const writeFileSync = fs.writeFileSync;
|
||
|
const nunjucks = require('nunjucks');
|
||
|
const renderString = nunjucks.renderString;
|
||
|
const shelljs = require('shelljs');
|
||
|
const webpack = require('webpack');
|
||
|
const webpackConfig = require('../webpack.config');
|
||
|
const pkg = require('../package.json');
|
||
|
const blocks = require('./data/blocks.json');
|
||
|
const template = require('./data/template');
|
||
|
|
||
|
shelljs.config.execPath = shelljs.which('node');
|
||
|
|
||
|
commander
|
||
|
.version(pkg.version)
|
||
|
.option('-w, --web')
|
||
|
.option('-p, --port <port>', 'specify a port number to run on', parseInt)
|
||
|
.parse(process.argv);
|
||
|
|
||
|
function startService(port) {
|
||
|
const server = connect();
|
||
|
server
|
||
|
.use(bodyParser.urlencoded({
|
||
|
extended: true
|
||
|
}))
|
||
|
.use((req, res, next) => { // pre-handlers
|
||
|
const urlInfo = url.parse(req.url, true);
|
||
|
const query = urlInfo.query || {};
|
||
|
const body = req.body || {};
|
||
|
|
||
|
req._urlInfo = urlInfo;
|
||
|
req._pathname = urlInfo.pathname;
|
||
|
|
||
|
// add req._params (combination of query and body)
|
||
|
const params = Object.assign({}, query, body);
|
||
|
req._params = params;
|
||
|
req._query = query;
|
||
|
req._body = body;
|
||
|
|
||
|
res._sendRes = (str, contentType) => {
|
||
|
const buf = new Buffer(str);
|
||
|
contentType = contentType || 'text/html;charset=utf-8';
|
||
|
res.setHeader('Content-Type', contentType);
|
||
|
res.setHeader('Content-Length', buf.length);
|
||
|
res.end(buf);
|
||
|
};
|
||
|
// res._JSONRes(data) (generate JSON response)
|
||
|
res._JSONRes = data => {
|
||
|
res._sendRes(JSON.stringify(data), 'application/json;charset=utf-8');
|
||
|
};
|
||
|
// TODO res._JSONError()
|
||
|
// res._HTMLRes(data) (generate HTML response)
|
||
|
res._HTMLRes = res._sendRes;
|
||
|
|
||
|
return next();
|
||
|
})
|
||
|
.use((req, res, next) => {
|
||
|
const pathname = parseurl(req).pathname;
|
||
|
if (req.method === 'GET') {
|
||
|
if (pathname === '/bundler/index.html') {
|
||
|
res.end(renderString(readFileSync(join(__dirname, './index.njk'), 'utf8'), {
|
||
|
blocks
|
||
|
}));
|
||
|
} else {
|
||
|
next();
|
||
|
}
|
||
|
} else if (req.method === 'POST') {
|
||
|
if (pathname === '/bundle') {
|
||
|
// step1: prepare entry __index.js
|
||
|
const entryPath = resolve(process.cwd(), './src/__index.js');
|
||
|
const ids = req.body.ids.map(id => parseInt(id, 10));
|
||
|
const codeBlocks = blocks
|
||
|
.filter((item, index) => ids.indexOf(index) !== -1)
|
||
|
.map(item => item.code)
|
||
|
.join('\n');
|
||
|
const entryFileContent = template(codeBlocks);
|
||
|
writeFileSync(entryPath, template(codeBlocks), 'utf8');
|
||
|
// step2: build it
|
||
|
const distPath = resolve(process.cwd(), './__dist');
|
||
|
shelljs.rm('-rf', distPath);
|
||
|
shelljs.mkdir('-p', distPath);
|
||
|
const config = Object.assign({}, webpackConfig);
|
||
|
config.entry = {
|
||
|
g2: './src/__index.js'
|
||
|
};
|
||
|
config.output.path = distPath;
|
||
|
webpack(config, (err, stats) => {
|
||
|
// shelljs.rm(entryPath);
|
||
|
if (err || stats.hasErrors()) {
|
||
|
// Handle errors here
|
||
|
// shelljs.rm('-rf', distPath);
|
||
|
shelljs.rm(entryPath);
|
||
|
shelljs.rm('-rf', distPath);
|
||
|
}
|
||
|
// step3: uglify
|
||
|
shelljs.exec('uglifyjs -c -m -o __dist/g2.min.js -- __dist/g2.js');
|
||
|
// step4: zipping it
|
||
|
const zip = new JSZip();
|
||
|
zip.folder('g2-dist').file('entry.js', entryFileContent);
|
||
|
zip.folder('g2-dist').file('g2.js', readFileSync(join(distPath, './g2.js'), 'utf8'));
|
||
|
zip.folder('g2-dist').file('g2.js.map', readFileSync(join(distPath, './g2.js.map'), 'utf8'));
|
||
|
zip.folder('g2-dist').file('g2.min.js', readFileSync(join(distPath, './g2.min.js'), 'utf8'));
|
||
|
res.writeHead(200, {
|
||
|
'Content-Type': 'application/zip'
|
||
|
});
|
||
|
zip
|
||
|
.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
|
||
|
.pipe(res)
|
||
|
.on('finish', function() {
|
||
|
// step5: clear up
|
||
|
shelljs.rm(entryPath);
|
||
|
shelljs.rm('-rf', distPath);
|
||
|
res.end();
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
next();
|
||
|
}
|
||
|
});
|
||
|
server.use(serveStatic(process.cwd()));
|
||
|
http.createServer(server).listen(port);
|
||
|
|
||
|
const urlPath = `http://127.0.0.1:${port}/bundler/index.html`;
|
||
|
debug(`server started, bundler available! ${urlPath}`);
|
||
|
|
||
|
if (commander.web) {
|
||
|
debug('running on web!');
|
||
|
open(urlPath);
|
||
|
} else {
|
||
|
debug('running on electron!');
|
||
|
const app = require('electron').app;
|
||
|
const BrowserWindow = require('electron').BrowserWindow;
|
||
|
const windowBoundsConfig = require('torchjs/lib/windowBoundsConfig')(
|
||
|
resolve(app.getPath('userData'), './g2-bundler-config.json')
|
||
|
);
|
||
|
|
||
|
let win;
|
||
|
app.once('ready', () => {
|
||
|
win = new BrowserWindow(assign({
|
||
|
// transparent: true
|
||
|
webPreferences: {
|
||
|
nodeIntegration: false
|
||
|
}
|
||
|
}, windowBoundsConfig.get('bundler')));
|
||
|
win.loadURL(urlPath);
|
||
|
|
||
|
win.on('close', () => {
|
||
|
windowBoundsConfig.set('bundler', win.getBounds());
|
||
|
});
|
||
|
win.on('closed', () => {
|
||
|
win = null;
|
||
|
});
|
||
|
});
|
||
|
app.on('window-all-closed', () => {
|
||
|
app.quit();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (commander.port) {
|
||
|
startService(commander.port);
|
||
|
} else {
|
||
|
getPort().then(port => {
|
||
|
startService(port);
|
||
|
});
|
||
|
}
|