New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

front-build

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

front-build - npm Package Compare versions

Comparing version 0.0.3 to 0.3.0

docs/faq.md

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": {}
}
}
# 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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc