front-build
Advanced tools
Comparing version 0.0.3 to 0.3.0
289
lib/app.js
@@ -1,28 +0,269 @@ | ||
var fs = require('fs'), | ||
path = require('path'), | ||
async = require('async'), | ||
getRoot = require('./getRoot'), | ||
page = require('./page'); | ||
var _ = require('underscore'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var fu = require('./fileutil'); | ||
var async = require('async'); | ||
exports.init = function (dir, cb) { | ||
//fb.json | ||
process.chdir(dir); | ||
var config = config || {}; | ||
async | ||
.series([ | ||
function(callback){ | ||
fs.writeFile(path.resolve(dir, 'fb.json'), JSON.stringify(config, null, 4), callback); | ||
}, | ||
function(callback){ | ||
async.map(['tools','docs'], fs.mkdir, callback); | ||
var Page = require('./page') | ||
/** | ||
* FB 应用 | ||
* @param {Object} cfg the app info | ||
* @return {[type]} [description] | ||
*/ | ||
var App = module.exports = function(cfg) { | ||
var self = this; | ||
self.rootDir = cfg.rootDir; | ||
self.workdir = cfg.workdir || ''; | ||
}; | ||
_.extend(App, { | ||
RootDirs: ['tools','docs','common', 'utils'], | ||
PageDirs: ['core', 'mods', 'test'], | ||
version: '0.03', | ||
FB_JSON_NAME: 'fb.json', | ||
versionReg: /^\d+\.\d+$/, | ||
timestampReg: /^\d{6+}$/, | ||
defaultConfig: { | ||
version: '0.03', | ||
charset: 'utf8' | ||
}, | ||
/** | ||
* 初始化项目根目录 | ||
* @param {String} dir target path | ||
* @param {Object} config default app config | ||
* @param {Function} callback callback with augment callback(error); | ||
* @return {[type]} [description] | ||
*/ | ||
init: function(dir, callback) { | ||
dir = path.resolve(dir); | ||
var json_path = path.resolve(dir, App.FB_JSON_NAME); | ||
App.getApp(dir, function(err, app) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
], function(err, results){ | ||
if(err) { | ||
return fb(err); | ||
if (app) { | ||
return callback(new Error('init error: only a frontbuild app;')); | ||
} | ||
console.log('file "fb.json" created'); | ||
console.log('dir "tools" created'); | ||
console.log('dir "docs" created'); | ||
cb(null); | ||
var app = new App({ | ||
rootDir: dir | ||
}); | ||
async.series([ | ||
function (callback) { | ||
//create directories | ||
async.forEach(App.RootDirs, function (p, callback) { | ||
var tPath = path.resolve(dir, p) | ||
path.exists(tPath, function (exist){ | ||
if (exist) { | ||
console.log('directorie exist: %s', p); | ||
return callback(null); | ||
} | ||
console.log('directorie created: %s', p); | ||
fs.mkdir(tPath, callback); | ||
}) | ||
}, callback); | ||
}, | ||
function (callback) { | ||
//json | ||
console.log('file "%s" created.', App.FB_JSON_NAME); | ||
app.saveConfig(callback); | ||
} | ||
], callback); | ||
}); | ||
}; | ||
}, | ||
/** | ||
* find the app rootDir by the fb.json file | ||
* from dir to up | ||
* @param {String} dir current path | ||
* @param {Function} callback callback with argument callback(error, app) | ||
*/ | ||
getApp: function(dir, callback) { | ||
function getRootSync(cPath) { | ||
var currentPath, | ||
nextPath = cPath, | ||
stat; | ||
do { | ||
currentPath = nextPath; | ||
try { | ||
stat = fs.statSync(path.resolve(currentPath,'fb.json'));; | ||
if (stat && stat.isFile) { | ||
return currentPath; | ||
} | ||
} catch (e) { | ||
} | ||
nextPath = path.join(currentPath, '..'); | ||
} while (currentPath !== nextPath); | ||
return null; | ||
} | ||
var workdir = path.resolve(dir), | ||
page = null, | ||
rootdir = getRootSync(workdir); | ||
if(!rootdir) { | ||
return callback(null); | ||
} | ||
try { | ||
var config = fu.readJSONSync(path.resolve(rootdir, 'fb.json')); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
var app = new App({ | ||
rootDir: rootdir, | ||
workdir: path.relative(rootdir, workdir) | ||
}); | ||
app.getConfig(function(err, json) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
callback(null, app); | ||
}); | ||
} | ||
}); | ||
_.extend(App.prototype, { | ||
/** | ||
* Add page to app | ||
* @param {String} pageName name of page | ||
* @param {Function} callback will be called with (error); | ||
*/ | ||
addPage: function(pageName, callback) { | ||
var self = this; | ||
//黑名单 | ||
var blacklist = _.extend([], App.RootDirs, App.PageDirs); | ||
if (blacklist.indexOf(pageName) != -1 ) { | ||
callback(new Error('App#addPage: name error')); | ||
return; | ||
} | ||
if (!pageName) { | ||
callback(new Error('App#addPage: Page Name is Not found.')); | ||
return; | ||
} | ||
var target = path.resolve(self.rootDir, pageName); | ||
if (!path.exists(target)) { | ||
console.log('page %s created', pageName); | ||
fs.mkdir(target, callback); | ||
} else { | ||
console.log('Page %s exists!', pageName); | ||
callback(null); | ||
} | ||
}, | ||
/** | ||
* 通过pagename 返回一个page | ||
* @return {Page} the target Page | ||
*/ | ||
getPage: function(pageName, callback){ | ||
var self = this; | ||
pageName = pageName || self.getCurrent().pageName; | ||
if (pageName) { | ||
page = new Page({ | ||
name: pageName, | ||
app: self, | ||
rootDir: path.resolve(self.rootDir, pageName) | ||
}); | ||
} else { | ||
return callback(new Error('Page#getPage: no page name;')); | ||
} | ||
return page; | ||
}, | ||
/** | ||
* 返回当前的工作的目录状态 | ||
* 如: 工作目录为 root/x/y/z 则 pageName 为 x, version 为 y | ||
* @return {Page} the target Page | ||
*/ | ||
getCurrent: function () { | ||
var self = this; | ||
var rel = self.workdir; | ||
var dirs; | ||
var current = {}; | ||
if(rel){ | ||
dirs = rel.replace('\\','/').split('/'); | ||
current.pageName = dirs[0]; | ||
if (dirs.length >= 2) { | ||
current.version = dirs[1]; | ||
} | ||
} | ||
return current; | ||
}, | ||
/** | ||
* build the common | ||
* @return {[type]} [description] | ||
*/ | ||
buildCommon: function (callback){ | ||
console.log('TODO: build common'); | ||
callback(); | ||
}, | ||
getConfig: function (callback) { | ||
var self = this; | ||
if (self.config) { | ||
return callback(null, self.config); | ||
} | ||
fu.readJSON(path.resolve(self.rootDir, App.FB_JSON_NAME), function (err, json) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
self.config = json; | ||
callback(null, json); | ||
}); | ||
}, | ||
saveConfig: function (callback) { | ||
var self = this; | ||
if (!self.config) { | ||
self.config = App.defaultConfig | ||
} | ||
var json_path = path.resolve(self.rootDir, App.FB_JSON_NAME); | ||
fu.writeJSON(json_path, self.config, callback); | ||
}, | ||
setGroup: function (groupName, pages, callback) { | ||
var self = this; | ||
self.config.groups = self.config.groups || {}; | ||
}, | ||
getGroup: function(groupName, callback) { | ||
var self = this; | ||
if (self.config.groups[groupName]) { | ||
callback(null, self.config.groups.groupName); | ||
} else { | ||
callback(null, null) | ||
} | ||
}, | ||
buildGroup: function(groupName, callback) { | ||
} | ||
}); |
450
lib/page.js
@@ -1,244 +0,286 @@ | ||
var fs = require('fs'), | ||
path = require('path'), | ||
async = require('async'), | ||
getRoot = require('./getRoot'), | ||
less = require('less'), | ||
build = require('./build'); | ||
var _ = require('underscore'); | ||
var iconv = require('iconv-lite'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var async = require('async'); | ||
var fu = require('./fileutil'); | ||
/** | ||
* add a Page to Project | ||
* @param {String} name name of page. | ||
* @param {Object} root project root info. | ||
* @param {String} cb pageName. | ||
* Page Class | ||
* @param {Object} cfg config | ||
* cfg.name {String} name of page | ||
* cfg.rootDir {String} source code | ||
* cfg.version {String} where builded source goto. | ||
* cfg.inputCharset {String} charset of source code | ||
* cfg.outputCharset {String} build charset. | ||
*/ | ||
exports.add = function(name, root, cb) { | ||
var Page = module.exports = function(cfg) { | ||
var self = this; | ||
self.app = cfg.app || null; | ||
self.name = cfg.name; | ||
if (!name) { | ||
throw new Error('Page Name is Not found.'); | ||
} | ||
if (!root) { | ||
throw new Error('NotFbProject'); | ||
return; | ||
} | ||
self.rootDir = path.resolve(cfg.rootDir); | ||
var target = path.resolve(root, name); | ||
self.config = { | ||
inputCharset: 'utf8', | ||
outputCharset: 'utf8' | ||
}; | ||
self._plugins = []; | ||
if (!path.exists(target)) { | ||
console.log('dir %s created', name); | ||
fs.mkdir(target, cb); | ||
}else { | ||
console.log('目录 %s 已存在', name); | ||
cb(); | ||
} | ||
}; | ||
self.srcDir = path.resolve(self.rootDir, Page.TEMP_SOURCE_NAME); | ||
self.destDir = path.resolve(self.rootDir, Page.destDir); | ||
self.charset = 'utf8'; | ||
/** | ||
* add new Version to Project | ||
* @param {Object} argv the cli argments. | ||
* @param {Object} root project info. | ||
* @param {Function} cb callback function. | ||
*/ | ||
exports.version = function(argv, root, cb) { | ||
} | ||
if (!root.page) { | ||
console.error('不在Page文件夹内!') | ||
process.exit(3); | ||
} | ||
if (argv._.length < 2 || !argv._[1]) { | ||
console.error("必须指定一个version: fb version {version}") | ||
process.exit(3); | ||
} | ||
_.extend(Page, { | ||
TEMP_SOURCE_NAME: 'page_src_temp', | ||
destDir: 'page_build_temp', | ||
JSON_NAME: 'fb.page.json', | ||
BUILD_JSON_NAME: 'build.json', | ||
DIRS: ['core', 'mods', 'test'] | ||
}); | ||
if (!/^(\d+\.)+\d+$/.test(argv._[1])) { | ||
console.error("{version} 格式错误。期望的格式是 [0.]+0;") | ||
process.exit(3); | ||
} | ||
_.extend(Page.prototype, { | ||
var version = argv._[1], | ||
page_dir = path.resolve(root.dir, root.page.name); | ||
console.log('add new version [%s] to Page [%s]', version, root.page.name); | ||
addVersion: function (version, callback) { | ||
var self = this; | ||
if (!self.rootDir) { | ||
console.error('不在Page文件夹内!') | ||
return callback(new Error('Page#addVersion: no page')); | ||
} | ||
if (!version) { | ||
console.error("必须指定一个version: fb version {version}") | ||
process.exit(3); | ||
} | ||
try { | ||
fs.mkdirSync(path.resolve(page_dir, version)); | ||
if (!/^(\d+\.)+\d+$/.test(version)) { | ||
console.error("version 格式错误。期望的格式是 1.0") | ||
return callback(new Error('version not illegal')); | ||
} | ||
['core', 'mods', 'utils'].forEach(function(name){ | ||
fs.mkdirSync(path.resolve(page_dir, version, name)); | ||
}); | ||
} catch (e) { | ||
console.error('fail to create directory'); | ||
cb(e); | ||
} | ||
cb(null); | ||
}; | ||
var versionDir = self.versionDir = path.resolve(self.rootDir, version); | ||
/** | ||
* list files in directory by RegExp | ||
* @param {RegExp} reg extname of file. | ||
* @param {Array} dir list of files to filter on. | ||
* @return {Array} files list match. | ||
*/ | ||
var pageInfo = { | ||
name: self.name, | ||
version: version | ||
}; | ||
async.series([ | ||
function (callback) { | ||
// mkdir pageRoot | ||
path.exists(versionDir, function (exist) { | ||
if (exist) { | ||
console.error('Page#addVersion: version %s is already existed', version); | ||
return callback(new Error('Page#addVersion: versionDir is already exist;')) | ||
} | ||
fs.mkdir(versionDir, callback); | ||
}); | ||
}, | ||
function filterFile(reg, dir) { | ||
function (callback) { | ||
//mkdir s | ||
async.forEach( | ||
Page.DIRS, | ||
function (name, callback){ | ||
fs.mkdir(path.resolve(versionDir, name), callback) | ||
}, | ||
callback | ||
); | ||
}, | ||
var list = fs.readdirSync(dir); | ||
function (callback) { | ||
//write config json | ||
fu.writeJSON(path.resolve(versionDir, Page.JSON_NAME), self.config, callback); | ||
}, | ||
var files = list | ||
.map(function(file) { | ||
return path.resolve(dir, file); | ||
}) | ||
.filter(function(file) { | ||
function (callback) { | ||
//write sh file | ||
var sh_path = path.resolve(versionDir, 'fb-build.sh'); | ||
var shTemplate = _.template('#!/bin/sh\n\ | ||
fb build <%= name%>@<%= version%> -t 000000'); | ||
fs.writeFile(sh_path, shTemplate(pageInfo), function (err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
fs.chmod(sh_path, '0777', callback); | ||
}); | ||
}, | ||
if (reg.test(file) && fs.statSync(file).isFile()) { | ||
return true; | ||
function (callback) { | ||
//write bat file | ||
var bat_path = path.resolve(versionDir, 'fb-build.bat'); | ||
var batTemplete = _.template('fb build <%= name%>@<%= version%> -t 000000') | ||
fs.writeFile(bat_path, batTemplete(pageInfo), callback); | ||
} | ||
return false; | ||
], callback); | ||
}, | ||
/** | ||
* Page can build only after setVersion | ||
* @param {Function} callback with (null) | ||
* @return {[type]} [description] | ||
*/ | ||
setVersion: function (version, callback) { | ||
var self = this; | ||
self.version = version; | ||
self.name_version = self.name + '@' + self.version; | ||
self.versionDir = path.resolve(self.rootDir, self.version); | ||
path.exists(self.versionDir, function(exist){ | ||
if (!exist) { | ||
return callback(new Error('Page#setVersion: ' + self.name + '@' + version +' is not exist')); | ||
} | ||
fu.readJSON(path.resolve(self.versionDir, Page.JSON_NAME), function (err, json) { | ||
if (!err && json) { | ||
_.extend(self.config, json); | ||
} | ||
self.input_charset = self.config.inputCharset || self.charset; | ||
self.output_charset = self.config.outputCharset || self.charset; | ||
self._loadPlugins(callback); | ||
}); | ||
}); | ||
}, | ||
return files; | ||
} | ||
_loadPlugins: function(callback) { | ||
var self = this; | ||
function mkdirp(abspath) { | ||
// console.log('[mkdirp]', abspath); | ||
var dirs = []; | ||
while (!path.existsSync(abspath)) { | ||
// console.log('abspath %s not exists', abspath); | ||
dirs.push(abspath); | ||
abspath = path.join(abspath, '..'); | ||
// console.log('upto %s', abspath) | ||
} | ||
// console.log('[mkdirp]', dirs); | ||
dirs.reverse().forEach(function(dir) { | ||
fs.mkdirSync(dir); | ||
}); | ||
} | ||
/** | ||
* map file name with RegExp | ||
* @param {String} file filename | ||
* @param {RegExp} reg 正则表达式. | ||
* @param {String} replace 替换. | ||
* @return {String} 替换后的file path | ||
*/ | ||
function fileMap(file, reg, replace) { | ||
return file.replace(reg, replace); | ||
} | ||
self.use(require('./plugins/module-compiler')()); | ||
self.use(require('./plugins/css-combo')()); | ||
self.use(require('./plugins/lesscss')()); | ||
self.use(require('./plugins/concat')()); | ||
self.use(require('./plugins/uglifyjs')()); | ||
self.use(require('./plugins/cssmin')()); | ||
callback(null); | ||
}, | ||
function writeConfig(path, json){ | ||
fs.writeFileSync(path, JSON.stringify(json, null, 2), 'utf-8'); | ||
}; | ||
/** | ||
* fb build -v 1.0 -t 20120513 | ||
* @param {Object} argv parsed argv object. | ||
* @param {Object} root root Object. | ||
*/ | ||
build: function(timestamp, callback) { | ||
var self = this; | ||
if (!self.version) { | ||
return callback(new Error('Page#build: version is not setted; ')); | ||
} | ||
exports.build = function(root, cb) { | ||
var page = root.page; | ||
var rootdir = root.dir; | ||
if (!timestamp) { | ||
return callback(new Error('Page#build: timestamp missing')) | ||
} | ||
if (!page.version) { | ||
console.log('必须指定打包的版本,示例 -v 1.0'); | ||
process.exit(2); | ||
} | ||
if (!page.timestamp) { | ||
console.log('必须指定打包的时间戳目录, 示例 -t 20120501'); | ||
process.exit(2); | ||
} | ||
self.timestamp = timestamp; | ||
self.timestampDir = path.resolve(self.rootDir, timestamp.toString()); | ||
var startTime = new Date(); | ||
console.log('building page: %s@%s to %s', | ||
page.name, | ||
page.version, | ||
page.timestamp); | ||
async.series([ | ||
function (callback){ | ||
//准备工作 | ||
self._startBuild(callback); | ||
}, | ||
function (callback){ | ||
self._build(callback); | ||
}, | ||
function (callback) { | ||
//扫尾工作 | ||
self._endBuild(startTime, callback); | ||
}, | ||
var page_dir = path.resolve(rootdir, page.name); | ||
var vertion_dir = path.join(page_dir, page.version); | ||
var version_core = path.join(vertion_dir, 'core'); | ||
var build_dir = path.join(page_dir, page.timestamp); | ||
var build_core = path.join(build_dir, 'core'); | ||
], callback); | ||
}, | ||
if (!path.existsSync(version_core)) { | ||
console.log('没有找到 core 目录, 打包中止.'); | ||
process.exit(3); | ||
} | ||
_build: function(callback) { | ||
var self = this; | ||
async.forEachSeries(self._plugins, function(plugin, callback) { | ||
plugin(self, callback); | ||
}, callback); | ||
}, | ||
var files = fs.readdirSync(version_core); | ||
_startBuild: function(callback) { | ||
var self = this; | ||
async.auto({ | ||
//init the build directory | ||
init: function(done) { | ||
console.log('building %s to %s', self.name_version, self.timestamp); | ||
if (!path.existsSync(build_dir)) { | ||
mkdirp(path.join(build_dir, 'core')); | ||
return done(null); | ||
} | ||
done(null); | ||
}, | ||
//parse less files | ||
less: ['init', function(done) { | ||
var lessfiles = filterFile(/\.less$/i, version_core), | ||
jobs = []; | ||
lessfiles.forEach(function(file) { | ||
//file.replace(/\.less$/i, '.css') | ||
var filepath = path.relative(version_core, file), | ||
output = fileMap(path.resolve(build_core, filepath), /\.less/i, '.css'); | ||
jobs.push({ | ||
target: path.resolve(version_core, file), | ||
output: output | ||
}); | ||
}); | ||
async.forEach( | ||
jobs, | ||
build.lessbuild, | ||
done | ||
); | ||
}], | ||
// make tempdir | ||
async.series([ | ||
function (callback) { | ||
//make temp src and dest dirs | ||
async.forEach( | ||
[self.srcDir, self.destDir], | ||
self._makeTempDir, | ||
callback | ||
); | ||
}, | ||
// | ||
kissybuild: ['init', function(done) { | ||
build.kissybuild({ | ||
target: 'core', | ||
base: vertion_dir, | ||
inputEncoding: 'utf-8', | ||
outputEncoding: 'utf-8', | ||
output: build_dir | ||
}, done); | ||
}], | ||
function (callback) { | ||
//copy and conv charset from version to src dir | ||
try { | ||
fu.iconvDir(self.versionDir, self.input_charset, self.srcDir, self.charset); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
callback(); | ||
}, | ||
// | ||
compress: ['kissybuild', function(done) { | ||
var files = filterFile(/\.combine\.js$/, build_core), | ||
jobs = []; | ||
function (callback) { | ||
//create timestamp dir | ||
var timestampDirs = [self.timestampDir, path.resolve(self.timestampDir, 'core')]; | ||
files.forEach(function(file) { | ||
var from = path.resolve(build_core, file), | ||
output = path.resolve(build_core, | ||
file.replace(/\.combine\.js$/, '.js')); | ||
fs.renameSync(from, output); | ||
async.forEachSeries(timestampDirs, function (p, callback){ | ||
path.exists(p, function (exist){ | ||
if (exist) { | ||
return callback(); | ||
} | ||
jobs.push({ | ||
target: output, | ||
output: output.replace(/\.js$/, '-min.js') | ||
}); | ||
}); | ||
fs.mkdir(p, callback); | ||
}); | ||
async.forEach(jobs, build.uglifyjs, done); | ||
}], | ||
}, callback); | ||
}, | ||
], callback); | ||
}, | ||
update: ['compress', function(done){ | ||
writeConfig(path.resolve(build_dir, 'build.json'), { | ||
pagename: page.name, | ||
version: page.version, | ||
buildDate: new(Date) | ||
}); | ||
}] | ||
}, function(err) { | ||
if (err) { | ||
console.log('build fail'); | ||
process.exit(3); | ||
_endBuild: function(startTime, callback) { | ||
console.log('build end'); | ||
var self = this; | ||
// change charset to target charset and move to target | ||
fu.iconvDir(self.destDir, self.charset, self.timestampDir, self.output_charset); | ||
// remove tempdir | ||
[self.srcDir, self.destDir].forEach(function(dir) { | ||
fu.rmTreeSync(dir); | ||
}); | ||
fu.writeJSON(path.resolve(self.timestampDir, Page.BUILD_JSON_NAME), { | ||
build_version: self.version, | ||
build_time: new Date().toString(), | ||
build_used_time: new Date().getTime() - startTime.getTime() | ||
}, callback); | ||
}, | ||
_makeTempDir: function(dir_name, callback) { | ||
if (path.existsSync(dir_name)) { | ||
fu.rmTreeSync(dir_name); | ||
} | ||
console.log('all done!'); | ||
}); | ||
}; | ||
fs.mkdir(dir_name, callback); | ||
}, | ||
/** | ||
* add plugin to Page | ||
* @param {Object} plugin the Page Plugins | ||
* @return {[type]} [description] | ||
*/ | ||
use: function(plugin) { | ||
var self = this; | ||
if (typeof plugin !== 'function') { | ||
return; | ||
} | ||
self._plugins.push(plugin); | ||
} | ||
}); |
@@ -5,3 +5,3 @@ { | ||
"description": "build front project", | ||
"version": "0.0.3", | ||
"version": "0.3.0", | ||
"repository": { | ||
@@ -24,7 +24,9 @@ "type": "git", | ||
"async": "~0.1.18", | ||
"tbuild": "~0.2.0", | ||
"tbuild": "~0.3.2", | ||
"less": "~1.3.0", | ||
"uglify-js": "~1.2.6" | ||
"uglify-js": "~1.2.6", | ||
"iconv-lite": "~0.2.0", | ||
"underscore": "~1.3.3" | ||
}, | ||
"devDependencies": {} | ||
} | ||
} |
175
README.md
# Front-Build | ||
- 约定高于配置 | ||
- 面向前端 | ||
- 基于目录规范 | ||
- 自动化打包 | ||
- 零配置 | ||
## 目录 | ||
### Root | ||
### Common | ||
### Page 目录 | ||
### Version 目录 | ||
#### core | ||
#### mods | ||
#### utils | ||
### Build 目录 | ||
## 目录规范 | ||
```` | ||
- app // root of app | ||
├ common // 通用脚本与样式, 可直接引用,独立打包 | ||
├ utils // 通用组件, 使用时打包入page使用, 一般不单独引用 | ||
│ ├ countdown | ||
│ │ ├ index.js | ||
│ │ └ countdown-mod.js | ||
│ └ text-formater | ||
├ homepage // page 目录 | ||
│ ├ 1.0 // page 版本 目录 | ||
│ │ ├ test // 测试用例 目录 | ||
│ │ ├ core // page 的入口文件目录, 打包,引用的入口 | ||
│ │ │ ├ base.js | ||
│ │ │ ├ style1.css | ||
│ │ │ └ style2.less | ||
│ │ ├ mods // page的模块目录 | ||
│ │ │ ├ mod1.js | ||
│ │ │ ├ mod2.js | ||
│ │ │ ├ mod3.js | ||
│ │ │ ├ mod1.css | ||
│ │ │ └ mod2.css | ||
│ │ ├ fb-build.sh // 打包快捷方式 | ||
│ │ ├ fb-build.bat // 打包快捷方式 | ||
│ │ └ fb.page.json // page 相关配置 | ||
│ └ 20121221 // 打包后的时间戳目录 | ||
│ ├ build.json // 打包信息 | ||
│ └ core // 打包只处理core目录,生成-min.js 的压缩版本 | ||
│ ├ base.js | ||
│ ├ base-min.js | ||
│ ├ style1.css | ||
│ ├ style1-min.css | ||
│ ├ style2.css | ||
│ └ style2-min.css | ||
└ fb.json // 应用的配置 | ||
```` | ||
## FB如何构建你的代码 | ||
### page | ||
#### 特点 | ||
- 基于时间戳目录 | ||
- 从入口文件(core 目录)开始 | ||
- 支持编码设置 | ||
#### fb使用以下步骤构建 | ||
1. 创建目录 临时src (page.srcDir); 临时build (page.destDir); timestame目录 | ||
2. 将版本目录里面的文件,转成utf8编码, 并全部拷贝到 src 目录 | ||
3. 使用内置插件系统 | ||
1. module-compiler: KISSY的模块打包, 从src/core/xx.js -> build/core/xx.js | ||
2. css-combo: css打包, 从src/core/xx.css -> build/core/xx.css | ||
3. lesscss: 打包, 从 src/core/xx.less -> build/core/xx.less.css | ||
4. concat: 根据配置合并文件 | ||
5. uglifyjs: build/core/xx.js -> build/core/xx-min.js | ||
6. cssmin: build/core/xx.css -> build/core/xx-min.css | ||
4. 将build下的所有文件转码到outpuCharse,并复制到timestamp目录 | ||
5. 在timestamp 目录下生成 包含打包信息的 build.json. | ||
### common | ||
1. 创建目录: 临时src (common.srcDir); 临时build (common.destDir); | ||
2. 将common目录里面源码文件,转成utf8编码, 并全部拷贝到 src 目录 | ||
3. 使用内置插件系统 | ||
1. module-compiler: KISSY的模块打包压缩, 从src/xx.index.js -> build/xx.index-minjs | ||
2. lesscss: 打包, 从 src/xx.less -> build/core/xx.less.css | ||
3. uglifyjs: build/xx.js -> build/xx-min.js | ||
4. cssmin: build/xx.css -> build/xx-min.css | ||
4. 将最终压缩文件 build/xx-min.yy 文件从 utf-8 转码到 outpuCharse,并复制回 common | ||
5. 在timestamp 目录下生成 包含打包信息的 build.json. | ||
TODO | ||
### utils | ||
TODO | ||
## 安装 | ||
- 首先安装nodejs环境 (and npm); | ||
- npm install front-build | ||
- done! | ||
## 兼容性 | ||
1. 首先安装nodejs环境 (and npm); | ||
2. npm install front-build -g; | ||
3. done! | ||
## 用法 | ||
## 快速开始 | ||
### fb init | ||
初始化一个项目文件夹, 只有在Root目录里才能执行下面的命令 | ||
初始化一个应用 | ||
### fb add {pagename} | ||
创建一个Page | ||
初始化一个项目文件夹为Root | ||
````sh | ||
cd dir/to/app | ||
fb init | ||
```` | ||
### fb version {versionNumber} | ||
在page文件夹里面执行 | ||
为当前Page 创建一个version | ||
创建一个 Page | ||
### fb build {pagename} -v {version} -t {timestame} | ||
打包{version} 目录 {timestamp} 目录 | ||
在应用里面创建一个Page。在应用目录内执行 | ||
会自动编译core 目录下面的less 文件到 打包目录的 core目录 | ||
会自动打包core目录下的kissy1.2入口文件到core目录, 并生成一个-min.js压缩版 | ||
````sh | ||
fb build -t {timestamp} | ||
fb add name_of_page | ||
```` | ||
## Bug | ||
为Page创建一个 Version | ||
在page文件夹里面执行, 为当前Page 创建一个version | ||
````sh | ||
fb version version_of_your_page | ||
```` | ||
or | ||
````sh | ||
fb ver 1.0 | ||
```` | ||
### 构建 | ||
单个page构建 | ||
````sh | ||
fb build {pagename}@{version} -t {timestame} | ||
```` | ||
sample: | ||
````sh | ||
fb build about@1.0 -t 20120601 | ||
```` | ||
构建所有页面 | ||
````sh | ||
fb build all -t 20121221 | ||
```` | ||
同时构建多个page | ||
````sh | ||
fb build pagea@1.0 pageb@2.0 pagec@1.0 -t 20121221 | ||
```` | ||
common 目录构建 | ||
````sh | ||
fb build common | ||
```` | ||
## Bugs | ||
## 兼容性 |
@@ -1,1 +0,12 @@ | ||
{} | ||
{ | ||
"version": "0.03", | ||
"groups": { | ||
"all": [ | ||
"page1@1.0" | ||
], | ||
"_g1": [ | ||
"page2@2.0", | ||
"page1@1.0" | ||
] | ||
} | ||
} |
@@ -5,2 +5,2 @@ KISSY.add(function(){ | ||
requires: ['../mods/submod1.js'] | ||
}); | ||
}); |
KISSY.add(function(){ | ||
var a = 'mods:submod1.js'; | ||
}); | ||
var a = 'mods:submod1'; | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
85613
78
2227
162
7
11
1
+ Addediconv-lite@~0.2.0
+ Addedunderscore@~1.3.3
+ Addedajv@6.12.6(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasync@0.9.2(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcolors@1.4.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addedcss-combo@0.5.5(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addediconv-lite@0.2.11(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedlodash@3.10.1(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpsl@1.15.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedtbuild@0.3.6(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addedunderscore@1.3.3(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removediconv-lite@0.6.3(transitive)
- Removedtbuild@0.2.1(transitive)
Updatedtbuild@~0.3.2