binhend 1.3.0 → 1.4.0
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 +138 -86
- 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.0",
|
|
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,190 @@
|
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
child = child.exports;
|
|
11
|
-
|
|
12
|
-
if (child.constructor !== component.constructor) return;
|
|
13
|
-
|
|
14
|
-
var filename = child.filename;
|
|
7
|
+
filenames.forEach(function(filename) {
|
|
8
|
+
var existed = global[filename];
|
|
9
|
+
|
|
10
|
+
if (existed) return;
|
|
11
|
+
|
|
12
|
+
var { type, url, dependency } = local[filename];
|
|
15
13
|
|
|
16
|
-
var
|
|
14
|
+
var dependencyDelaration = getDependencyDelaration(dependency, rootPath);
|
|
15
|
+
var componentCode = dependency.toString();
|
|
16
|
+
var optionCode = generateOptionCode(dependency, '', rootPath);
|
|
17
|
+
var htmlTagDeclaration = getHtmlTagDeclaration(dependency);
|
|
17
18
|
|
|
18
|
-
if (
|
|
19
|
-
|
|
19
|
+
if (dependencyDelaration) {
|
|
20
|
+
componentCode = componentCode.replace('{', `{\r\n${dependencyDelaration}\r\n`);
|
|
20
21
|
}
|
|
21
|
-
else {
|
|
22
|
-
var nodeModulePaths = require.main.paths;
|
|
23
|
-
var length = nodeModulePaths.length;
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
url = filename.replace(nodeModulePath, 'npm:/').replace(/\\/g, '/');
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
23
|
+
var blockCodes = [];
|
|
24
|
+
blockCodes.push(`Binh.${type}('${url}', ${type})${optionCode};`);
|
|
25
|
+
if (htmlTagDeclaration) {
|
|
26
|
+
blockCodes.push(htmlTagDeclaration);
|
|
33
27
|
}
|
|
28
|
+
blockCodes.push(componentCode);
|
|
34
29
|
|
|
35
|
-
|
|
30
|
+
codes.push(IIF(blockCodes));
|
|
31
|
+
codes.push('');
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
name, url,
|
|
39
|
-
type: child.type,
|
|
40
|
-
component: child
|
|
41
|
-
};
|
|
33
|
+
global[filename] = local[filename];
|
|
42
34
|
});
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
filenames.forEach(function(filename) {
|
|
37
|
+
var { dependency } = local[filename];
|
|
38
|
+
var codeOfDependencies = getCodeOfDependencies(dependency, rootPath, global);
|
|
39
|
+
if (codeOfDependencies) codes.push(codeOfDependencies);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return codes.join('\r\n');
|
|
43
|
+
}
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
function getDependencyDelaration(component, rootPath) {
|
|
46
|
+
var dependencies = getMetadataOfDependencies(component, rootPath);
|
|
47
|
+
var codes = [], fullCode = '';
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
for (var filePath in dependencies) {
|
|
50
|
+
var { name, url, type } = dependencies[filePath];
|
|
51
|
+
if (name) {
|
|
52
|
+
codes.push(` ${name} = Binh.${type}('${url}')`);
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
declaration += `${name} = Binh.${type}('${url}', ${component.toString()});\r\n`;
|
|
57
|
-
global[filename] = local[filename];
|
|
58
|
-
variables[name] = true;
|
|
59
|
-
};
|
|
54
|
+
}
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
var declarationCode = codes.join(',');
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
if (declarationCode) {
|
|
59
|
+
fullCode = [
|
|
60
|
+
`var Binh = _Binh;`,
|
|
61
|
+
`var${declarationCode};`,
|
|
62
|
+
''
|
|
63
|
+
].join('\r\n');
|
|
64
|
+
}
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
declaration
|
|
70
|
-
]);
|
|
66
|
+
return fullCode;
|
|
67
|
+
}
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
function getMetadataOfDependencies(component, rootPath) {
|
|
70
|
+
if (component.dependencies) return component.dependencies;
|
|
74
71
|
|
|
75
|
-
var
|
|
72
|
+
var dependencies = component.module.children;
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
code += `var ${vars.join(', ')};\r\n`;
|
|
79
|
-
}
|
|
74
|
+
component.dependencies = {};
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
dependencies.forEach(function(module) {
|
|
77
|
+
var dependency = module.exports;
|
|
78
|
+
|
|
79
|
+
if (dependency.constructor !== component.constructor) return;
|
|
80
|
+
|
|
81
|
+
var filename = dependency.filename;
|
|
82
|
+
var name = component.vars[filename] || dependency.varname;
|
|
83
|
+
var url = getRelativeFilePath(filename, rootPath);
|
|
84
|
+
|
|
85
|
+
component.dependencies[filename] = {
|
|
86
|
+
name, url, dependency,
|
|
87
|
+
type: dependency.type
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return component.dependencies;
|
|
82
92
|
}
|
|
83
93
|
|
|
84
|
-
function
|
|
85
|
-
var options = component.options,
|
|
94
|
+
function generateOptionCode(component, varname, rootPath) {
|
|
95
|
+
var options = component.options, urls = [];
|
|
86
96
|
|
|
87
97
|
if (!options) return '';
|
|
88
98
|
|
|
89
99
|
component.type === 'ui' && options.csses.forEach(function(cssModule) {
|
|
90
|
-
var
|
|
91
|
-
|
|
92
|
-
variableNames.push(variableName);
|
|
100
|
+
var url = getRelativeFilePath(cssModule.filename, rootPath);
|
|
101
|
+
urls.push(JSON.stringify(url));
|
|
93
102
|
});
|
|
94
103
|
|
|
95
|
-
if (
|
|
96
|
-
return `${
|
|
104
|
+
if (urls.length) {
|
|
105
|
+
return `${varname}.style([${urls.join(',')}])`;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
return '';
|
|
100
109
|
}
|
|
101
110
|
|
|
102
|
-
function
|
|
103
|
-
|
|
111
|
+
function getRelativeFilePath(filePath, rootPath) {
|
|
112
|
+
if (getRelativeFilePath.cache.hasOwnProperty(filePath)) {
|
|
113
|
+
return getRelativeFilePath.cache[filePath];
|
|
114
|
+
}
|
|
104
115
|
|
|
105
|
-
|
|
116
|
+
var url = '';
|
|
106
117
|
|
|
107
|
-
|
|
118
|
+
if (filePath.indexOf(rootPath) === 0) {
|
|
119
|
+
url = filePath.replace(rootPath, '').replace(/\\/g, '/');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
var nodeModulePaths = require.main.paths;
|
|
123
|
+
var length = nodeModulePaths.length;
|
|
108
124
|
|
|
109
|
-
|
|
125
|
+
for (var i = 0; i < length; i++) {
|
|
126
|
+
var nodeModulePath = nodeModulePaths[i];
|
|
110
127
|
|
|
111
|
-
|
|
112
|
-
|
|
128
|
+
if (filePath.indexOf(nodeModulePath) === 0) {
|
|
129
|
+
url = filePath.replace(nodeModulePath, 'npm:/').replace(/\\/g, '/');
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
113
134
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
tags = distinctValues(component, 'htmltags');
|
|
135
|
+
return url;
|
|
136
|
+
}
|
|
117
137
|
|
|
118
|
-
|
|
119
|
-
list.push(`${tag} = Binh.el('${tag}')`);
|
|
120
|
-
});
|
|
138
|
+
getRelativeFilePath.cache = {};
|
|
121
139
|
|
|
122
|
-
|
|
123
|
-
|
|
140
|
+
function bundle(component, rootPath) {
|
|
141
|
+
var codeOfDependencies = getCodeOfDependencies(component, rootPath);
|
|
142
|
+
var dependencyDelaration = getDependencyDelaration(component, rootPath);
|
|
143
|
+
var optionCode = generateOptionCode(component, '', rootPath);
|
|
144
|
+
var componentCode = component.toString();
|
|
145
|
+
|
|
146
|
+
if (dependencyDelaration) {
|
|
147
|
+
componentCode = componentCode.replace('{', `{\r\n${dependencyDelaration}`);
|
|
124
148
|
}
|
|
125
149
|
|
|
126
|
-
|
|
150
|
+
var codes = [];
|
|
127
151
|
|
|
128
|
-
|
|
152
|
+
if (codeOfDependencies) codes.push(codeOfDependencies);
|
|
153
|
+
if (componentCode) codes.push(`Binh.${component.type}(${componentCode})${optionCode};`);
|
|
154
|
+
|
|
155
|
+
return codes.join('\r\n');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function getHtmlTagDeclaration(component) {
|
|
159
|
+
var variablesList = component.htmltags.join(',');
|
|
160
|
+
|
|
161
|
+
if (!variablesList) return '';
|
|
162
|
+
|
|
163
|
+
return `var {${variablesList}} = Binh.els;\r\n`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function htmltags(component) {
|
|
167
|
+
var tags = distinctValues(component, 'htmltags');
|
|
168
|
+
|
|
169
|
+
if (!tags.length) return '';
|
|
170
|
+
|
|
171
|
+
var variablesList = tags.join(',');
|
|
172
|
+
tags = tags.map((tag) => JSON.stringify(tag));
|
|
173
|
+
|
|
174
|
+
return [
|
|
175
|
+
`Binh.els = Binh.element(${tags.join(',')});`,
|
|
176
|
+
'',
|
|
177
|
+
`var {${variablesList}} = Binh.els;`,
|
|
178
|
+
''
|
|
179
|
+
]
|
|
180
|
+
.join(`\r\n`);
|
|
129
181
|
}
|
|
130
182
|
|
|
131
183
|
function prequire(component, codes) {
|
|
132
184
|
var code = '', links = distinctValues(component, 'links');
|
|
133
185
|
|
|
134
186
|
if (links.length) {
|
|
135
|
-
code = `Binh.prequire(['${links.join("','")}'], function() {\r\n
|
|
187
|
+
code = `Binh.prequire(['${links.join("','")}'], function() {\r\n${codes.join('\r\n')}\r\n});`;
|
|
136
188
|
}
|
|
137
189
|
else {
|
|
138
190
|
code = IIF(codes);
|
|
@@ -142,7 +194,7 @@ function prequire(component, codes) {
|
|
|
142
194
|
}
|
|
143
195
|
|
|
144
196
|
function IIF(codes) {
|
|
145
|
-
return `!function(){\r\n
|
|
197
|
+
return `!function(){\r\n${codes.join('\r\n')}\r\n}();`;
|
|
146
198
|
}
|
|
147
199
|
|
|
148
200
|
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'));
|