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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binhend",
3
- "version": "1.3.0",
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",
@@ -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 == null) return;
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
- binh.bundle(type, context.module, component);
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.forEach(function(child) {
64
- child = child.exports;
65
- if (child.constructor !== Component) return;
66
- if (child.alias) {
67
- component.vars[child.filename] = child.alias;
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.bundle('ui', module, component);
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.bundle('service', module, component);
95
+ binh.final(module);
81
96
  };
82
97
 
83
98
  binh.style = function(module, component) {
84
- binh.bundle('style', module, component);
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 = require('fs').readFileSync(cssFilePath, { encoding: 'utf8', flag: 'r' });
90
- content = content.replace(/\s+/g, ' ');
91
- var component = new Function(`return ${JSON.stringify(content)};`);
92
- binh.bundle('style', module, component);
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
- const { parse } = require('path');
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 dependencies(component, root, metadata) {
5
- var global = metadata || {}, local = {}, variables = {}, code = '';
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
- var children = component.module.children;
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
- children.forEach(function(child) {
10
- child = child.exports;
19
+ if (dependencyDelaration) {
20
+ componentCode = componentCode.replace('{', `{\r\n${dependencyDelaration}`);
21
+ }
11
22
 
12
- if (child.constructor !== component.constructor) return;
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
- var filename = child.filename;
30
+ codes.push(IIF(blockCodes));
31
+ codes.push('');
15
32
 
16
- var url = '';
33
+ global[filename] = local[filename];
34
+ });
17
35
 
18
- if (filename.indexOf(root) === 0) {
19
- url = filename.replace(root, '').replace(/\\/g, '/');
20
- }
21
- else {
22
- var nodeModulePaths = require.main.paths;
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
- for (var i = 0; i < length; i++) {
26
- var nodeModulePath = nodeModulePaths[i];
42
+ return codes.join('\r\n');
43
+ }
27
44
 
28
- if (filename.indexOf(nodeModulePath) === 0) {
29
- url = filename.replace(nodeModulePath, 'npm:/').replace(/\\/g, '/');
30
- break;
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
- var name = component.vars[filename] || parse(filename).name.replace(/-/g, '').replace(/\W.*/, '');
56
+ var declarationCode = codes.join(',');
36
57
 
37
- local[filename] = {
38
- name, url,
39
- type: child.type,
40
- component: child
41
- };
42
- });
58
+ codes = [];
59
+ codes.push(`var Binh = _Binh;`);
43
60
 
44
- Object.keys(local).forEach(function(filename) {
45
- var declaration = '',
46
- current = local[filename],
47
- existed = global[filename];
61
+ if (declarationCode) {
62
+ codes.push(`var${declarationCode};`);
63
+ }
48
64
 
49
- var { type, name, url, component } = current;
65
+ codes.push('');
50
66
 
51
- if (existed) {
52
- declaration += `Binh.later(function() {${name} = Binh.${type}('${url}');});\r\n`;
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
- var optionCode = buildCodeApplyOptions(name, component);
70
+ function getMetadataOfDependencies(component, rootPath) {
71
+ if (component.dependencies) return component.dependencies;
62
72
 
63
- if (optionCode) {
64
- declaration += `Binh.later(function() {${optionCode};});\r\n`;
65
- }
73
+ var dependencies = component.module.children;
66
74
 
67
- code += IIF([
68
- dependencies(component, root, Object.assign({}, global, local)),
69
- declaration
70
- ]);
75
+ component.dependencies = {};
71
76
 
72
- code += '\r\n\r\n';
73
- });
77
+ dependencies.forEach(function(module) {
78
+ var dependency = module.exports;
74
79
 
75
- var vars = Object.keys(variables);
80
+ if (dependency.constructor !== component.constructor) return;
76
81
 
77
- if (vars.length) {
78
- code += `var ${vars.join(', ')};\r\n`;
79
- }
82
+ var filename = dependency.filename;
83
+ var name = component.vars[filename] || dependency.varname;
84
+ var url = getRelativeFilePath(filename, rootPath);
80
85
 
81
- return code;
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 buildCodeApplyOptions(componentName, component) {
85
- var options = component.options, variableNames = [];
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 filename = cssModule.filename;
91
- var variableName = component.vars[filename] || parse(filename).name.replace(/-/g, '').replace(/\W.*/, '');
92
- variableNames.push(variableName);
101
+ var url = getRelativeFilePath(cssModule.filename, rootPath);
102
+ urls.push(JSON.stringify(url));
93
103
  });
94
104
 
95
- if (variableNames.length) {
96
- return `${componentName}.style([${variableNames.join(',')}])`;
105
+ if (urls.length) {
106
+ return `${varname}.style([${urls.join(',')}])`;
97
107
  }
98
108
 
99
109
  return '';
100
110
  }
101
111
 
102
- function bundle(component, root) {
103
- var code = '';
112
+ function getRelativeFilePath(filePath, rootPath) {
113
+ if (getRelativeFilePath.cache.hasOwnProperty(filePath)) {
114
+ return getRelativeFilePath.cache[filePath];
115
+ }
104
116
 
105
- code += dependencies(component, root);
117
+ var url = '';
106
118
 
107
- code += '\r\n';
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
- code += `Binh.${component.type}(${component.toString()})${buildCodeApplyOptions('', component)};\r\n`;
126
+ for (var i = 0; i < length; i++) {
127
+ var nodeModulePath = nodeModulePaths[i];
110
128
 
111
- return code;
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
- function htmltags(component) {
115
- var code = '', list = [],
116
- tags = distinctValues(component, 'htmltags');
139
+ getRelativeFilePath.cache = {};
117
140
 
118
- tags.forEach(function(tag) {
119
- list.push(`${tag} = Binh.el('${tag}')`);
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 (list.length) {
123
- code = `var ${list.join(',\r\n')};`;
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
- code += code ? '\r\n' : '';
159
+ return codes.join('\r\n');
160
+ }
127
161
 
128
- return code;
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\r\n${codes.join('\r\n')}\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\r\n${codes.join('\r\n')}\r\n}();`
201
+ return `!function(){\r\n${codes.join('\r\n')}\r\n}();`;
146
202
  }
147
203
 
148
204
  function distinctValues(component, key) {
@@ -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
- // TODO
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 fullcode = CodeFormat.prequire(component, [
45
- CodeFormat.bundle(component, rootPath),
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
- return fullcode;
63
+ function beautifyCode(code) {
64
+ return BeautifyJS.js(code);
50
65
  }
51
66
 
52
67
  module.exports = {
package/src/component.js CHANGED
@@ -102,7 +102,8 @@ function showError(message, id, error) {
102
102
  }
103
103
 
104
104
  var Component = {
105
- generate
105
+ generate,
106
+ minification: false
106
107
  };
107
108
 
108
109
  module.exports = Component;
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'));