@qse/edu-scripts 1.13.1 → 1.13.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/CHANGELOG.md +13 -0
- package/docs/override.md +10 -4
- package/docs/static.md +1 -1
- package/lib/auto-refactor.js +1 -18
- package/lib/build.js +0 -18
- package/lib/cli.js +4 -4
- package/lib/commit-dist.js +1 -21
- package/lib/config/babel.dependencies.js +3 -6
- package/lib/config/babel.js +3 -11
- package/lib/config/paths.js +0 -6
- package/lib/config/plugins/postcss-safe-area.js +1 -4
- package/lib/config/webpackConfig.js +13 -29
- package/lib/config/webpackDevServerConfig.js +2 -3
- package/lib/deploy.js +18 -42
- package/lib/generator.js +2 -25
- package/lib/index.js +0 -1
- package/lib/start.js +3 -11
- package/lib/utils/FileSizeReporter.js +8 -25
- package/lib/utils/appConfig.js +0 -11
- package/lib/utils/beforeStart.js +0 -18
- package/lib/utils/changeDeployVersion.js +6 -27
- package/lib/utils/defineConfig.d.ts +3 -3
- package/lib/utils/defineConfig.js +0 -1
- package/lib/utils/exec.js +0 -2
- package/lib/utils/getConfig.js +0 -9
- package/lib/utils/getOverride.js +2 -7
- package/package.json +36 -36
- package/src/deploy.js +1 -1
package/lib/deploy.js
CHANGED
|
@@ -3,23 +3,14 @@
|
|
|
3
3
|
const {
|
|
4
4
|
sshSftp
|
|
5
5
|
} = require('@qse/ssh-sftp');
|
|
6
|
-
|
|
7
6
|
const path = require('path');
|
|
8
|
-
|
|
9
7
|
const paths = require('./config/paths');
|
|
10
|
-
|
|
11
8
|
const pkg = require(paths.package);
|
|
12
|
-
|
|
13
9
|
const chalk = require('chalk');
|
|
14
|
-
|
|
15
10
|
const fs = require('fs-extra');
|
|
16
|
-
|
|
17
11
|
const changeDeployVersion = require('./utils/changeDeployVersion');
|
|
18
|
-
|
|
19
12
|
const ora = require('ora');
|
|
20
|
-
|
|
21
13
|
const appConfig = require('./utils/appConfig');
|
|
22
|
-
|
|
23
14
|
const baseConfig = {
|
|
24
15
|
localPath: 'dist',
|
|
25
16
|
ignore: [],
|
|
@@ -28,7 +19,6 @@ const baseConfig = {
|
|
|
28
19
|
keepAlive: true,
|
|
29
20
|
noWarn: true
|
|
30
21
|
};
|
|
31
|
-
|
|
32
22
|
async function normalDeploy(args) {
|
|
33
23
|
const presetConfig = {
|
|
34
24
|
s: {
|
|
@@ -44,8 +34,8 @@ async function normalDeploy(args) {
|
|
|
44
34
|
folder: 'documentshelves'
|
|
45
35
|
}
|
|
46
36
|
};
|
|
47
|
-
|
|
48
37
|
const resolve = (...pathSegments) => path.resolve(process.cwd(), ...pathSegments);
|
|
38
|
+
|
|
49
39
|
/**
|
|
50
40
|
* 生成路径
|
|
51
41
|
* @name remoteFile 远程文件
|
|
@@ -54,8 +44,6 @@ async function normalDeploy(args) {
|
|
|
54
44
|
* @name tmpBase 本地临时文件夹 到`__tmp__`层
|
|
55
45
|
* @param {string} remoteFilePath 远程文件相对`opts.remotePath`地址
|
|
56
46
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
47
|
function getLocalAndRemoteFilePath(remoteFilePath, opts) {
|
|
60
48
|
const splited = remoteFilePath.split('/');
|
|
61
49
|
const fileName = splited[splited.length - 1];
|
|
@@ -70,36 +58,32 @@ async function normalDeploy(args) {
|
|
|
70
58
|
tmpBase
|
|
71
59
|
};
|
|
72
60
|
}
|
|
73
|
-
|
|
74
61
|
function dateTime() {
|
|
75
62
|
let date = new Date();
|
|
76
63
|
date = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
|
|
77
64
|
return date.toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
|
78
65
|
}
|
|
79
|
-
|
|
80
66
|
function updateLogContent(content, info) {
|
|
81
67
|
const lines = content.trim().split('\n');
|
|
82
68
|
lines.push(`[${dateTime()}] ${JSON.stringify(info)}\n`);
|
|
83
|
-
return lines.slice(
|
|
69
|
+
return lines.slice(-50).join('\n');
|
|
84
70
|
}
|
|
85
|
-
|
|
86
71
|
async function upload(opts) {
|
|
87
72
|
// 上传dist文件
|
|
88
73
|
const {
|
|
89
74
|
sftp,
|
|
90
75
|
opts: fullOpts
|
|
91
76
|
} = await sshSftp(opts);
|
|
92
|
-
const spinner = ora('自动更新 ver.js 版本配置').start();
|
|
93
|
-
|
|
94
|
-
const fileName = 'js/ver.js';
|
|
95
|
-
|
|
77
|
+
const spinner = ora('自动更新 ver.js 版本配置').start();
|
|
78
|
+
// 指定远程需要修改的文件
|
|
79
|
+
const fileName = 'js/ver.js';
|
|
80
|
+
// 生成各种路径
|
|
96
81
|
const {
|
|
97
82
|
remoteFile,
|
|
98
83
|
tmpDir,
|
|
99
84
|
tmpFile,
|
|
100
85
|
tmpBase
|
|
101
86
|
} = getLocalAndRemoteFilePath(fileName, fullOpts);
|
|
102
|
-
|
|
103
87
|
try {
|
|
104
88
|
// 创建本地临时文件夹,位置在 `opts.localPath` 下的 `__tmp__` 文件夹
|
|
105
89
|
fs.mkdirSync(tmpDir, {
|
|
@@ -112,27 +96,26 @@ async function normalDeploy(args) {
|
|
|
112
96
|
};
|
|
113
97
|
{
|
|
114
98
|
// 拉取远程文件到本地
|
|
115
|
-
await sftp.fastGet(remoteFile, tmpFile);
|
|
99
|
+
await sftp.fastGet(remoteFile, tmpFile);
|
|
116
100
|
|
|
101
|
+
// 读取本地文件内容
|
|
117
102
|
let code = await fs.readFile(tmpFile, {
|
|
118
103
|
encoding: 'utf-8'
|
|
119
104
|
});
|
|
120
105
|
code = changeDeployVersion(code, info);
|
|
121
106
|
await sftp.fastPut(tmpFile, remoteFile + '.bak');
|
|
122
|
-
await fs.writeFile(tmpFile, code);
|
|
123
|
-
|
|
107
|
+
await fs.writeFile(tmpFile, code);
|
|
108
|
+
// 将修改完的内容传回服务器
|
|
124
109
|
await sftp.fastPut(tmpFile, remoteFile);
|
|
125
110
|
}
|
|
126
111
|
{
|
|
127
112
|
const remoteLogFile = remoteFile + '.log';
|
|
128
113
|
const tmpLogFile = tmpFile + '.log';
|
|
129
114
|
let content = '';
|
|
130
|
-
|
|
131
115
|
try {
|
|
132
116
|
await sftp.fastGet(remoteLogFile, tmpLogFile);
|
|
133
117
|
content = await fs.readFile(tmpLogFile, 'utf-8');
|
|
134
118
|
} catch (error) {}
|
|
135
|
-
|
|
136
119
|
content = updateLogContent(content, info);
|
|
137
120
|
await fs.writeFile(tmpLogFile, content);
|
|
138
121
|
await sftp.fastPut(tmpLogFile, remoteLogFile);
|
|
@@ -142,26 +125,21 @@ async function normalDeploy(args) {
|
|
|
142
125
|
spinner.fail(`自动修改 ver.js 失败,请手动修改`);
|
|
143
126
|
console.log(chalk.bgRed(e.message));
|
|
144
127
|
} finally {
|
|
145
|
-
await sftp.end();
|
|
146
|
-
|
|
128
|
+
await sftp.end();
|
|
129
|
+
// 清除临时文件夹
|
|
147
130
|
fs.removeSync(tmpBase);
|
|
148
131
|
}
|
|
149
132
|
}
|
|
150
|
-
|
|
151
133
|
const presets = [];
|
|
152
|
-
|
|
153
134
|
if (args.b) {
|
|
154
135
|
presets.push(presetConfig.b);
|
|
155
136
|
}
|
|
156
|
-
|
|
157
137
|
if (args.s) {
|
|
158
138
|
presets.push(presetConfig.s);
|
|
159
139
|
}
|
|
160
|
-
|
|
161
140
|
if (args.d) {
|
|
162
141
|
presets.push(presetConfig.d);
|
|
163
142
|
}
|
|
164
|
-
|
|
165
143
|
if (presets.length === 0) {
|
|
166
144
|
console.log(`
|
|
167
145
|
${chalk.red('指定 deploy 部署范围')}
|
|
@@ -177,24 +155,23 @@ async function normalDeploy(args) {
|
|
|
177
155
|
`);
|
|
178
156
|
process.exit();
|
|
179
157
|
}
|
|
180
|
-
|
|
181
|
-
|
|
158
|
+
const uploadConfig = {
|
|
159
|
+
...baseConfig,
|
|
182
160
|
ignore: [...baseConfig.ignore, 'js/ver.js']
|
|
183
161
|
};
|
|
184
|
-
|
|
185
162
|
if (!appConfig.mainProject) {
|
|
186
163
|
uploadConfig.ignore = [...uploadConfig.ignore, '!(js|images)'];
|
|
187
164
|
}
|
|
188
|
-
|
|
189
165
|
for (const preset of presets) {
|
|
190
|
-
await upload({
|
|
166
|
+
await upload({
|
|
167
|
+
...uploadConfig,
|
|
191
168
|
preset
|
|
192
169
|
});
|
|
193
170
|
}
|
|
194
171
|
}
|
|
195
|
-
|
|
196
172
|
async function singleDeploy() {
|
|
197
|
-
const config = fs.existsSync(paths.sshSftp) ? fs.readJsonSync(paths.sshSftp) : {
|
|
173
|
+
const config = fs.existsSync(paths.sshSftp) ? fs.readJsonSync(paths.sshSftp) : {
|
|
174
|
+
...baseConfig,
|
|
198
175
|
preset: {
|
|
199
176
|
context: 'qsxxwapdev'
|
|
200
177
|
},
|
|
@@ -205,7 +182,6 @@ async function singleDeploy() {
|
|
|
205
182
|
};
|
|
206
183
|
sshSftp(config);
|
|
207
184
|
}
|
|
208
|
-
|
|
209
185
|
module.exports = function deploy(args) {
|
|
210
186
|
if (appConfig.single) {
|
|
211
187
|
singleDeploy();
|
package/lib/generator.js
CHANGED
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
|
-
|
|
5
4
|
const fs = require('fs-extra');
|
|
6
|
-
|
|
7
5
|
const {
|
|
8
6
|
upperFirst,
|
|
9
7
|
camelCase,
|
|
10
8
|
has
|
|
11
9
|
} = require('lodash');
|
|
12
|
-
|
|
13
10
|
const paths = require('./config/paths');
|
|
14
|
-
|
|
15
11
|
const chalk = require('chalk');
|
|
12
|
+
|
|
16
13
|
/**
|
|
17
14
|
* @param {string[]} args
|
|
18
15
|
* @returns {string}
|
|
19
16
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
17
|
const getTmpPath = (...args) => path.resolve(__dirname, 'asset', 'template', ...args);
|
|
23
|
-
|
|
24
18
|
function genFile({
|
|
25
19
|
source,
|
|
26
20
|
target,
|
|
@@ -28,15 +22,14 @@ function genFile({
|
|
|
28
22
|
replace
|
|
29
23
|
}) {
|
|
30
24
|
let content = fs.readFileSync(source, 'utf-8');
|
|
31
|
-
|
|
32
25
|
if (typeof replace === 'object') {
|
|
33
26
|
Object.entries(replace).forEach(([searchValue, replaceValue]) => {
|
|
34
27
|
content = content.replaceAll(searchValue, replaceValue);
|
|
35
28
|
});
|
|
36
29
|
}
|
|
37
|
-
|
|
38
30
|
fs.writeFileSync(path.resolve(modulePath, target), content);
|
|
39
31
|
}
|
|
32
|
+
|
|
40
33
|
/**
|
|
41
34
|
* @typedef {Object} PageArgs
|
|
42
35
|
* @property {string} name
|
|
@@ -46,8 +39,6 @@ function genFile({
|
|
|
46
39
|
*
|
|
47
40
|
* @param {PageArgs} args
|
|
48
41
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
42
|
async function generatorPage(args) {
|
|
52
43
|
const tmpPath = getTmpPath('page', 'index.[type].[ext].tpl');
|
|
53
44
|
const lessPath = tmpPath.replace('[type].[ext]', 'less');
|
|
@@ -80,7 +71,6 @@ async function generatorPage(args) {
|
|
|
80
71
|
modulePath,
|
|
81
72
|
replace
|
|
82
73
|
});
|
|
83
|
-
|
|
84
74
|
if (type === 'class' && ext === 'js') {
|
|
85
75
|
genFile({
|
|
86
76
|
source: logicPath,
|
|
@@ -89,7 +79,6 @@ async function generatorPage(args) {
|
|
|
89
79
|
replace
|
|
90
80
|
});
|
|
91
81
|
}
|
|
92
|
-
|
|
93
82
|
if (args.route) {
|
|
94
83
|
genFile({
|
|
95
84
|
source: routePath,
|
|
@@ -98,55 +87,43 @@ async function generatorPage(args) {
|
|
|
98
87
|
replace
|
|
99
88
|
});
|
|
100
89
|
}
|
|
101
|
-
|
|
102
90
|
console.log(chalk.green([`生成完毕:`, `import ${ModuleName} from '@/pages/${moduleName}'`, `const ${ModuleName} = lazy(() => import(/* webpackChunkName: '${moduleName}' */ '@/pages/${moduleName}'))`, `{ path: '/${moduleName}', element: <${ModuleName} /> },`].join('\n')));
|
|
103
91
|
}
|
|
104
|
-
|
|
105
92
|
async function generatorOverride() {
|
|
106
93
|
if (fs.existsSync(paths.override)) {
|
|
107
94
|
console.log(chalk.red(`文件已存在 ${paths.override}`));
|
|
108
95
|
process.exit(0);
|
|
109
96
|
}
|
|
110
|
-
|
|
111
97
|
fs.copySync(getTmpPath('edu-scripts.override.js.tpl'), paths.override);
|
|
112
98
|
console.log(chalk.green(`成功生成 ${paths.override}`));
|
|
113
99
|
}
|
|
114
|
-
|
|
115
100
|
async function generatorTsconfig() {
|
|
116
101
|
if (fs.existsSync(paths.tsconfig)) {
|
|
117
102
|
console.log(chalk.red(`文件已存在 ${paths.tsconfig}`));
|
|
118
103
|
process.exit(0);
|
|
119
104
|
}
|
|
120
|
-
|
|
121
105
|
fs.copySync(getTmpPath('tsconfig.json.tpl'), paths.tsconfig);
|
|
122
106
|
fs.copySync(getTmpPath('edu-app-env.d.ts.tpl'), paths.eduAppEnv);
|
|
123
107
|
console.log(chalk.green(`成功生成 ${paths.tsconfig}`));
|
|
124
108
|
}
|
|
125
|
-
|
|
126
109
|
async function generatorTailwind() {
|
|
127
110
|
if (fs.existsSync(paths.tailwind)) {
|
|
128
111
|
console.log(chalk.red(`文件已存在 ${paths.tailwind}`));
|
|
129
112
|
process.exit(0);
|
|
130
113
|
}
|
|
131
|
-
|
|
132
114
|
fs.copySync(getTmpPath('tailwind.config.js.tpl'), paths.tailwind);
|
|
133
115
|
const code = ['@tailwind base;', '@tailwind components;', '@tailwind utilities;'].join('\n');
|
|
134
116
|
const globalLessFile = paths.resolveApp('src', 'index.less');
|
|
135
|
-
|
|
136
117
|
if (fs.existsSync(globalLessFile)) {
|
|
137
118
|
const content = fs.readFileSync(globalLessFile, 'utf-8');
|
|
138
|
-
|
|
139
119
|
if (!content.includes('@tailwind base')) {
|
|
140
120
|
fs.writeFileSync(globalLessFile, [code, content].join('\n'));
|
|
141
121
|
}
|
|
142
|
-
|
|
143
122
|
console.log(chalk.green(`成功生成 ${paths.tailwind}`));
|
|
144
123
|
return;
|
|
145
124
|
}
|
|
146
|
-
|
|
147
125
|
console.log(chalk.green([`成功生成 ${paths.tailwind}`, '', '添加以下代码到入口处的 index.less 中', code].join('\n')));
|
|
148
126
|
}
|
|
149
|
-
|
|
150
127
|
module.exports = {
|
|
151
128
|
page: generatorPage,
|
|
152
129
|
override: generatorOverride,
|
package/lib/index.js
CHANGED
package/lib/start.js
CHANGED
|
@@ -3,32 +3,25 @@
|
|
|
3
3
|
process.env.NODE_ENV = 'development';
|
|
4
4
|
process.env.BABEL_ENV = 'development';
|
|
5
5
|
process.env.BROWSERSLIST = 'chrome >= 70';
|
|
6
|
-
process.env.WEBPACK_DEV_SERVER_BASE_PORT = '3000';
|
|
6
|
+
process.env.WEBPACK_DEV_SERVER_BASE_PORT = '3000';
|
|
7
|
+
|
|
8
|
+
// Makes the script crash on unhandled rejections instead of silently
|
|
7
9
|
// ignoring them. In the future, promise rejections that are not handled will
|
|
8
10
|
// terminate the Node.js process with a non-zero exit code.
|
|
9
|
-
|
|
10
11
|
process.on('unhandledRejection', err => {
|
|
11
12
|
throw err;
|
|
12
13
|
});
|
|
13
|
-
|
|
14
14
|
const WebpackDevServer = require('webpack-dev-server');
|
|
15
|
-
|
|
16
15
|
const webpack = require('webpack');
|
|
17
|
-
|
|
18
16
|
const getConfig = require('./utils/getConfig');
|
|
19
|
-
|
|
20
17
|
const chalk = require('chalk');
|
|
21
|
-
|
|
22
18
|
process.env.WDS_SOCKET_HOST = WebpackDevServer.internalIPSync('v4') || '127.0.0.1';
|
|
23
|
-
|
|
24
19
|
module.exports = async function start(args) {
|
|
25
20
|
const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT;
|
|
26
21
|
const port = await WebpackDevServer.getFreePort(args.port || process.env.PORT);
|
|
27
|
-
|
|
28
22
|
if (!(args.port || process.env.PORT) && +port !== +basePort) {
|
|
29
23
|
console.log(chalk.bgYellow(`${basePort} 端口已被占用,现切换到 ${port} 端口运行`));
|
|
30
24
|
}
|
|
31
|
-
|
|
32
25
|
process.env.WDS_SOCKET_PORT = port;
|
|
33
26
|
args.port = port;
|
|
34
27
|
const compiler = webpack(getConfig(args));
|
|
@@ -40,7 +33,6 @@ module.exports = async function start(args) {
|
|
|
40
33
|
process.exit();
|
|
41
34
|
});
|
|
42
35
|
});
|
|
43
|
-
|
|
44
36
|
if (process.env.CI !== 'true') {
|
|
45
37
|
// Gracefully exit when stdin ends
|
|
46
38
|
process.stdin.on('end', function () {
|
|
@@ -6,25 +6,19 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
var fs = require('fs');
|
|
10
9
|
|
|
10
|
+
var fs = require('fs');
|
|
11
11
|
var path = require('path');
|
|
12
|
-
|
|
13
12
|
var chalk = require('chalk');
|
|
14
|
-
|
|
15
13
|
var filesize = require('filesize');
|
|
16
|
-
|
|
17
14
|
var recursive = require('recursive-readdir');
|
|
18
|
-
|
|
19
15
|
var stripAnsi = require('strip-ansi');
|
|
20
|
-
|
|
21
16
|
var gzipSize = require('gzip-size').sync;
|
|
22
|
-
|
|
23
17
|
function canReadAsset(asset) {
|
|
24
18
|
return /\.(js|css)$/.test(asset) && !/service-worker\.js/.test(asset) && !/precache-manifest\.[0-9a-f]+\.js/.test(asset);
|
|
25
|
-
}
|
|
26
|
-
|
|
19
|
+
}
|
|
27
20
|
|
|
21
|
+
// Prints a detailed summary of build files.
|
|
28
22
|
function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, maxBundleGzipSize, maxChunkGzipSize) {
|
|
29
23
|
var root = previousSizeMap.root;
|
|
30
24
|
var sizes = previousSizeMap.sizes;
|
|
@@ -43,8 +37,9 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
|
|
|
43
37
|
sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '')
|
|
44
38
|
};
|
|
45
39
|
})).reduce((single, all) => all.concat(single), []);
|
|
46
|
-
assets.sort((a, b) => b.size - a.size);
|
|
40
|
+
assets.sort((a, b) => b.size - a.size);
|
|
47
41
|
|
|
42
|
+
// move main file to first
|
|
48
43
|
var mainAssetIdx = assets.findIndex(asset => /_\d+\.\d+\.\d+\./.test(asset.name));
|
|
49
44
|
assets.unshift(assets.splice(mainAssetIdx, 1)[0]);
|
|
50
45
|
var longestSizeLabelLength = Math.max.apply(null, assets.map(a => stripAnsi(a.sizeLabel).length));
|
|
@@ -52,27 +47,21 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
|
|
|
52
47
|
assets.forEach(asset => {
|
|
53
48
|
var sizeLabel = asset.sizeLabel;
|
|
54
49
|
var sizeLength = stripAnsi(sizeLabel).length;
|
|
55
|
-
|
|
56
50
|
if (sizeLength < longestSizeLabelLength) {
|
|
57
51
|
var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
|
|
58
52
|
sizeLabel += rightPadding;
|
|
59
53
|
}
|
|
60
|
-
|
|
61
54
|
var isMainBundle = /_\d+\.\d+\.\d+\./.test(asset.name);
|
|
62
55
|
var maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize;
|
|
63
56
|
var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
|
|
64
|
-
|
|
65
57
|
if (isLarge && path.extname(asset.name) === '.js') {
|
|
66
58
|
suggestBundleSplitting = true;
|
|
67
59
|
}
|
|
68
|
-
|
|
69
60
|
console.log(' ' + (isLarge ? chalk.yellow(sizeLabel) : sizeLabel) + ' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name));
|
|
70
|
-
|
|
71
61
|
if (isMainBundle) {
|
|
72
62
|
console.log('');
|
|
73
63
|
}
|
|
74
64
|
});
|
|
75
|
-
|
|
76
65
|
if (suggestBundleSplitting) {
|
|
77
66
|
console.log();
|
|
78
67
|
console.log(chalk.yellow('产物大小明显大于推荐的大小 (主文件 30k, chunk 1M, 黄色标注为偏大)'));
|
|
@@ -80,18 +69,16 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
|
|
|
80
69
|
console.log(chalk.yellow('也可以使用 npm run analyze 命令分析产物'));
|
|
81
70
|
}
|
|
82
71
|
}
|
|
83
|
-
|
|
84
72
|
function removeFileNameHash(buildFolder, fileName) {
|
|
85
73
|
return fileName.replace(buildFolder, '').replace(/\\/g, '/').replace(/\/\d+\.\d+\.\d+\//, '/').replace(/\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/, (match, p1, p2, p3, p4) => p1 + p4);
|
|
86
|
-
}
|
|
87
|
-
// Output: "(+1 KB)"
|
|
88
|
-
|
|
74
|
+
}
|
|
89
75
|
|
|
76
|
+
// Input: 1024, 2048
|
|
77
|
+
// Output: "(+1 KB)"
|
|
90
78
|
function getDifferenceLabel(currentSize, previousSize) {
|
|
91
79
|
var FIFTY_KILOBYTES = 1024 * 50;
|
|
92
80
|
var difference = currentSize - previousSize;
|
|
93
81
|
var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
|
|
94
|
-
|
|
95
82
|
if (difference >= FIFTY_KILOBYTES) {
|
|
96
83
|
return chalk.red('+' + fileSize);
|
|
97
84
|
} else if (difference < FIFTY_KILOBYTES && difference > 0) {
|
|
@@ -102,12 +89,10 @@ function getDifferenceLabel(currentSize, previousSize) {
|
|
|
102
89
|
return '';
|
|
103
90
|
}
|
|
104
91
|
}
|
|
105
|
-
|
|
106
92
|
function measureFileSizesBeforeBuild(buildFolder) {
|
|
107
93
|
return new Promise(resolve => {
|
|
108
94
|
recursive(buildFolder, (err, fileNames) => {
|
|
109
95
|
var sizes;
|
|
110
|
-
|
|
111
96
|
if (!err && fileNames) {
|
|
112
97
|
sizes = fileNames.filter(canReadAsset).reduce((memo, fileName) => {
|
|
113
98
|
var contents = fs.readFileSync(fileName);
|
|
@@ -116,7 +101,6 @@ function measureFileSizesBeforeBuild(buildFolder) {
|
|
|
116
101
|
return memo;
|
|
117
102
|
}, {});
|
|
118
103
|
}
|
|
119
|
-
|
|
120
104
|
resolve({
|
|
121
105
|
root: buildFolder,
|
|
122
106
|
sizes: sizes || {}
|
|
@@ -124,7 +108,6 @@ function measureFileSizesBeforeBuild(buildFolder) {
|
|
|
124
108
|
});
|
|
125
109
|
});
|
|
126
110
|
}
|
|
127
|
-
|
|
128
111
|
module.exports = {
|
|
129
112
|
measureFileSizesBeforeBuild: measureFileSizesBeforeBuild,
|
|
130
113
|
printFileSizesAfterBuild: printFileSizesAfterBuild
|
package/lib/utils/appConfig.js
CHANGED
|
@@ -1,44 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const paths = require('../config/paths');
|
|
4
|
-
|
|
5
4
|
const appPkg = require(paths.package);
|
|
6
|
-
|
|
7
5
|
const fs = require('fs');
|
|
8
|
-
|
|
9
6
|
const edu = appPkg.edu || {};
|
|
10
|
-
|
|
11
7
|
if (edu.single || edu.mainProject) {
|
|
12
8
|
if (edu.single) {
|
|
13
9
|
edu.mode = 'single';
|
|
14
10
|
delete edu.single;
|
|
15
11
|
}
|
|
16
|
-
|
|
17
12
|
if (edu.mainProject) {
|
|
18
13
|
edu.mode = 'main';
|
|
19
14
|
delete edu.mainProject;
|
|
20
15
|
}
|
|
21
|
-
|
|
22
16
|
fs.writeFileSync(paths.package, JSON.stringify(appPkg, null, 2), 'utf-8');
|
|
23
17
|
}
|
|
24
|
-
|
|
25
18
|
const appConfig = {
|
|
26
19
|
/** @type {'main'|'single'} */
|
|
27
20
|
get mode() {
|
|
28
21
|
return edu.mode;
|
|
29
22
|
},
|
|
30
|
-
|
|
31
23
|
get mainProject() {
|
|
32
24
|
return this.mode === 'main';
|
|
33
25
|
},
|
|
34
|
-
|
|
35
26
|
get single() {
|
|
36
27
|
return this.mode === 'single';
|
|
37
28
|
},
|
|
38
|
-
|
|
39
29
|
get grayscale() {
|
|
40
30
|
return !!edu.grayscale;
|
|
41
31
|
}
|
|
42
|
-
|
|
43
32
|
};
|
|
44
33
|
module.exports = appConfig;
|
package/lib/utils/beforeStart.js
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
|
|
5
4
|
const paths = require('../config/paths');
|
|
6
|
-
|
|
7
5
|
const chalk = require('chalk');
|
|
8
|
-
|
|
9
6
|
const pkg = require('../../package.json');
|
|
10
|
-
|
|
11
7
|
const updateNotifier = require('update-notifier');
|
|
12
|
-
|
|
13
8
|
const semver = require('semver');
|
|
14
|
-
|
|
15
9
|
const notifier = updateNotifier({
|
|
16
10
|
pkg,
|
|
17
11
|
shouldNotifyInNpmScript: true,
|
|
18
12
|
updateCheckInterval: 1000 * 60 // 时刻保持更新
|
|
19
|
-
|
|
20
13
|
});
|
|
21
14
|
|
|
22
15
|
if (notifier.update && ['minor', 'major'].includes(notifier.update.type)) {
|
|
@@ -26,38 +19,29 @@ if (notifier.update && ['minor', 'major'].includes(notifier.update.type)) {
|
|
|
26
19
|
});
|
|
27
20
|
process.exit(1);
|
|
28
21
|
}
|
|
29
|
-
|
|
30
22
|
const appPkg = require(paths.package);
|
|
31
|
-
|
|
32
23
|
const appConfig = require('./appConfig');
|
|
33
|
-
|
|
34
24
|
if (semver.valid(appPkg.version) === null) {
|
|
35
25
|
console.log(chalk.red(`package.version 不符合 semver 规范 https://docs.npmjs.com/about-semantic-versioning`));
|
|
36
26
|
process.exit(1);
|
|
37
27
|
}
|
|
38
|
-
|
|
39
28
|
switch (appConfig.mode) {
|
|
40
29
|
case 'main':
|
|
41
30
|
console.log(chalk.bgMagenta('正在使用教育主工程模式'));
|
|
42
31
|
break;
|
|
43
|
-
|
|
44
32
|
case 'single':
|
|
45
33
|
console.log(chalk.bgMagenta('正在使用独立项目模式'));
|
|
46
34
|
break;
|
|
47
|
-
|
|
48
35
|
default:
|
|
49
36
|
console.log(chalk.bgMagenta('正在使用教育集成模式'));
|
|
50
37
|
break;
|
|
51
38
|
}
|
|
52
|
-
|
|
53
39
|
if (appConfig.grayscale) {
|
|
54
40
|
console.log(chalk.bgYellow('正在使用灰度测试模式'));
|
|
55
41
|
}
|
|
56
|
-
|
|
57
42
|
if (!(appConfig.single || appConfig.mainProject)) {
|
|
58
43
|
if (fs.existsSync(paths.static)) {
|
|
59
44
|
console.log(chalk.bgYellow('教育集成工程不能含有 public/static, 现已自动删除'));
|
|
60
|
-
|
|
61
45
|
try {
|
|
62
46
|
fs.rmSync(paths.static, {
|
|
63
47
|
recursive: true
|
|
@@ -65,14 +49,12 @@ if (!(appConfig.single || appConfig.mainProject)) {
|
|
|
65
49
|
} catch (e) {}
|
|
66
50
|
}
|
|
67
51
|
}
|
|
68
|
-
|
|
69
52
|
if (!fs.existsSync(paths.public) && !process.argv.includes('auto-refactor')) {
|
|
70
53
|
console.log(chalk.red(`public 文件夹不存在,请先按文档改造项目`));
|
|
71
54
|
console.log(`文档: ${chalk.underline(pkg.homepage)}`);
|
|
72
55
|
console.log(`\n使用 ${chalk.green('npx edu-scripts auto-refactor')} 自动改造\n`);
|
|
73
56
|
process.exit(0);
|
|
74
57
|
}
|
|
75
|
-
|
|
76
58
|
if (appPkg.browserslist) {
|
|
77
59
|
console.log(chalk.yellow('已删除 package.json 中 browserslist,该值由内部自动控制\n'));
|
|
78
60
|
delete appPkg.browserslist;
|