neo.mjs 3.0.6 → 3.1.3
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/README.md +0 -2
- package/apps/covid/Util.mjs +3 -3
- package/apps/sharedcovid/Util.mjs +3 -3
- package/apps/sharedcovid/view/MainContainerController.mjs +1 -1
- package/apps/website/data/blog.json +26 -0
- package/buildScripts/buildAll.mjs +137 -0
- package/buildScripts/buildThemes.mjs +436 -0
- package/buildScripts/{copyFolder.js → copyFolder.mjs} +3 -5
- package/buildScripts/createApp.mjs +289 -0
- package/buildScripts/docs/{jsdocx.js → jsdocx.mjs} +32 -32
- package/buildScripts/webpack/buildMyApps.mjs +126 -0
- package/buildScripts/webpack/buildThreads.mjs +116 -0
- package/buildScripts/webpack/development/{webpack.config.appworker.js → webpack.config.appworker.mjs} +20 -22
- package/buildScripts/webpack/development/webpack.config.main.mjs +24 -0
- package/buildScripts/webpack/development/{webpack.config.myapps.js → webpack.config.myapps.mjs} +15 -15
- package/buildScripts/webpack/development/{webpack.config.worker.js → webpack.config.worker.mjs} +12 -9
- package/buildScripts/webpack/production/{webpack.config.appworker.js → webpack.config.appworker.mjs} +20 -22
- package/buildScripts/webpack/production/webpack.config.main.mjs +23 -0
- package/buildScripts/webpack/production/{webpack.config.myapps.js → webpack.config.myapps.mjs} +15 -15
- package/buildScripts/webpack/production/{webpack.config.worker.js → webpack.config.worker.mjs} +12 -9
- package/buildScripts/webpack/{webpack.server.config.js → webpack.server.config.mjs} +2 -2
- package/docs/app/view/classdetails/MembersList.mjs +7 -13
- package/package.json +14 -13
- package/src/DefaultConfig.mjs +1 -1
- package/src/Neo.mjs +13 -13
- package/src/core/Base.mjs +8 -6
- package/src/main/addon/AmCharts.mjs +2 -2
- package/src/manager/DomEvent.mjs +1 -1
- package/src/worker/Base.mjs +6 -5
- package/buildScripts/buildAll.js +0 -148
- package/buildScripts/buildThemes.js +0 -442
- package/buildScripts/createApp.js +0 -283
- package/buildScripts/webpack/buildMyApps.js +0 -125
- package/buildScripts/webpack/buildThreads.js +0 -112
- package/buildScripts/webpack/development/webpack.config.main.js +0 -21
- package/buildScripts/webpack/index.ejs +0 -25
- package/buildScripts/webpack/production/webpack.config.main.js +0 -20
package/README.md
CHANGED
|
@@ -19,8 +19,6 @@ No need to take care of a workers setup, and the cross channel communication on
|
|
|
19
19
|
<a href="https://youtu.be/aEA5333WiWY"><img height="316px" width="400px" src="https://raw.githubusercontent.com/neomjs/pages/master/resources/images/neo-movie.png"></a>
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
|
-
<a href="https://itnext.io/the-webworkers-driven-ui-framework-neo-mjs-version-2-release-announcement-b91b476d6f16?source=friends_link&sk=e6eb21f75475f431ad9215d63a44fb53">Version 2 release announcement</a>
|
|
23
|
-
|
|
24
22
|
## Content
|
|
25
23
|
1. <a href="#slack-channel">Slack Channel for questions & feedback</a>
|
|
26
24
|
2. <a href="#architectures">Scalable frontend architectures</a>
|
package/apps/covid/Util.mjs
CHANGED
|
@@ -135,16 +135,16 @@ class Util extends Base {
|
|
|
135
135
|
imageName = map[imageName] || imageName;
|
|
136
136
|
|
|
137
137
|
if (Neo.config.isGitHubPages) {
|
|
138
|
-
let path =
|
|
138
|
+
let path = `../../../../resources/images/flaticon/country_flags/png/${imageName}.png`;
|
|
139
139
|
|
|
140
140
|
if (Neo.config.environment !== 'development') {
|
|
141
|
-
path =
|
|
141
|
+
path = `../../${path}`;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
return path;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
return
|
|
147
|
+
return `https://raw.githubusercontent.com/neomjs/pages/master/resources/images/flaticon/country_flags/png/${imageName}.png`;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
@@ -135,16 +135,16 @@ class Util extends Base {
|
|
|
135
135
|
imageName = map[imageName] || imageName;
|
|
136
136
|
|
|
137
137
|
if (Neo.config.isGitHubPages) {
|
|
138
|
-
let path =
|
|
138
|
+
let path = `../../../../resources/images/flaticon/country_flags/png/${imageName}.png`;
|
|
139
139
|
|
|
140
140
|
if (Neo.config.environment !== 'development') {
|
|
141
|
-
path =
|
|
141
|
+
path = `../../${path}`;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
return path;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
return
|
|
147
|
+
return `https://raw.githubusercontent.com/neomjs/pages/master/resources/images/flaticon/country_flags/png/${imageName}.png`;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
@@ -167,7 +167,7 @@ class MainContainerController extends ComponentController {
|
|
|
167
167
|
|
|
168
168
|
Neo.Main.getWindowData().then(winData => {
|
|
169
169
|
me.component.getDomRect(me.getReference(containerReference).id).then(data => {
|
|
170
|
-
let {height, left, top, width} = data
|
|
170
|
+
let {height, left, top, width} = data;
|
|
171
171
|
|
|
172
172
|
height -= 50; // popup header in Chrome
|
|
173
173
|
left += winData.screenLeft;
|
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"author" : "Tobias Uhlig",
|
|
4
|
+
"authorImage" : "author_TobiasUhlig.jpeg",
|
|
5
|
+
"date" : "Jan 17, 2022",
|
|
6
|
+
"id" : 49,
|
|
7
|
+
"image" : "scaling-your-micro-frontends-off-the-main-thread.png",
|
|
8
|
+
"name" : "Scaling your micro-frontends off the main thread",
|
|
9
|
+
"provider" : "Medium",
|
|
10
|
+
"publisher" : "ITNEXT",
|
|
11
|
+
"selectedInto": [],
|
|
12
|
+
"type" : "Blog Post",
|
|
13
|
+
"url" : "https://itnext.io/scaling-your-micro-frontends-off-the-main-thread-36dedf54c5bf?source=friends_link&sk=04620ee92b04adb4dba22c8ec98d1ef6"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"author" : "Tobias Uhlig",
|
|
17
|
+
"authorImage" : "author_TobiasUhlig.jpeg",
|
|
18
|
+
"date" : "Jan 10, 2022",
|
|
19
|
+
"id" : 48,
|
|
20
|
+
"image" : "intercepting-component-state-to-ensure-smooth-animated-transitions.png",
|
|
21
|
+
"name" : "Intercepting component state to ensure smooth animated transitions",
|
|
22
|
+
"provider" : "Medium",
|
|
23
|
+
"publisher" : "ITNEXT",
|
|
24
|
+
"selectedInto": [],
|
|
25
|
+
"type" : "Blog Post",
|
|
26
|
+
"url" : "https://itnext.io/intercepting-component-state-to-ensure-smooth-animated-transitions-4facd46414dd?source=friends_link&sk=95a0eaef0e0b15dfc12ddd071479c61c"
|
|
27
|
+
},
|
|
2
28
|
{
|
|
3
29
|
"author" : "Tobias Uhlig",
|
|
4
30
|
"authorImage" : "author_TobiasUhlig.jpeg",
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawnSync } from 'child_process';
|
|
3
|
+
import { Command } from 'commander/esm.mjs';
|
|
4
|
+
import envinfo from 'envinfo';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const __dirname = fileURLToPath(path.dirname(import.meta.url)),
|
|
12
|
+
cwd = process.cwd(),
|
|
13
|
+
cpOpts = {env: process.env, cwd: cwd, stdio: 'inherit', shell: true},
|
|
14
|
+
npmCmd = os.platform().startsWith('win') ? 'npm.cmd' : 'npm', // npm binary based on OS
|
|
15
|
+
requireJson = path => JSON.parse(fs.readFileSync((path))),
|
|
16
|
+
packageJson = requireJson(path.join(__dirname, 'package.json')),
|
|
17
|
+
program = new Command(),
|
|
18
|
+
neoPath = path.resolve(packageJson.name === 'neo.mjs' ? './' : './node_modules/neo.mjs/'),
|
|
19
|
+
webpackPath = path.resolve(neoPath, 'buildScripts/webpack'),
|
|
20
|
+
programName = `${packageJson.name} buildAll`,
|
|
21
|
+
questions = [];
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.name(programName)
|
|
25
|
+
.version(packageJson.version)
|
|
26
|
+
.option('-i, --info', 'print environment debug info')
|
|
27
|
+
.option('-e, --env <value>', '"all", "dev", "prod"')
|
|
28
|
+
.option('-l, --npminstall <value>', '"yes", "no"')
|
|
29
|
+
.option('-f, --framework')
|
|
30
|
+
.option('-n, --noquestions')
|
|
31
|
+
.option('-p, --parsedocs <value>', '"yes", "no"')
|
|
32
|
+
.option('-t, --themes <value>', '"yes", "no"')
|
|
33
|
+
.option('-w, --threads <value>', '"yes", "no"')
|
|
34
|
+
.allowUnknownOption()
|
|
35
|
+
.on('--help', () => {
|
|
36
|
+
console.log('\nIn case you have any issues, please create a ticket here:');
|
|
37
|
+
console.log(chalk.cyan(packageJson.bugs.url));
|
|
38
|
+
})
|
|
39
|
+
.parse(process.argv);
|
|
40
|
+
|
|
41
|
+
const programOpts = program.opts();
|
|
42
|
+
|
|
43
|
+
if (programOpts.info) {
|
|
44
|
+
console.log(chalk.bold('\nEnvironment Info:'));
|
|
45
|
+
console.log(`\n current version of ${packageJson.name}: ${packageJson.version}`);
|
|
46
|
+
console.log(` running from ${__dirname}`);
|
|
47
|
+
|
|
48
|
+
envinfo
|
|
49
|
+
.run({
|
|
50
|
+
System : ['OS', 'CPU'],
|
|
51
|
+
Binaries : ['Node', 'npm', 'Yarn'],
|
|
52
|
+
Browsers : ['Chrome', 'Edge', 'Firefox', 'Safari'],
|
|
53
|
+
npmPackages: ['neo.mjs']
|
|
54
|
+
}, {
|
|
55
|
+
duplicates : true,
|
|
56
|
+
showNotFound: true
|
|
57
|
+
})
|
|
58
|
+
.then(console.log);
|
|
59
|
+
} else {
|
|
60
|
+
console.log(chalk.green(programName));
|
|
61
|
+
|
|
62
|
+
if (!programOpts.noquestions) {
|
|
63
|
+
if (!programOpts.npminstall) {
|
|
64
|
+
questions.push({
|
|
65
|
+
type : 'list',
|
|
66
|
+
name : 'npminstall',
|
|
67
|
+
message: 'Run npm install?:',
|
|
68
|
+
choices: ['yes', 'no'],
|
|
69
|
+
default: 'all'
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!programOpts.env) {
|
|
74
|
+
questions.push({
|
|
75
|
+
type : 'list',
|
|
76
|
+
name : 'env',
|
|
77
|
+
message: 'Please choose the environment:',
|
|
78
|
+
choices: ['all', 'dev', 'prod'],
|
|
79
|
+
default: 'all'
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!programOpts.npminstall) {
|
|
84
|
+
questions.push({
|
|
85
|
+
type : 'list',
|
|
86
|
+
name : 'themes',
|
|
87
|
+
message: 'Build the themes?',
|
|
88
|
+
choices: ['yes', 'no'],
|
|
89
|
+
default: 'yes'
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!programOpts.threads) {
|
|
94
|
+
questions.push({
|
|
95
|
+
type : 'list',
|
|
96
|
+
name : 'threads',
|
|
97
|
+
message: 'Build the threads?',
|
|
98
|
+
choices: ['yes', 'no'],
|
|
99
|
+
default: 'yes'
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!programOpts.parsedocs) {
|
|
104
|
+
questions.push({
|
|
105
|
+
type : 'list',
|
|
106
|
+
name : 'parsedocs',
|
|
107
|
+
message: 'Trigger the jsdocx parsing?',
|
|
108
|
+
choices: ['yes', 'no'],
|
|
109
|
+
default: 'yes'
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
inquirer.prompt(questions).then(answers => {
|
|
115
|
+
const env = answers.env || programOpts.env || 'all',
|
|
116
|
+
npminstall = answers.npminstall || programOpts.npminstall || 'yes',
|
|
117
|
+
parsedocs = answers.parsedocs || programOpts.parsedocs || 'yes',
|
|
118
|
+
themes = answers.themes || programOpts.themes || 'yes',
|
|
119
|
+
threads = answers.threads || programOpts.threads || 'yes',
|
|
120
|
+
insideNeo = !!programOpts.framework || false,
|
|
121
|
+
cpArgs = ['-e', env],
|
|
122
|
+
startDate = new Date();
|
|
123
|
+
|
|
124
|
+
programOpts.noquestions && cpArgs.push('-n');
|
|
125
|
+
insideNeo && cpArgs.push('-f');
|
|
126
|
+
|
|
127
|
+
npminstall === 'yes' && spawnSync(npmCmd, ['i'], cpOpts);
|
|
128
|
+
themes === 'yes' && spawnSync('node', [`${neoPath}/buildScripts/buildThemes.mjs`].concat(cpArgs), cpOpts);
|
|
129
|
+
threads === 'yes' && spawnSync('node', [`${webpackPath}/buildThreads.mjs`] .concat(cpArgs), cpOpts);
|
|
130
|
+
parsedocs === 'yes' && spawnSync(npmCmd, ['run', 'generate-docs-json'], cpOpts);
|
|
131
|
+
|
|
132
|
+
const processTime = (Math.round((new Date - startDate) * 100) / 100000).toFixed(2);
|
|
133
|
+
console.log(`\nTotal time for ${programName}: ${processTime}s`);
|
|
134
|
+
|
|
135
|
+
process.exit(0);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import autoprefixer from 'autoprefixer';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import cssnano from 'cssnano';
|
|
4
|
+
import { Command } from 'commander/esm.mjs';
|
|
5
|
+
import envinfo from 'envinfo';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import postcss from 'postcss';
|
|
10
|
+
import sass from 'sass';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = fileURLToPath(path.dirname(import.meta.url)),
|
|
14
|
+
cwd = process.cwd(),
|
|
15
|
+
requireJson = path => JSON.parse(fs.readFileSync((path))),
|
|
16
|
+
packageJson = requireJson(path.resolve(cwd, 'package.json')),
|
|
17
|
+
neoPath = packageJson.name === 'neo.mjs' ? './' : './node_modules/neo.mjs/',
|
|
18
|
+
programName = `${packageJson.name} buildThemes`,
|
|
19
|
+
program = new Command(),
|
|
20
|
+
regexComments = /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm,
|
|
21
|
+
regexLineBreak = /(\r\n|\n|\r)/gm,
|
|
22
|
+
regexSassImport = /@import[^'"]+?['"](.+?)['"];?/g,
|
|
23
|
+
scssFolders = fs.readdirSync(path.join(neoPath, '/resources/scss')),
|
|
24
|
+
scssPath = 'resources/scss/',
|
|
25
|
+
themeMapFile = 'resources/theme-map.json',
|
|
26
|
+
themeMapFileNoVars = 'resources/theme-map-no-vars.json',
|
|
27
|
+
themeFolders = [],
|
|
28
|
+
questions = [];
|
|
29
|
+
|
|
30
|
+
scssFolders.forEach(folder => {
|
|
31
|
+
if (folder.includes('theme')) {
|
|
32
|
+
themeFolders.push(folder);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
program
|
|
37
|
+
.name(programName)
|
|
38
|
+
.version(packageJson.version)
|
|
39
|
+
.option('-i, --info', 'print environment debug info')
|
|
40
|
+
.option('-c, --cssVars <value>', '"all", "true", "false"')
|
|
41
|
+
.option('-e, --env <value>', '"all", "dev", "prod"')
|
|
42
|
+
.option('-f, --framework')
|
|
43
|
+
.option('-n, --noquestions')
|
|
44
|
+
.option('-t, --themes <value>', ["all", ...themeFolders].join(", "))
|
|
45
|
+
.allowUnknownOption()
|
|
46
|
+
.on('--help', () => {
|
|
47
|
+
console.log('\nIn case you have any issues, please create a ticket here:');
|
|
48
|
+
console.log(chalk.cyan(packageJson.bugs.url));
|
|
49
|
+
})
|
|
50
|
+
.parse(process.argv);
|
|
51
|
+
|
|
52
|
+
const programOpts = program.opts();
|
|
53
|
+
|
|
54
|
+
if (programOpts.info) {
|
|
55
|
+
console.log(chalk.bold('\nEnvironment Info:'));
|
|
56
|
+
console.log(`\n current version of ${packageJson.name}: ${packageJson.version}`);
|
|
57
|
+
console.log(` running from ${__dirname}`);
|
|
58
|
+
|
|
59
|
+
envinfo
|
|
60
|
+
.run({
|
|
61
|
+
System : ['OS', 'CPU'],
|
|
62
|
+
Binaries : ['Node', 'npm', 'Yarn'],
|
|
63
|
+
Browsers : ['Chrome', 'Edge', 'Firefox', 'Safari'],
|
|
64
|
+
npmPackages : ['neo.mjs'],
|
|
65
|
+
npmGlobalPackages: ['neo-app']
|
|
66
|
+
}, {
|
|
67
|
+
duplicates : true,
|
|
68
|
+
showNotFound: true
|
|
69
|
+
})
|
|
70
|
+
.then(console.log);
|
|
71
|
+
} else {
|
|
72
|
+
console.log(chalk.green(programName));
|
|
73
|
+
|
|
74
|
+
if (!programOpts.noquestions) {
|
|
75
|
+
if (!programOpts.themes) {
|
|
76
|
+
questions.push({
|
|
77
|
+
type : 'list',
|
|
78
|
+
name : 'themes',
|
|
79
|
+
message: 'Please choose the themes to build:',
|
|
80
|
+
choices: ['all', ...themeFolders],
|
|
81
|
+
default: 'all'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!programOpts.env) {
|
|
86
|
+
questions.push({
|
|
87
|
+
type : 'list',
|
|
88
|
+
name : 'env',
|
|
89
|
+
message: 'Please choose the environment:',
|
|
90
|
+
choices: ['all', 'dev', 'prod'],
|
|
91
|
+
default: 'all'
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!programOpts.cssVars) {
|
|
96
|
+
questions.push({
|
|
97
|
+
type : 'list',
|
|
98
|
+
name : 'cssVars',
|
|
99
|
+
message: 'Build using CSS variables?',
|
|
100
|
+
choices: ['all', 'yes', 'no'],
|
|
101
|
+
default: 'yes'
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
inquirer.prompt(questions).then(answers => {
|
|
107
|
+
const cssVars = answers.cssVars || programOpts.cssVars || 'all',
|
|
108
|
+
env = answers.env || programOpts.env || 'all',
|
|
109
|
+
themes = answers.themes || programOpts.themes || 'all',
|
|
110
|
+
insideNeo = programOpts.framework || false,
|
|
111
|
+
startDate = new Date(),
|
|
112
|
+
fileCount = {development: {vars: 0, noVars: 0}, production: {vars: 0, noVars: 0}},
|
|
113
|
+
totalFiles = {development: {vars: 0, noVars: 0}, production: {vars: 0, noVars: 0}},
|
|
114
|
+
sassThemes = [];
|
|
115
|
+
|
|
116
|
+
let themeMap, themeMapNoVars;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {Object} file
|
|
120
|
+
* @param {String} target
|
|
121
|
+
* @param {Boolean} useCssVars
|
|
122
|
+
*/
|
|
123
|
+
function addItemToThemeMap(file, target, useCssVars) {
|
|
124
|
+
let classPath = file.className.split('.'),
|
|
125
|
+
fileName = classPath.pop(),
|
|
126
|
+
namespace;
|
|
127
|
+
|
|
128
|
+
classPath = classPath.join('.');
|
|
129
|
+
namespace = ns(classPath, true, useCssVars ? themeMap : themeMapNoVars);
|
|
130
|
+
|
|
131
|
+
if (!namespace[fileName]) {
|
|
132
|
+
namespace[fileName] = [target];
|
|
133
|
+
} else {
|
|
134
|
+
if (!namespace[fileName].includes(target)) {
|
|
135
|
+
namespace[fileName].push(target);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param {String} p
|
|
142
|
+
* @param {String} mode development or production
|
|
143
|
+
*/
|
|
144
|
+
function buildEnv(p, mode) {
|
|
145
|
+
if (cssVars !== 'no') {
|
|
146
|
+
parseScssFiles(getAllScssFiles(path.join(p, 'src')), mode, 'src', true);
|
|
147
|
+
|
|
148
|
+
themeFolders.forEach(themeFolder => {
|
|
149
|
+
if (themes === 'all' || themes === themeFolder) {
|
|
150
|
+
parseScssFiles(getAllScssFiles(path.join(p, themeFolder)), mode, themeFolder, true);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (cssVars !== 'yes') {
|
|
156
|
+
themeFolders.forEach(themeFolder => {
|
|
157
|
+
if (themes === 'all' || themes === themeFolder) {
|
|
158
|
+
parseScssFiles(getAllScssFiles(path.join(p, 'src')), mode, themeFolder, false);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @param {String} dirPath
|
|
166
|
+
* @returns {Object[]}
|
|
167
|
+
*/
|
|
168
|
+
function getAllScssFiles(dirPath) {
|
|
169
|
+
const files = getScssFiles(path.resolve(neoPath, dirPath));
|
|
170
|
+
|
|
171
|
+
if (!insideNeo) {
|
|
172
|
+
files.push(...getScssFiles(path.resolve(cwd, dirPath)));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return files;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {String} dirPath
|
|
180
|
+
* @param [arrayOfFiles=[]]
|
|
181
|
+
* @param [relativePath='']
|
|
182
|
+
* @returns {Object[]}
|
|
183
|
+
*/
|
|
184
|
+
function getScssFiles(dirPath, arrayOfFiles=[], relativePath='') {
|
|
185
|
+
let files = fs.readdirSync(dirPath),
|
|
186
|
+
className, fileInfo, filePath;
|
|
187
|
+
|
|
188
|
+
files.forEach(file => {
|
|
189
|
+
filePath = path.join(dirPath + '/' + file);
|
|
190
|
+
|
|
191
|
+
if (fs.statSync(filePath).isDirectory()) {
|
|
192
|
+
arrayOfFiles = getScssFiles(filePath, arrayOfFiles, relativePath + '/' + file);
|
|
193
|
+
} else {
|
|
194
|
+
fileInfo = path.parse(file);
|
|
195
|
+
|
|
196
|
+
if (!fileInfo.name.startsWith('_')) {
|
|
197
|
+
className = relativePath === '' ? fileInfo.name : `${relativePath.substring(1)}/${fileInfo.name}`;
|
|
198
|
+
className = className.split('/').join('.');
|
|
199
|
+
|
|
200
|
+
if (className.startsWith('apps.')) {
|
|
201
|
+
className = className.split('.');
|
|
202
|
+
className[0].toLowerCase();
|
|
203
|
+
className = className.join('.');
|
|
204
|
+
} else {
|
|
205
|
+
className = 'Neo.' + className;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
arrayOfFiles.push({
|
|
209
|
+
className,
|
|
210
|
+
name: fileInfo.name,
|
|
211
|
+
path: filePath,
|
|
212
|
+
relativePath
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return arrayOfFiles;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @param {String} filePath
|
|
223
|
+
* @returns {Object}
|
|
224
|
+
*/
|
|
225
|
+
function getThemeMap(filePath) {
|
|
226
|
+
let themeMapJson = path.resolve(cwd, filePath),
|
|
227
|
+
themeMap;
|
|
228
|
+
|
|
229
|
+
if (fs.existsSync(themeMapJson)) {
|
|
230
|
+
themeMap = requireJson(themeMapJson);
|
|
231
|
+
} else {
|
|
232
|
+
themeMapJson = path.resolve(neoPath, filePath);
|
|
233
|
+
|
|
234
|
+
if (fs.existsSync(themeMapJson)) {
|
|
235
|
+
themeMap = requireJson(themeMapJson);
|
|
236
|
+
} else {
|
|
237
|
+
themeMap = {};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return themeMap;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @param {Array|String} names The class name string containing dots or an Array of the string parts
|
|
246
|
+
* @param {Boolean} [create] Set create to true to create empty objects for non existing parts
|
|
247
|
+
* @param {Object} [scope] Set a different starting point as globalThis
|
|
248
|
+
* @returns {Object} reference to the toplevel namespace
|
|
249
|
+
*/
|
|
250
|
+
function ns(names, create, scope) {
|
|
251
|
+
names = Array.isArray(names) ? names : names.split('.');
|
|
252
|
+
|
|
253
|
+
return names.reduce((prev, current) => {
|
|
254
|
+
if (create && !prev[current]) {
|
|
255
|
+
prev[current] = {};
|
|
256
|
+
}
|
|
257
|
+
if (prev) {
|
|
258
|
+
return prev[current];
|
|
259
|
+
}
|
|
260
|
+
}, scope || globalThis);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {Object[]} files
|
|
265
|
+
* @param {String} mode development or production
|
|
266
|
+
* @param {String} target src or a theme
|
|
267
|
+
* @param {Boolean} useCssVars
|
|
268
|
+
*/
|
|
269
|
+
function parseScssFiles(files, mode, target, useCssVars) {
|
|
270
|
+
let data = '',
|
|
271
|
+
devMode = mode === 'development',
|
|
272
|
+
mixinPath = path.resolve(neoPath, 'resources/scss/mixins/_all.scss'),
|
|
273
|
+
suffix = useCssVars ? '' : '-no-vars',
|
|
274
|
+
varsFlag = useCssVars ? 'vars' : 'noVars',
|
|
275
|
+
map, neoThemePath, themeBuffer, themePath, workspaceThemePath;
|
|
276
|
+
|
|
277
|
+
totalFiles[mode][varsFlag] += files.length;
|
|
278
|
+
|
|
279
|
+
if (path.sep === '\\') {
|
|
280
|
+
mixinPath = mixinPath.replace(/\\/g, '/');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (target.includes('theme')) {
|
|
284
|
+
themePath = `resources/scss/${target}/_all.scss`;
|
|
285
|
+
neoThemePath = path.resolve(neoPath, themePath);
|
|
286
|
+
|
|
287
|
+
if (!sassThemes[target]) {
|
|
288
|
+
themeBuffer = scssCombine(fs.readFileSync(neoThemePath).toString(), path.dirname(neoThemePath));
|
|
289
|
+
|
|
290
|
+
if (!insideNeo) {
|
|
291
|
+
workspaceThemePath = path.resolve(cwd, themePath);
|
|
292
|
+
themeBuffer += scssCombine(fs.readFileSync(workspaceThemePath).toString(), path.dirname(workspaceThemePath));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
themeBuffer = themeBuffer.replace(regexComments, '');
|
|
296
|
+
themeBuffer = themeBuffer.replace(regexLineBreak, '');
|
|
297
|
+
|
|
298
|
+
sassThemes[target] = themeBuffer;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
data = [
|
|
302
|
+
`@use "sass:map";`,
|
|
303
|
+
`@use "sass:math";`,
|
|
304
|
+
`$neoMap: ();`,
|
|
305
|
+
`$useCssVars: ${useCssVars};`,
|
|
306
|
+
`@import "${mixinPath}";`,
|
|
307
|
+
`$useCssVars: false;`,
|
|
308
|
+
`${sassThemes[target]}`,
|
|
309
|
+
`$useCssVars: ${useCssVars};`
|
|
310
|
+
].join('');
|
|
311
|
+
} else {
|
|
312
|
+
data = [
|
|
313
|
+
`@use "sass:map";`,
|
|
314
|
+
`@use "sass:math";`,
|
|
315
|
+
`$neoMap: ();`,
|
|
316
|
+
`$useCssVars: ${useCssVars};`,
|
|
317
|
+
`@import "${mixinPath}";`
|
|
318
|
+
].join('');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
files.forEach(file => {
|
|
322
|
+
addItemToThemeMap(file, target, useCssVars);
|
|
323
|
+
|
|
324
|
+
let folderPath = path.resolve(cwd, `dist/${mode}/css${suffix}/${target}/${file.relativePath}`),
|
|
325
|
+
destPath = path.resolve(folderPath, `${file.name}.css`);
|
|
326
|
+
|
|
327
|
+
fs.readFile(file.path).then(content => {
|
|
328
|
+
let result = sass.renderSync({
|
|
329
|
+
data : data + scssCombine(content.toString(), path.resolve(neoPath, scssPath, target, file.relativePath)),
|
|
330
|
+
outFile : destPath,
|
|
331
|
+
sourceMap : devMode,
|
|
332
|
+
sourceMapEmbed: false
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const plugins = [autoprefixer];
|
|
336
|
+
|
|
337
|
+
if (mode === 'production') {
|
|
338
|
+
plugins.push(cssnano);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
map = result.map?.toString();
|
|
342
|
+
|
|
343
|
+
if (map) {
|
|
344
|
+
// https://github.com/neomjs/neo/issues/1970
|
|
345
|
+
map = JSON.parse(map);
|
|
346
|
+
let len = file.relativePath.split('/').length,
|
|
347
|
+
src = `${target}${file.relativePath}/${file.name}.scss`,
|
|
348
|
+
i = 0;
|
|
349
|
+
|
|
350
|
+
for (; i < len; i++) {
|
|
351
|
+
src = '../' + src;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
map.sources = [src];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
postcss(plugins).process(result.css, {
|
|
358
|
+
from: file.path,
|
|
359
|
+
to : destPath,
|
|
360
|
+
map : !devMode ? null : {
|
|
361
|
+
prev: map && JSON.stringify(map)
|
|
362
|
+
}
|
|
363
|
+
}).then(result => {
|
|
364
|
+
fs.mkdirpSync(folderPath);
|
|
365
|
+
fileCount[mode][varsFlag]++;
|
|
366
|
+
|
|
367
|
+
const processTime = (Math.round((new Date - startDate) * 100) / 100000).toFixed(2);
|
|
368
|
+
console.log('Writing file:', (fileCount[mode].vars + fileCount[mode].noVars), chalk.blue(`${processTime}s`), destPath);
|
|
369
|
+
fs.writeFileSync(destPath, result.css, () => true);
|
|
370
|
+
|
|
371
|
+
if (result.map) {
|
|
372
|
+
fs.writeFileSync(result.opts.to + '.map', result.map.toString());
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (fileCount[mode][varsFlag] === totalFiles[mode][varsFlag]) {
|
|
376
|
+
fs.writeFileSync(
|
|
377
|
+
path.resolve(cwd, useCssVars ? themeMapFile : themeMapFileNoVars),
|
|
378
|
+
JSON.stringify(useCssVars ? themeMap : themeMapNoVars, null, 0)
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
fs.mkdirpSync(path.join(cwd, '/dist/', mode, '/resources'), {
|
|
382
|
+
recursive: true
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
fs.writeFileSync(
|
|
386
|
+
path.join(cwd, '/dist/', mode, useCssVars ? themeMapFile : themeMapFileNoVars),
|
|
387
|
+
JSON.stringify(useCssVars ? themeMap : themeMapNoVars, null, 0)
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {String} content
|
|
397
|
+
* @param {String} baseDir
|
|
398
|
+
* @returns {String}
|
|
399
|
+
*/
|
|
400
|
+
function scssCombine (content, baseDir) {
|
|
401
|
+
if (regexSassImport.test(content)) {
|
|
402
|
+
content = content.replace(regexSassImport, (m, capture) => {
|
|
403
|
+
let parse = path.parse(path.resolve(baseDir, capture)),
|
|
404
|
+
file = path.resolve(`${parse.dir}/${parse.name}.scss`);
|
|
405
|
+
|
|
406
|
+
if (!fs.existsSync(file)) {
|
|
407
|
+
file = path.resolve(`${parse.dir}/_${parse.name}.scss`);
|
|
408
|
+
|
|
409
|
+
if (!fs.existsSync(file)) {
|
|
410
|
+
return '';
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return scssCombine(fs.readFileSync(file).toString(), path.dirname(file));
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return content;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (cssVars !== 'no') {themeMap = getThemeMap(themeMapFile);}
|
|
422
|
+
if (cssVars !== 'yes') {themeMapNoVars = getThemeMap(themeMapFileNoVars);}
|
|
423
|
+
|
|
424
|
+
// dist/development
|
|
425
|
+
if (env === 'all' || env === 'dev') {
|
|
426
|
+
console.log(chalk.blue(`${programName} starting dist/development`));
|
|
427
|
+
buildEnv(scssPath, 'development');
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// dist/production
|
|
431
|
+
if (env === 'all' || env === 'prod') {
|
|
432
|
+
console.log(chalk.blue(`${programName} starting dist/production`));
|
|
433
|
+
buildEnv(scssPath, 'production');
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { Command } from 'commander/esm.mjs';
|
|
2
|
+
import fs from 'fs-extra';
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
fs = require('fs-extra');
|
|
5
|
-
|
|
6
|
-
const program = new commander.Command('copyFolder')
|
|
4
|
+
const program = new Command('copyFolder')
|
|
7
5
|
.version('1.0.0')
|
|
8
6
|
.option('-s, --source <value>', 'path to the source folder')
|
|
9
7
|
.option('-t, --target <value>', 'path to the target folder')
|