binhend 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -2
- package/src/binh.web.builder.js +44 -35
- package/src/code.js +139 -83
- package/src/component.build.js +22 -7
- package/src/component.js +2 -1
- package/test.js +22 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "binhend",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Nguyen Duc Binh",
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"example-web2": "node example_web2"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"express": "^4.17.1"
|
|
18
|
+
"express": "^4.17.1",
|
|
19
|
+
"js-beautify": "^1.15.1",
|
|
20
|
+
"uglify-js": "^3.17.4",
|
|
21
|
+
"uglifycss": "^0.0.29"
|
|
19
22
|
},
|
|
20
23
|
"engines": {
|
|
21
24
|
"node": ">=16.17.1",
|
package/src/binh.web.builder.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
3
4
|
|
|
4
5
|
const Component = require('./component');
|
|
5
6
|
const ComponentFormat = require('./component.format');
|
|
6
7
|
const ComponentBuild = require('./component.build');
|
|
7
8
|
|
|
9
|
+
const UglifyCSS = require('uglifycss');
|
|
10
|
+
|
|
8
11
|
function WebBuilder(binh, Binh) {
|
|
9
12
|
binh.context = function(module, defaultRequire) {
|
|
10
13
|
var context = { module, require: defaultRequire };
|
|
@@ -44,14 +47,24 @@ function WebBuilder(binh, Binh) {
|
|
|
44
47
|
var component = ui || service || style;
|
|
45
48
|
var type = ui && 'ui' || service && 'service' || style && 'style';
|
|
46
49
|
|
|
47
|
-
if (component
|
|
50
|
+
if (!(component instanceof Function)) return;
|
|
48
51
|
|
|
49
52
|
context.component = component;
|
|
53
|
+
|
|
54
|
+
var module = context.module;
|
|
55
|
+
module.exports = component;
|
|
56
|
+
|
|
57
|
+
component.module = module;
|
|
58
|
+
component.constructor = Component;
|
|
59
|
+
component.filename = module.filename;
|
|
60
|
+
component.type = type;
|
|
61
|
+
|
|
50
62
|
component.htmltags = [];
|
|
51
63
|
component.links = [];
|
|
52
64
|
component.options = { csses: [] };
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
component.vars = {};
|
|
66
|
+
component.varname = getVariableName(component.filename);
|
|
67
|
+
component.as = alias;
|
|
55
68
|
};
|
|
56
69
|
|
|
57
70
|
binh.final = function(module) {
|
|
@@ -60,62 +73,58 @@ function WebBuilder(binh, Binh) {
|
|
|
60
73
|
if (!(component instanceof Function)) return;
|
|
61
74
|
if (component && component.constructor !== Component) return;
|
|
62
75
|
|
|
63
|
-
module.children
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
if (
|
|
67
|
-
component.vars[
|
|
76
|
+
for (var index in module.children) {
|
|
77
|
+
var dependency = module.children[index].exports;
|
|
78
|
+
if (dependency.constructor !== Component) continue;
|
|
79
|
+
if (dependency.alias) {
|
|
80
|
+
component.vars[dependency.filename] = dependency.alias;
|
|
68
81
|
}
|
|
69
|
-
}
|
|
82
|
+
}
|
|
70
83
|
};
|
|
71
84
|
|
|
72
85
|
binh.ui = function(module, component, htmltags, links) {
|
|
86
|
+
binh.component({ module }, component);
|
|
73
87
|
component.htmltags = htmltags;
|
|
74
88
|
component.links = links;
|
|
75
|
-
binh.
|
|
89
|
+
binh.final(module);
|
|
76
90
|
};
|
|
77
91
|
|
|
78
92
|
binh.service = function(module, component, links) {
|
|
93
|
+
binh.component({ module }, null, component, null);
|
|
79
94
|
component.links = links;
|
|
80
|
-
binh.
|
|
95
|
+
binh.final(module);
|
|
81
96
|
};
|
|
82
97
|
|
|
83
98
|
binh.style = function(module, component) {
|
|
84
|
-
binh.
|
|
99
|
+
binh.component({ module }, null, null, component);
|
|
100
|
+
binh.final(module);
|
|
85
101
|
};
|
|
86
102
|
|
|
87
103
|
binh.css = function(module, cssFilename) {
|
|
88
104
|
var cssFilePath = cssFilename && path.join(module.path, cssFilename) || module.filename.replace(/.js$/, '');
|
|
89
|
-
var content =
|
|
90
|
-
content =
|
|
91
|
-
var component = new Function(`return ${JSON.stringify(content)};`);
|
|
92
|
-
binh.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
binh.bundle = function(type, module, component) {
|
|
96
|
-
if (!(component instanceof Function)) return;
|
|
97
|
-
|
|
98
|
-
component.type = type;
|
|
99
|
-
component.filename = module.filename;
|
|
100
|
-
component.constructor = Component;
|
|
101
|
-
component.module = module;
|
|
102
|
-
component.as = alias;
|
|
103
|
-
component.vars = {};
|
|
104
|
-
|
|
105
|
-
module.exports = component;
|
|
106
|
-
|
|
107
|
-
module.children.forEach(function(child) {
|
|
108
|
-
child = child.exports;
|
|
109
|
-
if (child.constructor !== Component) return;
|
|
110
|
-
if (child.alias) component.vars[child.filename] = child.alias;
|
|
111
|
-
});
|
|
105
|
+
var content = fs.readFileSync(cssFilePath, { encoding: 'utf8', flag: 'r' });
|
|
106
|
+
content = UglifyCSS.processString(content);
|
|
107
|
+
var component = new Function(`return function style() { return ${JSON.stringify(content)}; };`)();
|
|
108
|
+
binh.component({ module }, null, null, component);
|
|
109
|
+
binh.final(module);
|
|
112
110
|
};
|
|
113
111
|
|
|
114
112
|
function alias(name) {
|
|
113
|
+
if (!isString(name)) return this;
|
|
114
|
+
name = name.trim();
|
|
115
115
|
this.alias = name;
|
|
116
116
|
return this;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
function getVariableName(filePath) {
|
|
120
|
+
return path.parse(filePath).name.replace(/-/g, '').replace(/\W.*/, '').trim();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
Binh.minify = function(flag = true) {
|
|
124
|
+
Component.minification = flag;
|
|
125
|
+
return Binh;
|
|
126
|
+
};
|
|
127
|
+
|
|
119
128
|
Binh.web = function(webPath, sourcePath, modulePath) {
|
|
120
129
|
switch (arguments.length) {
|
|
121
130
|
case 1:
|
package/src/code.js
CHANGED
|
@@ -1,138 +1,194 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
function getCodeOfDependencies(component, rootPath, metadata) {
|
|
3
|
+
var global = metadata || {};
|
|
4
|
+
var local = getMetadataOfDependencies(component, rootPath);
|
|
5
|
+
var codes = [], filenames = Object.keys(local);
|
|
3
6
|
|
|
4
|
-
function
|
|
5
|
-
|
|
7
|
+
filenames.forEach(function(filename) {
|
|
8
|
+
var existed = global[filename];
|
|
9
|
+
|
|
10
|
+
if (existed) return;
|
|
11
|
+
|
|
12
|
+
var { type, url, dependency } = local[filename];
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
var dependencyDelaration = getDependencyDelaration(dependency, rootPath);
|
|
15
|
+
var componentCode = dependency.toString();
|
|
16
|
+
var optionCode = generateOptionCode(dependency, '', rootPath);
|
|
17
|
+
var htmlTagDeclaration = getHtmlTagDeclaration(dependency);
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
|
|
19
|
+
if (dependencyDelaration) {
|
|
20
|
+
componentCode = componentCode.replace('{', `{\r\n${dependencyDelaration}`);
|
|
21
|
+
}
|
|
11
22
|
|
|
12
|
-
|
|
23
|
+
var blockCodes = [];
|
|
24
|
+
blockCodes.push(`Binh.${type}('${url}', ${type})${optionCode};`);
|
|
25
|
+
if (htmlTagDeclaration) {
|
|
26
|
+
blockCodes.push(htmlTagDeclaration);
|
|
27
|
+
}
|
|
28
|
+
blockCodes.push(componentCode);
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
codes.push(IIF(blockCodes));
|
|
31
|
+
codes.push('');
|
|
15
32
|
|
|
16
|
-
|
|
33
|
+
global[filename] = local[filename];
|
|
34
|
+
});
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var length = nodeModulePaths.length;
|
|
36
|
+
filenames.forEach(function(filename) {
|
|
37
|
+
var { dependency } = local[filename];
|
|
38
|
+
var codeOfDependencies = getCodeOfDependencies(dependency, rootPath, global);
|
|
39
|
+
if (codeOfDependencies) codes.push(codeOfDependencies);
|
|
40
|
+
});
|
|
24
41
|
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
return codes.join('\r\n');
|
|
43
|
+
}
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
function getDependencyDelaration(component, rootPath) {
|
|
46
|
+
var dependencies = getMetadataOfDependencies(component, rootPath);
|
|
47
|
+
var codes = [];
|
|
48
|
+
|
|
49
|
+
for (var filePath in dependencies) {
|
|
50
|
+
var { name, url, type } = dependencies[filePath];
|
|
51
|
+
if (name) {
|
|
52
|
+
codes.push(` ${name} = Binh.${type}('${url}')`);
|
|
33
53
|
}
|
|
54
|
+
}
|
|
34
55
|
|
|
35
|
-
|
|
56
|
+
var declarationCode = codes.join(',');
|
|
36
57
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
type: child.type,
|
|
40
|
-
component: child
|
|
41
|
-
};
|
|
42
|
-
});
|
|
58
|
+
codes = [];
|
|
59
|
+
codes.push(`var Binh = _Binh;`);
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
existed = global[filename];
|
|
61
|
+
if (declarationCode) {
|
|
62
|
+
codes.push(`var${declarationCode};`);
|
|
63
|
+
}
|
|
48
64
|
|
|
49
|
-
|
|
65
|
+
codes.push('');
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
variables[name] = true;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
declaration += `${name} = Binh.${type}('${url}', ${component.toString()});\r\n`;
|
|
57
|
-
global[filename] = local[filename];
|
|
58
|
-
variables[name] = true;
|
|
59
|
-
};
|
|
67
|
+
return codes.join('\r\n');
|
|
68
|
+
}
|
|
60
69
|
|
|
61
|
-
|
|
70
|
+
function getMetadataOfDependencies(component, rootPath) {
|
|
71
|
+
if (component.dependencies) return component.dependencies;
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
declaration += `Binh.later(function() {${optionCode};});\r\n`;
|
|
65
|
-
}
|
|
73
|
+
var dependencies = component.module.children;
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
dependencies(component, root, Object.assign({}, global, local)),
|
|
69
|
-
declaration
|
|
70
|
-
]);
|
|
75
|
+
component.dependencies = {};
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
dependencies.forEach(function(module) {
|
|
78
|
+
var dependency = module.exports;
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
if (dependency.constructor !== component.constructor) return;
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
var filename = dependency.filename;
|
|
83
|
+
var name = component.vars[filename] || dependency.varname;
|
|
84
|
+
var url = getRelativeFilePath(filename, rootPath);
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
component.dependencies[filename] = {
|
|
87
|
+
name, url, dependency,
|
|
88
|
+
type: dependency.type
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return component.dependencies;
|
|
82
93
|
}
|
|
83
94
|
|
|
84
|
-
function
|
|
85
|
-
var options = component.options,
|
|
95
|
+
function generateOptionCode(component, varname, rootPath) {
|
|
96
|
+
var options = component.options, urls = [];
|
|
86
97
|
|
|
87
98
|
if (!options) return '';
|
|
88
99
|
|
|
89
100
|
component.type === 'ui' && options.csses.forEach(function(cssModule) {
|
|
90
|
-
var
|
|
91
|
-
|
|
92
|
-
variableNames.push(variableName);
|
|
101
|
+
var url = getRelativeFilePath(cssModule.filename, rootPath);
|
|
102
|
+
urls.push(JSON.stringify(url));
|
|
93
103
|
});
|
|
94
104
|
|
|
95
|
-
if (
|
|
96
|
-
return `${
|
|
105
|
+
if (urls.length) {
|
|
106
|
+
return `${varname}.style([${urls.join(',')}])`;
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
return '';
|
|
100
110
|
}
|
|
101
111
|
|
|
102
|
-
function
|
|
103
|
-
|
|
112
|
+
function getRelativeFilePath(filePath, rootPath) {
|
|
113
|
+
if (getRelativeFilePath.cache.hasOwnProperty(filePath)) {
|
|
114
|
+
return getRelativeFilePath.cache[filePath];
|
|
115
|
+
}
|
|
104
116
|
|
|
105
|
-
|
|
117
|
+
var url = '';
|
|
106
118
|
|
|
107
|
-
|
|
119
|
+
if (filePath.indexOf(rootPath) === 0) {
|
|
120
|
+
url = filePath.replace(rootPath, '').replace(/\\/g, '/');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
var nodeModulePaths = require.main.paths;
|
|
124
|
+
var length = nodeModulePaths.length;
|
|
108
125
|
|
|
109
|
-
|
|
126
|
+
for (var i = 0; i < length; i++) {
|
|
127
|
+
var nodeModulePath = nodeModulePaths[i];
|
|
110
128
|
|
|
111
|
-
|
|
129
|
+
if (filePath.indexOf(nodeModulePath) === 0) {
|
|
130
|
+
url = filePath.replace(nodeModulePath, 'npm:/').replace(/\\/g, '/');
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return url;
|
|
112
137
|
}
|
|
113
138
|
|
|
114
|
-
|
|
115
|
-
var code = '', list = [],
|
|
116
|
-
tags = distinctValues(component, 'htmltags');
|
|
139
|
+
getRelativeFilePath.cache = {};
|
|
117
140
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
141
|
+
function bundle(component, rootPath) {
|
|
142
|
+
var codeOfDependencies = getCodeOfDependencies(component, rootPath);
|
|
143
|
+
var dependencyDelaration = getDependencyDelaration(component, rootPath);
|
|
144
|
+
var optionCode = generateOptionCode(component, '', rootPath);
|
|
145
|
+
var componentCode = component.toString();
|
|
146
|
+
|
|
147
|
+
if (dependencyDelaration) {
|
|
148
|
+
componentCode = componentCode.replace('{', `{\r\n${dependencyDelaration}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var codes = [];
|
|
121
152
|
|
|
122
|
-
if (
|
|
123
|
-
|
|
153
|
+
if (codeOfDependencies) codes.push(codeOfDependencies);
|
|
154
|
+
if (componentCode) {
|
|
155
|
+
codes.push(`Binh.${component.type}(${component.type})${optionCode};`);
|
|
156
|
+
codes.push(`${componentCode}`);
|
|
124
157
|
}
|
|
125
158
|
|
|
126
|
-
|
|
159
|
+
return codes.join('\r\n');
|
|
160
|
+
}
|
|
127
161
|
|
|
128
|
-
|
|
162
|
+
function getHtmlTagDeclaration(component) {
|
|
163
|
+
var variablesList = component.htmltags.join(',');
|
|
164
|
+
|
|
165
|
+
if (!variablesList) return '';
|
|
166
|
+
|
|
167
|
+
return `var {${variablesList}} = Binh.els;\r\n`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function htmltags(component) {
|
|
171
|
+
var tags = distinctValues(component, 'htmltags');
|
|
172
|
+
|
|
173
|
+
if (!tags.length) return '';
|
|
174
|
+
|
|
175
|
+
var variablesList = tags.join(',');
|
|
176
|
+
tags = tags.map((tag) => JSON.stringify(tag));
|
|
177
|
+
|
|
178
|
+
return [
|
|
179
|
+
`Binh.els = Binh.element(${tags.join(',')});`,
|
|
180
|
+
'',
|
|
181
|
+
`var {${variablesList}} = Binh.els;`,
|
|
182
|
+
''
|
|
183
|
+
]
|
|
184
|
+
.join(`\r\n`);
|
|
129
185
|
}
|
|
130
186
|
|
|
131
187
|
function prequire(component, codes) {
|
|
132
188
|
var code = '', links = distinctValues(component, 'links');
|
|
133
189
|
|
|
134
190
|
if (links.length) {
|
|
135
|
-
code = `Binh.prequire(['${links.join("','")}'], function() {\r\n
|
|
191
|
+
code = `Binh.prequire(['${links.join("','")}'], function() {\r\n${codes.join('\r\n')}\r\n});`;
|
|
136
192
|
}
|
|
137
193
|
else {
|
|
138
194
|
code = IIF(codes);
|
|
@@ -142,7 +198,7 @@ function prequire(component, codes) {
|
|
|
142
198
|
}
|
|
143
199
|
|
|
144
200
|
function IIF(codes) {
|
|
145
|
-
return `!function(){\r\n
|
|
201
|
+
return `!function(){\r\n${codes.join('\r\n')}\r\n}();`;
|
|
146
202
|
}
|
|
147
203
|
|
|
148
204
|
function distinctValues(component, key) {
|
package/src/component.build.js
CHANGED
|
@@ -3,9 +3,8 @@ const { parse } = require('path');
|
|
|
3
3
|
const { scanNestedFiles, cloneFile, writeToFile, makeFullDirPath } = require('./component.file');
|
|
4
4
|
const CodeFormat = require('./code');
|
|
5
5
|
const Component = require('./component');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// [-] Able to minify/beautify generated files
|
|
6
|
+
const UglifyJS = require('uglify-js');
|
|
7
|
+
const BeautifyJS = require('js-beautify/js');
|
|
9
8
|
|
|
10
9
|
function generate(sourceRootPath, outputRootPath, stageRootPath) {
|
|
11
10
|
if (sourceRootPath == undefined || outputRootPath == undefined) return;
|
|
@@ -36,17 +35,33 @@ function generate(sourceRootPath, outputRootPath, stageRootPath) {
|
|
|
36
35
|
|
|
37
36
|
var code = joinCodes(component, stageRootPath);
|
|
38
37
|
|
|
38
|
+
code = Component.minification ? minifyCode(code) : beautifyCode(code);
|
|
39
|
+
|
|
39
40
|
writeToFile(fileOutputPath, code);
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
function joinCodes(component, rootPath) {
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
CodeFormat.htmltags(component)
|
|
45
|
+
var mainCode = CodeFormat.prequire(component, [
|
|
46
|
+
`var _Binh = Binh;\r\n`,
|
|
47
|
+
CodeFormat.htmltags(component),
|
|
48
|
+
CodeFormat.bundle(component, rootPath)
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
return CodeFormat.IIF([
|
|
52
|
+
`var Binh = window.Binh;`,
|
|
53
|
+
mainCode
|
|
47
54
|
]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function minifyCode(code) {
|
|
58
|
+
var result = UglifyJS.minify(code);
|
|
59
|
+
if (result.error) throw result.error;
|
|
60
|
+
return result.code;
|
|
61
|
+
}
|
|
48
62
|
|
|
49
|
-
|
|
63
|
+
function beautifyCode(code) {
|
|
64
|
+
return BeautifyJS.js(code);
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
module.exports = {
|
package/src/component.js
CHANGED
package/test.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function parseFilePathToVariableName(filePath) {
|
|
5
|
+
return path.parse(filePath).name.replace(/-/g, '').replace(/\W.*/, '');
|
|
6
|
+
// try {
|
|
7
|
+
// }
|
|
8
|
+
// catch (error) {
|
|
9
|
+
// return '';
|
|
10
|
+
// }
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// console.log(parseFilePathToVariableName(1));
|
|
15
|
+
console.log(parseFilePathToVariableName(''));
|
|
16
|
+
// console.log(parseFilePathToVariableName(null));
|
|
17
|
+
// console.log(parseFilePathToVariableName());
|
|
18
|
+
// console.log(parseFilePathToVariableName('abc.js'));
|
|
19
|
+
// console.log(parseFilePathToVariableName('abc,.js'));
|
|
20
|
+
// console.log(parseFilePathToVariableName('abc.css.js'));
|
|
21
|
+
// console.log(parseFilePathToVariableName('./uhm/abc.css.js'));
|
|
22
|
+
console.log(parseFilePathToVariableName('.css.js'));
|