apollo-nico
Version:
对 nico 及 apollo-theme 的封装,方便跨平台使用
311 lines (258 loc) • 8.46 kB
JavaScript
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
exports.init = function(name){
var cwd = process.cwd();
// var cwd = 'D:/workspace/apollo/apollo-nico/apollo-nico/htdocs/css/6v/apollo/mod/notice';
var isCreate = false;
var buildType = 'css';
// 如果有输入 name 的时候,先创建 name 目录
if(name){
var dir = path.join(cwd, name);
if(!fs.existsSync(dir)){
fs.mkdirSync(dir);
isCreate = true;
}
process.chdir(dir);
cwd = process.cwd();
}
//test codes
var pkg = path2obj(cwd);
// 有效性校验
if(!pkg){
console.log('The path "' + cwd + '" is invalid!');
if(isCreate && dir){
process.chdir('..');
fs.rmdirSync(dir);
}
return;
}
// 创建并获取 dev 目录,同时新建一堆文件
var devDir = createDev(cwd, pkg, buildType,pkg.platform);
var mainIntrance = require('../../bin/apollo-nico');
// 运行apollo-nico,并启动浏览器
mainIntrance.server();//这里采用了对象启动,不采用命令行启动了
/*
console.log('apollo server is running!');
exec('apollo-nico', {
cwd: devDir
});*/
};
//----------------------写默认的目录结构及文件------------------------//
var beautify = require('js-beautify').js_beautify;
var files = {
js : ['{{name}}.js','_dev/package.json', '_dev/README.md', '_dev/HISTORY.md', '_dev/examples/index.md', '_dev/src/{{name}}.js', '_dev/tests/{{name}}-spec.js'],
css : ['{{name}}-sc.css','{{name}}-ws.css','package.json','README.md','HISTORY.md','_src/common/{{name}}-base.css','_src/theme/alibaba/{{name}}.css','_src/theme/aliexpress/{{name}}.css','_examples/alibaba/{{name}}.md','_examples/aliexpress/{{name}}.md']
};
var mobileFiles = {
css : ['{{name}}.css','_src/_{{name}}.scss','_src/_variables.scss','_src/_mixins.scss','package.json','README.md','HISTORY.md','_examples/{{name}}-example.html']
}
var mobileDirs = {
css : ['_src','_examples']
}
var dirs = {
js : ['_dev','_dev/examples', '_dev/tests', '_dev/src'],
css : ['_src','_examples','_src/common','_src/theme','_src/theme/alibaba','_src/theme/aliexpress','_examples/alibaba','_examples/aliexpress']
};
// 缓存好 bridge 字符串
var bridge = fs.readFileSync(path.join(__dirname, 'bridge.js')).toString();
// 创建dev目录
function createDev(cwd, pkg, buildType,platform){
//var devDir = cwd.indexOf('_dev') == -1 ? path.join(cwd, '_dev') : cwd;
/*
// 创建 _dev 目录
if(!fs.existsSync(devDir)){
fs.mkdirSync(devDir);
}
// 创建 bridge
createBridge(devDir, pkg);
*/
// 创建 默认的dir
createDevDir(cwd, buildType,platform);
// 创建 默认的file
createDevFile(cwd, pkg, buildType,platform);
if(buildType === 'js') {
return cwd.indexOf('_dev') == -1 ? path.join(cwd, '_dev') : cwd;
} else if(buildType === 'css') {
return cwd;
}
}
/*
// 创建 bridge
function createBridge(devDir, pkg){
var name = pkg.name;
var bridgeFile = path.join(devDir, '..', name + '.js');
var content = bridge.replace('{{name}}', name);
if(!fs.existsSync(bridgeFile)){
fs.writeFileSync(bridgeFile, content);
}
}
*/
// 创建 默认的dir
function createDevDir(root, buildType,platform){
var d = platform=='mobile'?mobileDirs:dirs;
d[buildType].forEach(function(dir){
dir = path.join(root, dir);
// 创建 _dev 目录
if(!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
});
}
// 创建 默认的file
function createDevFile(root, pkg, buildType,platform){
var file = platform=='mobile'?mobileFiles:files;
file[buildType].forEach(function(file){
var content = '';
var modName = pkg.name;
var uName = ucfirst(modName);
switch(file){
case 'package.json':
content = beautify(JSON.stringify(pkg));
break;
case 'README.md':
content = ['# {{name}}', '- order: 1', '---', '---','## 依赖','## 示例']
.join('\r\n\r\n')
.replace('{{name}}', uName);
break;
case 'examples/alibaba/{{name}}.md'.replace('{{name}}',uName):
case 'examples/aliexpress/{{name}}.md'.replace('{{name}}',uName):
content = ['# {{name}}', '- order: 1', '---']
.join('\r\n\r\n')
.replace('{{name}}', uName);
break;
case 'HISTORY.md':
content = ['# {{name}}', '\r\n---', '## 1.0.0', '正式版']
.join('\r\n')
.replace('{{name}}', uName);
break;
case '_src/_{{name}}.scss':
content = ['@charset "utf-8";','\r\n','/*','*@name : '+modName,' *@description :', '*@author : ','*@require : core',' *@version : ','*@modifyTime :','*/','\r\n','//global variables and mixins scss','//-----------------------------------------------------','@import "../../core/_mixins.scss";','@import "../../core/_variables.scss";','\r\n','// '+modName+' variables and mixins scss','//-----------------------------------------------------','@import "_variables.scss";','@import "_mixins.scss";']
.join('\r\n')
.replace('{{name}}', modName);
break;
case '{{name}}.css':
content = ['/* #require "_src/'+modName+'.css" */'];
break;
default :
break;
}
file = path.join(root, file.replace('{{name}}', pkg.name));
// 创建 _dev 目录
if(!fs.existsSync(file)){
fs.writeFileSync(file, content);
}
});
}
function ucfirst(str) {
return str.charAt(0).toUpperCase() + str.substring(1);
}
//----------------------根据路径计算出package obj------------------------//
var dPkg = require('./default.json');
// 'xxxxx/js/6v/nnn/mmm/xxx' -> 'nnn/mmm/xxx'
// 'xxxxx/css/6v/nnn/mmm/xxx' -> 'nnn/mmm/xxx'
//mobile\css\3v\apollo\core
var pathExp = /[a-z0-9\-\_\/]+[js|css]\/6v\/([a-z0-9\-\_\/]+)$/;
var mobilePathExp = /mobile\/(?:js|css)\/3v\/([a-z0-9\-\_\/]+)$/
// 将当前 path 转换为 结构化的 obj
// path 从 css/6v 之后的内容开始截取
// {
// "family": "",
// "name": "",
// "keywords": [],
// "homepage": "",
// "spm": {
// "output": []
// },
// "tests": []
// }
function path2obj(cwd ){
cwd = normalizePath(cwd);
var arr = [],isMobile = false;
if (cwd.indexOf('mobile') !== -1) {
isMobile = true;
// 提取出 css/6v 之后的部分
if (mobilePathExp.test(cwd)) {
arr = RegExp.$1.split('/');
}
} else {
// 提取出 css/6v 之后的部分
if (pathExp.test(cwd)) {
arr = RegExp.$1.split('/');
}
}
// 提取有问题
if(!arr.length){
return null;
}
var root,
family,
name,
type = 'mod';
console.log('arr:'+arr);
switch((root = arr.shift())){
case 'apollo': // [core, mod]
switch((apolloRoot = arr.shift())){
case 'core':
family = 'core';
name = arr.shift();
type = 'apollo core';
break;
case 'mod':
var tmp = arr.shift();
if(tmp !== 'assets') {
family = 'mod';
name = tmp;
type = 'apollo mod';
} else {
family = 'assets';
name = arr.shift();
type = 'apollo mod assets';
}
break;
default:
return null;
}
break;
case 'run':
family = arr.shift();
name = arr.shift();
type = 'run';
break;
default:
return null;
}
// 保证肯定有family和name
if(!family || !name){
return null;
}
// 如果是更深的目录也是不可接受的
if((arr[0] && arr[0] != '_dev') || arr.length > 5){
return null;
}
// 开始回写对象
var ret = JSON.parse(JSON.stringify(dPkg));
ret.family = family;
ret.name = name;
ret.keywords.push(type);
ret.homepage = 'http://apollo.alif2e.com/' + family + '/' + name + '/';
//自动引入模块css的相对路径
if(isMobile){
ret.modURL = 'mobile/css/3v/apollo/'+ family + '/' + name + '/' + name +'-sc.css';
ret.platform = 'mobile';
}else{
ret.platform = 'pc'
ret.modURL = 'css/6v/apollo/'+ family + '/' + name + '/' + name +'-sc.css';
}
ret.atomSc = 'js/6v/atom/atom-sc.js';
ret.spm.output.push(name + '.css');
ret.tests.push(name);
return ret;
}
exports.path2obj = path2obj;
//-----------helper
// 屏蔽 windows 与 linux 的路径差异
function normalizePath(path){
return path.replace(/\\/g, '/');
}
//----------------------根据路径计算出package obj end!------------------------//