leanweb 1.0.4
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/LICENSE +21 -0
- package/README.md +712 -0
- package/commands/build.js +160 -0
- package/commands/clean.js +8 -0
- package/commands/destroy.js +24 -0
- package/commands/dist.js +61 -0
- package/commands/electron.js +59 -0
- package/commands/generate.js +50 -0
- package/commands/help.js +32 -0
- package/commands/init.js +101 -0
- package/commands/serve.js +71 -0
- package/commands/upgrade.js +53 -0
- package/commands/utils.js +237 -0
- package/commands/version.js +2 -0
- package/leanweb.js +56 -0
- package/lib/lw-html-parser.js +113 -0
- package/package.json +43 -0
- package/templates/component.js +48 -0
- package/templates/electron.js +43 -0
- package/templates/env/prod.js +3 -0
- package/templates/env/test.js +3 -0
- package/templates/env.js +3 -0
- package/templates/favicon.svg +7 -0
- package/templates/index.html +13 -0
- package/templates/lib/api-client.js +74 -0
- package/templates/lib/lw-element.js +483 -0
- package/templates/lib/lw-event-bus.js +54 -0
- package/templates/lib/lw-expr-parser.js +156 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
(async () => {
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fse = require('fs-extra');
|
|
5
|
+
const utils = require('./utils.js');
|
|
6
|
+
const parser = require('../lib/lw-html-parser.js');
|
|
7
|
+
|
|
8
|
+
let env;
|
|
9
|
+
const args = process.argv;
|
|
10
|
+
if (args.length >= 3) {
|
|
11
|
+
env = args[2];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const replaceNodeModulesImport = (str, filePath) => {
|
|
15
|
+
// match import not starting with dot or slash
|
|
16
|
+
return str.replace(/^(\s*import.+?['"])([^\.|\/].+?)(['"].*)$/gm, (m, a, b, c) => {
|
|
17
|
+
if (b.startsWith(`~`)) {
|
|
18
|
+
// ~/package.json
|
|
19
|
+
return a + path.normalize(`${process.cwd()}/` + b.substring(1)) + c;
|
|
20
|
+
} else if (b.indexOf('/') > -1) {
|
|
21
|
+
// lodash-es/get.js
|
|
22
|
+
return a + path.normalize(`${process.cwd()}/node_modules/` + b) + c;
|
|
23
|
+
} else {
|
|
24
|
+
const nodeModulePath = `${process.cwd()}/node_modules/` + b + '/package.json';
|
|
25
|
+
const package = require(nodeModulePath);
|
|
26
|
+
// lodash-es
|
|
27
|
+
return a + path.normalize(`${process.cwd()}/node_modules/` + b + '/' + package.main) + c;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const walkDirSync = (dir, accept = null, callback) => {
|
|
33
|
+
fs.readdirSync(dir).forEach(f => {
|
|
34
|
+
let dirPath = path.join(dir, f);
|
|
35
|
+
const isDirectory = fs.statSync(dirPath).isDirectory() && (!accept || (typeof accept === 'function' && accept(dirPath, f)));
|
|
36
|
+
isDirectory ? walkDirSync(dirPath, accept, callback) : callback(path.join(dirPath));
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const preprocessJsImport = filePath => {
|
|
41
|
+
if (filePath.toLowerCase().endsWith('.js') && !filePath.toLowerCase().endsWith('/ast.js') && !filePath.startsWith(`${utils.dirs.build}/lib/`)) {
|
|
42
|
+
let jsFileString = fs.readFileSync(filePath, 'utf8');
|
|
43
|
+
jsFileString = replaceNodeModulesImport(jsFileString, filePath);
|
|
44
|
+
fs.writeFileSync(filePath, jsFileString);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const buildDirFilter = dirPath => {
|
|
49
|
+
if (dirPath.startsWith(`${utils.dirs.build}/lib/`)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const leanwebPackageJSON = require(`${__dirname}/../package.json`);
|
|
56
|
+
|
|
57
|
+
const buildModule = (projectPath) => {
|
|
58
|
+
|
|
59
|
+
const project = require(`${projectPath}/${utils.dirs.src}/leanweb.json`);
|
|
60
|
+
const isMain = process.cwd() === projectPath;
|
|
61
|
+
|
|
62
|
+
const buildDir = isMain ? utils.dirs.build : `${utils.dirs.build}/_dependencies/${project.name}`;
|
|
63
|
+
fs.mkdirSync(buildDir, { recursive: true });
|
|
64
|
+
|
|
65
|
+
let depImports = '';
|
|
66
|
+
project.imports?.forEach(im => {
|
|
67
|
+
let depPath;
|
|
68
|
+
if (im.indexOf('/') < 0) {
|
|
69
|
+
depPath = `${process.cwd()}/node_modules/${im}`;
|
|
70
|
+
} else {
|
|
71
|
+
if (im.startsWith('./')) {
|
|
72
|
+
depPath = `${process.cwd()}/${im}`;
|
|
73
|
+
} else if (im.startsWith('/')) {
|
|
74
|
+
depPath = im;
|
|
75
|
+
} else {
|
|
76
|
+
depPath = `${process.cwd()}/node_modules/${im}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const depName = buildModule(depPath);
|
|
80
|
+
if (isMain) {
|
|
81
|
+
depImports += `import './_dependencies/${depName}/${depName}.js';\n`;
|
|
82
|
+
} else {
|
|
83
|
+
depImports += `import '../${depName}/${depName}.js';\n`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const copySrc = () => {
|
|
89
|
+
fse.copySync(`${projectPath}/${utils.dirs.src}/`, buildDir);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const copyEnv = () => {
|
|
93
|
+
if (env) {
|
|
94
|
+
fse.copySync(`${buildDir}/env/${env}.js`, `${buildDir}/env.js`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const buildJS = () => {
|
|
99
|
+
walkDirSync(buildDir, buildDirFilter, preprocessJsImport);
|
|
100
|
+
|
|
101
|
+
const jsString = project.components.reduce((acc, cur) => {
|
|
102
|
+
const cmpName = utils.getComponentName(cur);
|
|
103
|
+
let importString = `import './components/${cur}/${cmpName}.js';`;
|
|
104
|
+
return acc + importString + '\n';
|
|
105
|
+
}, depImports + '\n');
|
|
106
|
+
fs.writeFileSync(`${buildDir}/${project.name}.js`, jsString);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const buildHTML = () => {
|
|
110
|
+
project.components.forEach(cmp => {
|
|
111
|
+
const cmpName = utils.getComponentName(cmp);
|
|
112
|
+
const htmlFilename = `${projectPath}/${buildDir}/components/${cmp}/${cmpName}.html`;
|
|
113
|
+
const htmlFileExists = fs.existsSync(htmlFilename);
|
|
114
|
+
if (htmlFileExists) {
|
|
115
|
+
|
|
116
|
+
const scssFilename = `${projectPath}/${buildDir}/components/${cmp}/${cmpName}.scss`;
|
|
117
|
+
const scssFileExists = fs.existsSync(scssFilename);
|
|
118
|
+
let cssString = '';
|
|
119
|
+
if (scssFileExists) {
|
|
120
|
+
let scssString = `@import "global-styles.scss";\n`;
|
|
121
|
+
scssString += fs.readFileSync(scssFilename, 'utf8');
|
|
122
|
+
scssString += '\n[lw-false],[lw-for]{display:none !important;}\n';
|
|
123
|
+
cssString = utils.buildCSS(scssString, `${projectPath}/${buildDir}/components/${cmp}`);
|
|
124
|
+
}
|
|
125
|
+
const styleString = cssString || '';
|
|
126
|
+
const htmlString = fs.readFileSync(htmlFilename, 'utf8');
|
|
127
|
+
const ast = parser.parse(htmlString);
|
|
128
|
+
ast.css = styleString;
|
|
129
|
+
ast.componentFullName = project.name + '-' + cmp.replace(/\//g, '-');
|
|
130
|
+
ast.runtimeVersion = project.version;
|
|
131
|
+
ast.builderVersion = leanwebPackageJSON.version;
|
|
132
|
+
fs.writeFileSync(`${buildDir}/components/${cmp}/ast.js`, `export default ${JSON.stringify(ast, null, 0)};`);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
const htmlString = fs.readFileSync(`${projectPath}/${buildDir}/index.html`, 'utf8');
|
|
136
|
+
fs.writeFileSync(`${buildDir}/index.html`, htmlString);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const buildSCSS = () => {
|
|
140
|
+
const projectScssFilename = `${projectPath}/src/${project.name}.scss`;
|
|
141
|
+
let projectCssString = '';
|
|
142
|
+
if (fs.existsSync(projectScssFilename)) {
|
|
143
|
+
const projectScssString = fs.readFileSync(projectScssFilename, 'utf8');
|
|
144
|
+
projectCssString += utils.buildCSS(projectScssString, `${projectPath}/${buildDir}`);
|
|
145
|
+
}
|
|
146
|
+
fs.writeFileSync(`${buildDir}/${project.name}.css`, projectCssString);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
copySrc();
|
|
150
|
+
copyEnv();
|
|
151
|
+
buildJS();
|
|
152
|
+
buildSCSS();
|
|
153
|
+
buildHTML();
|
|
154
|
+
|
|
155
|
+
return project.name;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
buildModule(process.cwd());
|
|
159
|
+
|
|
160
|
+
})();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const utils = require('./utils.js');
|
|
3
|
+
|
|
4
|
+
(async () => {
|
|
5
|
+
fs.rmSync(utils.dirs.build + '/', { recursive: true, force: true });
|
|
6
|
+
fs.rmSync(utils.dirs.dist + '/', { recursive: true, force: true });
|
|
7
|
+
fs.rmSync(utils.dirs.serve + '/', { recursive: true, force: true });
|
|
8
|
+
})();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const utils = require('./utils.js');
|
|
3
|
+
|
|
4
|
+
const args = process.argv;
|
|
5
|
+
if (args.length < 3) {
|
|
6
|
+
console.log('Usage: lw destroy project-name');
|
|
7
|
+
console.log(`This will delete ${utils.dirs.src}/ ${utils.dirs.build}/ ${utils.dirs.dist}/ ${utils.dirs.serve}/ and ${utils.dirs.electron}/`)
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const projectName = args[2];
|
|
12
|
+
|
|
13
|
+
const project = require(`${process.cwd()}/${utils.dirs.src}/leanweb.json`);
|
|
14
|
+
|
|
15
|
+
if (projectName !== project.name) {
|
|
16
|
+
console.error('Error: project name doesn\'t match.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fs.rmSync(utils.dirs.build + '/', { recursive: true, force: true });
|
|
21
|
+
fs.rmSync(utils.dirs.dist + '/', { recursive: true, force: true });
|
|
22
|
+
fs.rmSync(utils.dirs.src + '/', { recursive: true, force: true });
|
|
23
|
+
fs.rmSync(utils.dirs.serve + '/', { recursive: true, force: true });
|
|
24
|
+
fs.rmSync(utils.dirs.electron + '/', { recursive: true, force: true });
|
package/commands/dist.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const webpack = require('webpack');
|
|
2
|
+
const utils = require('./utils.js');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const fse = require('fs-extra');
|
|
5
|
+
const minify = require('html-minifier').minify;
|
|
6
|
+
const CleanCSS = require('clean-css');
|
|
7
|
+
|
|
8
|
+
let env = '';
|
|
9
|
+
const args = process.argv;
|
|
10
|
+
if (args.length >= 3) {
|
|
11
|
+
env = args[2];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
(async () => {
|
|
15
|
+
const project = require(`${process.cwd()}/${utils.dirs.src}/leanweb.json`);
|
|
16
|
+
|
|
17
|
+
await utils.exec(`npx lw clean`);
|
|
18
|
+
await utils.exec(`npx lw build ${env}`);
|
|
19
|
+
|
|
20
|
+
const webpackConfig = utils.getWebPackConfig(utils.dirs.dist, project);
|
|
21
|
+
|
|
22
|
+
const compiler = webpack({
|
|
23
|
+
...webpackConfig,
|
|
24
|
+
mode: 'production',
|
|
25
|
+
devtool: 'source-map',
|
|
26
|
+
performance: {
|
|
27
|
+
hints: false,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
compiler.run(async (err, stats) => {
|
|
32
|
+
if (err) {
|
|
33
|
+
console.log(err);
|
|
34
|
+
}
|
|
35
|
+
if (stats.compilation.errors.length) {
|
|
36
|
+
console.log(stats.compilation.errors);
|
|
37
|
+
}
|
|
38
|
+
if (stats.compilation.warnings.length) {
|
|
39
|
+
console.log(stats.compilation.warnings);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const indexHTML = fs.readFileSync(`./${utils.dirs.build}/index.html`, 'utf8');
|
|
43
|
+
const minifiedIndexHtml = minify(indexHTML, {
|
|
44
|
+
caseSensitive: true,
|
|
45
|
+
collapseWhitespace: true,
|
|
46
|
+
minifyCSS: true,
|
|
47
|
+
minifyJS: true,
|
|
48
|
+
caseSensitive: true,
|
|
49
|
+
});
|
|
50
|
+
fs.writeFileSync(`./${utils.dirs.dist}/index.html`, minifiedIndexHtml);
|
|
51
|
+
|
|
52
|
+
const appCSS = fs.readFileSync(`./${utils.dirs.build}/${project.name}.css`, 'utf8');
|
|
53
|
+
const minifiedAppCss = new CleanCSS({}).minify(appCSS);
|
|
54
|
+
fs.writeFileSync(`./${utils.dirs.dist}/${project.name}.css`, minifiedAppCss.styles);
|
|
55
|
+
|
|
56
|
+
fse.copySync(`./${utils.dirs.build}/favicon.svg`, `./${utils.dirs.dist}/favicon.svg`);
|
|
57
|
+
project.resources.forEach(resource => {
|
|
58
|
+
fse.copySync(`./${utils.dirs.build}/${resource}`, `./${utils.dirs.dist}/${resource}`);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
})();
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
(async () => {
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const fse = require('fs-extra');
|
|
4
|
+
const webpack = require('webpack');
|
|
5
|
+
const utils = require('./utils.js');
|
|
6
|
+
|
|
7
|
+
let env = '';
|
|
8
|
+
const args = process.argv;
|
|
9
|
+
if (args.length >= 3) {
|
|
10
|
+
env = args[2];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!fs.existsSync(process.cwd() + `/${utils.dirs.src}/electron.js`)) {
|
|
14
|
+
fse.copySync(`${__dirname}/../templates/electron.js`, `${process.cwd()}/${utils.dirs.src}/electron.js`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const leanwebJSONPath = `${process.cwd()}/${utils.dirs.src}/leanweb.json`;
|
|
18
|
+
const project = require(leanwebJSONPath);
|
|
19
|
+
if (!project.electron) {
|
|
20
|
+
utils.exec(`npm i -D electron --loglevel=error`);
|
|
21
|
+
project.electron = true;
|
|
22
|
+
fs.writeFileSync(leanwebJSONPath, JSON.stringify(project, null, 2));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await utils.exec(`npx lw clean`);
|
|
26
|
+
await utils.exec(`npx lw build ${env}`);
|
|
27
|
+
|
|
28
|
+
fse.copySync(`./${utils.dirs.build}/electron.js`, `./${utils.dirs.electron}/electron.js`);
|
|
29
|
+
fse.copySync(`./${utils.dirs.build}/index.html`, `./${utils.dirs.electron}/index.html`);
|
|
30
|
+
fse.copySync(`./${utils.dirs.build}/${project.name}.css`, `./${utils.dirs.electron}/${project.name}.css`);
|
|
31
|
+
fse.copySync(`./${utils.dirs.build}/favicon.svg`, `./${utils.dirs.electron}/favicon.svg`);
|
|
32
|
+
project.resources && project.resources.forEach(resource => {
|
|
33
|
+
fse.copySync(`./${utils.dirs.build}/${resource}`, `./${utils.dirs.electron}/${resource}`);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const webpackConfig = utils.getWebPackConfig(utils.dirs.electron, project);
|
|
37
|
+
|
|
38
|
+
const compiler = webpack({
|
|
39
|
+
...webpackConfig,
|
|
40
|
+
mode: 'development',
|
|
41
|
+
devtool: 'eval-cheap-module-source-map',
|
|
42
|
+
performance: {
|
|
43
|
+
hints: false,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
compiler.run(async (err, stats) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
console.log(err);
|
|
50
|
+
}
|
|
51
|
+
if (stats.compilation.errors.length) {
|
|
52
|
+
console.log(stats.compilation.errors);
|
|
53
|
+
}
|
|
54
|
+
if (stats.compilation.warnings.length) {
|
|
55
|
+
console.log(stats.compilation.warnings);
|
|
56
|
+
}
|
|
57
|
+
await utils.exec(`npx electron ${process.cwd()}/${utils.dirs.electron}/electron.js`);
|
|
58
|
+
});
|
|
59
|
+
})();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
(async () => {
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const utils = require('./utils.js');
|
|
4
|
+
|
|
5
|
+
const args = process.argv;
|
|
6
|
+
if (args.length < 3) {
|
|
7
|
+
console.error('Usage: lw generate component-names');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const leanwebJSONPath = `${process.cwd()}/${utils.dirs.src}/leanweb.json`;
|
|
12
|
+
const leanwebJSON = require(leanwebJSONPath);
|
|
13
|
+
const cmps = args.slice(2);
|
|
14
|
+
|
|
15
|
+
for (const cmpJSON of leanwebJSON.components) {
|
|
16
|
+
for (const cmp of cmps) {
|
|
17
|
+
if (cmpJSON === cmp) {
|
|
18
|
+
console.error(`Error: component ${cmpJSON} existed.`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
leanwebJSON.components.push(...cmps);
|
|
25
|
+
fs.writeFileSync(leanwebJSONPath, JSON.stringify(leanwebJSON, null, 2));
|
|
26
|
+
|
|
27
|
+
for (const cmp of cmps) {
|
|
28
|
+
const cmpName = utils.getComponentName(cmp);
|
|
29
|
+
const cmpPath = `${utils.dirs.src}/components/${cmp}`;
|
|
30
|
+
|
|
31
|
+
fs.mkdirSync(cmpPath, { recursive: true });
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(`${cmpPath}/${cmpName}.js`)) {
|
|
34
|
+
let jsString = fs.readFileSync(`${__dirname}/../templates/component.js`, 'utf8');
|
|
35
|
+
jsString = jsString.replace(/\$\{projectName\}/g, leanwebJSON.name);
|
|
36
|
+
jsString = jsString.replace(/\$\{component\}/g, cmp.replace(/\//g, '-'));
|
|
37
|
+
jsString = jsString.replace(/\$\{pathLevels\}/g, utils.getPathLevels(cmp));
|
|
38
|
+
|
|
39
|
+
fs.writeFileSync(`${cmpPath}/${cmpName}.js`, jsString);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!fs.existsSync(`${cmpPath}/${cmpName}.html`)) {
|
|
43
|
+
fs.writeFileSync(`${cmpPath}/${cmpName}.html`, `<div>${leanwebJSON.name}-${cmpName} works!</div>`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!fs.existsSync(`${cmpPath}/${cmpName}.scss`)) {
|
|
47
|
+
fs.writeFileSync(`${cmpPath}/${cmpName}.scss`, '');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})();
|
package/commands/help.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
(async () => {
|
|
2
|
+
|
|
3
|
+
const utils = require('./utils.js');
|
|
4
|
+
|
|
5
|
+
if (process.argv.length < 3) {
|
|
6
|
+
utils.exec('npx lw version');
|
|
7
|
+
console.log('Usage: lw target parameters');
|
|
8
|
+
console.log('Targets:\n');
|
|
9
|
+
Object.keys(utils.targets).forEach(t => {
|
|
10
|
+
console.log(t);
|
|
11
|
+
});
|
|
12
|
+
console.log();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let target = process.argv[2];
|
|
17
|
+
|
|
18
|
+
const targetCandidates = Object.keys(utils.targets).filter(t => t.startsWith(target));
|
|
19
|
+
|
|
20
|
+
if (targetCandidates.length === 0) {
|
|
21
|
+
console.error(`Error: target ${target} not found.`);
|
|
22
|
+
return;
|
|
23
|
+
} else if (targetCandidates.length > 1) {
|
|
24
|
+
targetCandidates.forEach(t => {
|
|
25
|
+
console.log(t);
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
target = targetCandidates[0];
|
|
31
|
+
console.log(utils.targets[target].note);
|
|
32
|
+
})();
|
package/commands/init.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
(async () => {
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const fse = require('fs-extra');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const git = require('isomorphic-git');
|
|
6
|
+
const globby = require('globby');
|
|
7
|
+
const args = process.argv;
|
|
8
|
+
const utils = require('./utils.js');
|
|
9
|
+
|
|
10
|
+
const leanwebJSONExisted = fs.existsSync(`${process.cwd()}/${utils.dirs.src}/leanweb.json`);
|
|
11
|
+
const packageJSONExisted = fs.existsSync(`${process.cwd()}/package.json`);
|
|
12
|
+
|
|
13
|
+
const lwPackage = require(`${__dirname}/../package.json`);
|
|
14
|
+
|
|
15
|
+
if (leanwebJSONExisted) {
|
|
16
|
+
console.error('Error: leanweb.json existed.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!packageJSONExisted) {
|
|
21
|
+
utils.exec(`npm init -y`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let projectName = path.basename(path.resolve());
|
|
25
|
+
|
|
26
|
+
if (args.length >= 3) {
|
|
27
|
+
projectName = args[2];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const leanwebData = {
|
|
31
|
+
name: projectName,
|
|
32
|
+
version: lwPackage.version,
|
|
33
|
+
components: [],
|
|
34
|
+
imports: [],
|
|
35
|
+
resources: [
|
|
36
|
+
'resources/'
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const projectScss = `// html,
|
|
41
|
+
// body {
|
|
42
|
+
// height: 100%;
|
|
43
|
+
// width: 100%;
|
|
44
|
+
// margin: 0 auto;
|
|
45
|
+
// padding: 0;
|
|
46
|
+
|
|
47
|
+
// font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
|
48
|
+
// }
|
|
49
|
+
`
|
|
50
|
+
|
|
51
|
+
const globalScss = `// div {
|
|
52
|
+
// color: tomato;
|
|
53
|
+
// }
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
fs.mkdirSync(`${utils.dirs.src}/resources/`, { recursive: true });
|
|
57
|
+
fs.writeFileSync(`${utils.dirs.src}/leanweb.json`, JSON.stringify(leanwebData, null, 2));
|
|
58
|
+
|
|
59
|
+
utils.exec(`npm i -D @babel/runtime --loglevel=error`);
|
|
60
|
+
|
|
61
|
+
utils.exec(`npx lw generate root`);
|
|
62
|
+
|
|
63
|
+
fse.copySync(`${__dirname}/../templates/lib`, `./${utils.dirs.src}/lib/`);
|
|
64
|
+
|
|
65
|
+
let htmlString = fs.readFileSync(`${__dirname}/../templates/index.html`, 'utf8');
|
|
66
|
+
htmlString = htmlString.replace(/\$\{project\.name\}/g, projectName);
|
|
67
|
+
fs.writeFileSync(`./${utils.dirs.src}/index.html`, htmlString);
|
|
68
|
+
fs.writeFileSync(`./src/${projectName}.scss`, projectScss);
|
|
69
|
+
fs.writeFileSync(`./${utils.dirs.src}/global-styles.scss`, globalScss);
|
|
70
|
+
fse.copySync(`${__dirname}/../templates/favicon.svg`, `./${utils.dirs.src}/favicon.svg`);
|
|
71
|
+
fse.copySync(`${__dirname}/../templates/env.js`, `./${utils.dirs.src}/env.js`);
|
|
72
|
+
fse.copySync(`${__dirname}/../templates/env/`, `./${utils.dirs.src}/env/`);
|
|
73
|
+
|
|
74
|
+
if (!(fs.existsSync(`${process.cwd()}/.git/`) && fs.statSync(`${process.cwd()}/.git/`).isDirectory())) {
|
|
75
|
+
await git.init({ fs, dir: process.cwd() });
|
|
76
|
+
|
|
77
|
+
if (fs.existsSync(`${process.cwd()}/.gitignore`) && fs.statSync(`${process.cwd()}/.gitignore`).isFile()) {
|
|
78
|
+
fs.appendFileSync(`${process.cwd()}/.gitignore`, `\nnode_modules/\n${utils.dirs.build}/\n${utils.dirs.dist}/\n${utils.dirs.serve}/\n${utils.dirs.electron}/\n`, 'utf8');
|
|
79
|
+
} else {
|
|
80
|
+
fs.writeFileSync(`${process.cwd()}/.gitignore`, `node_modules/\n${utils.dirs.build}/\n${utils.dirs.dist}/\n${utils.dirs.serve}/\n${utils.dirs.electron}/\n`, 'utf8');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const paths = await globby(['./**', './**/.*'], { gitignore: true });
|
|
84
|
+
for (const filepath of paths) {
|
|
85
|
+
await git.add({ fs, dir: process.cwd(), filepath });
|
|
86
|
+
}
|
|
87
|
+
await git.commit({
|
|
88
|
+
fs,
|
|
89
|
+
dir: process.cwd(),
|
|
90
|
+
author: {
|
|
91
|
+
name: 'Leanweb',
|
|
92
|
+
email: 'leanweb@leanweb.app',
|
|
93
|
+
},
|
|
94
|
+
message: 'lw init'
|
|
95
|
+
});
|
|
96
|
+
console.log('\nSome useful commands:');
|
|
97
|
+
console.log('"lw s" to start the dev server.');
|
|
98
|
+
console.log('"lw d" to build for production. The output will be in dist/ directory.');
|
|
99
|
+
console.log('"lw g my-new-component" to generate a new standard web component.');
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const fse = require('fs-extra');
|
|
2
|
+
const utils = require('./utils.js');
|
|
3
|
+
const webpack = require('webpack');
|
|
4
|
+
const watch = require('node-watch');
|
|
5
|
+
const WebpackDevServer = require('webpack-dev-server');
|
|
6
|
+
|
|
7
|
+
let env = '';
|
|
8
|
+
const args = process.argv;
|
|
9
|
+
if (args.length >= 3) {
|
|
10
|
+
env = args[2];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const address = process.env.address || '127.0.0.1';
|
|
14
|
+
let port = process.env.port || 2020;
|
|
15
|
+
const noopen = process.env.noopen || false;
|
|
16
|
+
|
|
17
|
+
(async () => {
|
|
18
|
+
|
|
19
|
+
const project = require(`${process.cwd()}/${utils.dirs.src}/leanweb.json`);
|
|
20
|
+
|
|
21
|
+
const build = async (eventType, filename) => {
|
|
22
|
+
// console.log(eventType + ': ', filename);
|
|
23
|
+
try {
|
|
24
|
+
await utils.exec(`npx lw build ${env}`);
|
|
25
|
+
fse.copySync(`./${utils.dirs.build}/index.html`, `./${utils.dirs.serve}/index.html`);
|
|
26
|
+
fse.copySync(`./${utils.dirs.build}/${project.name}.css`, `./${utils.dirs.serve}/${project.name}.css`);
|
|
27
|
+
fse.copySync(`./${utils.dirs.build}/favicon.svg`, `./${utils.dirs.serve}/favicon.svg`);
|
|
28
|
+
project.resources?.forEach(resource => {
|
|
29
|
+
fse.copySync(`./${utils.dirs.build}/${resource}`, `./${utils.dirs.serve}/${resource}`);
|
|
30
|
+
});
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.error(e);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const throttledBuild = utils.throttle(build);
|
|
37
|
+
watch(process.cwd() + `/${utils.dirs.src}/`, { recursive: true }, (eventType, filename) => {
|
|
38
|
+
throttledBuild(eventType, filename);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
build();
|
|
42
|
+
|
|
43
|
+
const webpackConfig = utils.getWebPackConfig(utils.dirs.serve, project);
|
|
44
|
+
|
|
45
|
+
const webpackDevConfig = {
|
|
46
|
+
...webpackConfig,
|
|
47
|
+
mode: 'development',
|
|
48
|
+
// watch: true,
|
|
49
|
+
devtool: 'eval-cheap-module-source-map',
|
|
50
|
+
performance: {
|
|
51
|
+
hints: false,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const compiler = webpack(webpackDevConfig);
|
|
56
|
+
|
|
57
|
+
const devServerOptions = {
|
|
58
|
+
...webpackDevConfig.devServer,
|
|
59
|
+
static: {
|
|
60
|
+
directory: process.cwd() + `/${utils.dirs.serve}/`,
|
|
61
|
+
watch: true,
|
|
62
|
+
},
|
|
63
|
+
open: !noopen,
|
|
64
|
+
};
|
|
65
|
+
const server = new WebpackDevServer(devServerOptions, compiler);
|
|
66
|
+
|
|
67
|
+
while (await utils.portInUse(port, address)) {
|
|
68
|
+
++port;
|
|
69
|
+
}
|
|
70
|
+
server.start(port, address);
|
|
71
|
+
})();
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const semver = require('semver');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const fse = require('fs-extra');
|
|
4
|
+
const utils = require('./utils.js');
|
|
5
|
+
|
|
6
|
+
const leanwebPackageJSON = require(`${__dirname}/../package.json`);
|
|
7
|
+
const projectLeanwebJSON = require(`${process.cwd()}/${utils.dirs.src}/leanweb.json`);
|
|
8
|
+
|
|
9
|
+
const upgradeTo045 = () => {
|
|
10
|
+
const projectName = projectLeanwebJSON.name;
|
|
11
|
+
projectLeanwebJSON.components.forEach(cmp => {
|
|
12
|
+
const component = projectName + '-' + cmp;
|
|
13
|
+
|
|
14
|
+
const filePath = process.cwd() + `/${utils.dirs.src}/components/` + cmp + '/' + cmp + '.js';
|
|
15
|
+
const oldSrc = fs.readFileSync(filePath, 'utf8');
|
|
16
|
+
const newSrc = oldSrc.replace(/import\s+interpolation\s+from\s+\'.\/ast\.js\';/, 'import ast from \'./ast.js\';')
|
|
17
|
+
.replace(/const\s+component\s+=\s+{\s+id\:\s+'.+?',\s+interpolation\s+};/, '')
|
|
18
|
+
.replace(/component\.id/g, '\'' + component + '\'')
|
|
19
|
+
.replace(/super\(component\);/, 'super(ast);');
|
|
20
|
+
fs.writeFileSync(filePath, newSrc);
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const upgradeTo081 = () => {
|
|
25
|
+
fse.copySync(`${__dirname}/../templates/env`, `./${utils.dirs.src}/env/`);
|
|
26
|
+
fse.copySync(`${__dirname}/../templates/env.js`, `./${utils.dirs.src}/env.js`);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const upgradeTo088 = () => {
|
|
30
|
+
utils.exec(`npm i -D @babel/runtime --loglevel=error`);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const upgradeAvailable = semver.gt(leanwebPackageJSON.version, projectLeanwebJSON.version);
|
|
34
|
+
if (upgradeAvailable) {
|
|
35
|
+
fse.copySync(`${__dirname}/../templates/lib`, `./${utils.dirs.src}/lib/`);
|
|
36
|
+
const oldVersion = projectLeanwebJSON.version;
|
|
37
|
+
projectLeanwebJSON.version = leanwebPackageJSON.version;
|
|
38
|
+
fs.writeFileSync(`${process.cwd()}/${utils.dirs.src}/leanweb.json`, JSON.stringify(projectLeanwebJSON, null, 2));
|
|
39
|
+
|
|
40
|
+
if (semver.gte(leanwebPackageJSON.version, '0.4.5') && semver.lt(oldVersion, '0.4.5')) {
|
|
41
|
+
upgradeTo045();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (semver.gte(leanwebPackageJSON.version, '0.8.1') && semver.lt(oldVersion, '0.8.1')) {
|
|
45
|
+
upgradeTo081();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (semver.gte(leanwebPackageJSON.version, '0.8.8') && semver.lt(oldVersion, '0.8.8')) {
|
|
49
|
+
upgradeTo088();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log('Leanweb upgraded:', oldVersion, '=>', leanwebPackageJSON.version);
|
|
53
|
+
}
|