@airiot/cli 1.0.5 → 1.0.7
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/config/paths.js +2 -0
- package/package.json +2 -1
- package/scripts/build.js +27 -1
- package/scripts/eslint.js +7 -2
- package/scripts/i18n-scanner.js +0 -4
- package/scripts/install.js +2 -1
- package/scripts/pack.js +2 -1
- package/vite-plugin/buildinfo.js +42 -1
- package/vite-plugin/index.js +2 -2
- package/vite-plugin/plugin.js +106 -30
package/config/paths.js
CHANGED
|
@@ -56,6 +56,7 @@ export default {
|
|
|
56
56
|
dotenv: resolveApp('.env'),
|
|
57
57
|
appPath: resolveApp('.'),
|
|
58
58
|
buildPath: resolveApp('dist'),
|
|
59
|
+
buildEsPath: resolveApp('es'),
|
|
59
60
|
appHtml: resolveDevtool('dist/index.html'),
|
|
60
61
|
appIndexJs: resolveModule(resolveApp, 'src/index'),
|
|
61
62
|
appFrontJs: resolveModule(resolveApp, 'src/front'),
|
|
@@ -73,6 +74,7 @@ export default {
|
|
|
73
74
|
proxySetup: resolveApp('src/setupProxy.js'),
|
|
74
75
|
appNodeModules,
|
|
75
76
|
clientBuildPath: path.resolve(appNodeModules, '@gtiot/iot-client/dist'),
|
|
77
|
+
clientBuildEsPath: path.resolve(appNodeModules, '@gtiot/iot-client/es'),
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
export { moduleFileExtensions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@airiot/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "AIRIOT平台前端包管理工具",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {},
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@eslint/js": "^9.39.0",
|
|
29
|
+
"@npmcli/arborist": "^9.1.6",
|
|
29
30
|
"@vitejs/plugin-legacy": "^7.2.1",
|
|
30
31
|
"@vitejs/plugin-react": "^5.1.0",
|
|
31
32
|
"archiver": "^7.0.1",
|
package/scripts/build.js
CHANGED
|
@@ -29,18 +29,44 @@ import { visualizer } from 'rollup-plugin-visualizer';
|
|
|
29
29
|
if (process.env.ANALYZE === 'true' || analyze) {
|
|
30
30
|
plugins.push(
|
|
31
31
|
visualizer({
|
|
32
|
-
filename:
|
|
32
|
+
filename: '.build_stats.html',
|
|
33
33
|
title: 'Build Analysis',
|
|
34
34
|
open: true,
|
|
35
35
|
})
|
|
36
36
|
)
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
let outDir = 'es'
|
|
40
|
+
for (let i = 0; i < args.length; i++) {
|
|
41
|
+
const a = args[i];
|
|
42
|
+
if (a === '-o' || a === '--out' || a === '--outDir') {
|
|
43
|
+
const v = args[i + 1];
|
|
44
|
+
if (v && !v.startsWith('-')) {
|
|
45
|
+
outDir = v;
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (a.startsWith('-o=')) {
|
|
51
|
+
outDir = a.slice(3);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
if (a.startsWith('--out=')) {
|
|
55
|
+
outDir = a.split('=')[1];
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
if (a.startsWith('--outDir=')) {
|
|
59
|
+
outDir = a.split('=')[1];
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
38
63
|
|
|
39
64
|
await build({
|
|
40
65
|
configFile: false,
|
|
41
66
|
root: paths.appPath,
|
|
42
67
|
base: '',
|
|
43
68
|
build: {
|
|
69
|
+
outDir,
|
|
44
70
|
assetsDir: '',
|
|
45
71
|
assetsInlineLimit: 0,
|
|
46
72
|
cssCodeSplit: true,
|
package/scripts/eslint.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLint } from 'eslint';
|
|
2
|
-
|
|
2
|
+
import chalk from 'chalk';
|
|
3
3
|
import overrideConfig from '../config/eslint.config.js';
|
|
4
4
|
|
|
5
5
|
const args = process.argv.slice(2);
|
|
@@ -31,5 +31,10 @@ const eslint = new ESLint({
|
|
|
31
31
|
}
|
|
32
32
|
const formatter = await eslint.loadFormatter('stylish');
|
|
33
33
|
const resultText = formatter.format(results);
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
if(resultText) {
|
|
36
|
+
console.log(resultText);
|
|
37
|
+
} else {
|
|
38
|
+
console.log(chalk.green('✓' + ' eslint 检测没有发现任何问题。'))
|
|
39
|
+
}
|
|
35
40
|
})();
|
package/scripts/i18n-scanner.js
CHANGED
|
@@ -6,10 +6,6 @@ import paths from '../config/paths.js';
|
|
|
6
6
|
|
|
7
7
|
const input = [
|
|
8
8
|
'src/**/*.{js,jsx}',
|
|
9
|
-
// Use ! to filter out files or directories
|
|
10
|
-
'!src/**/*.spec.{js,jsx}',
|
|
11
|
-
'!src/i18n/**',
|
|
12
|
-
'!**/node_modules/**',
|
|
13
9
|
].map(p => path.resolve(paths.appPath, p));
|
|
14
10
|
|
|
15
11
|
const options = {
|
package/scripts/install.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
3
|
import pacote from "pacote";
|
|
4
|
+
import Arborist from '@npmcli/arborist';
|
|
4
5
|
import os from "os";
|
|
5
6
|
import fs from "fs";
|
|
6
7
|
import fetch from "node-fetch";
|
|
@@ -80,7 +81,7 @@ inquirer
|
|
|
80
81
|
}
|
|
81
82
|
const token = `Bearer ${json.accessToken}`;
|
|
82
83
|
|
|
83
|
-
const data = await pacote.tarball(paths.appPath);
|
|
84
|
+
const data = await pacote.tarball("file:" + paths.appPath, { Arborist });
|
|
84
85
|
|
|
85
86
|
const form = new FormData();
|
|
86
87
|
|
package/scripts/pack.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pacote from 'pacote';
|
|
2
2
|
import paths from "../config/paths.js";
|
|
3
|
+
import Arborist from '@npmcli/arborist';
|
|
3
4
|
|
|
4
|
-
pacote.tarball.file(paths.appPath, 'package.tgz').then(data => {
|
|
5
|
+
pacote.tarball.file("file:" + paths.appPath, 'package.tgz', { Arborist }).then(data => {
|
|
5
6
|
console.log('生成包文件成功')
|
|
6
7
|
})
|
package/vite-plugin/buildinfo.js
CHANGED
|
@@ -9,7 +9,6 @@ const isCI = process.env.CI &&
|
|
|
9
9
|
|
|
10
10
|
const jsonData = await fsPromises.readFile(paths.appPackageJson, 'utf-8');
|
|
11
11
|
const appPackage = JSON.parse(jsonData);
|
|
12
|
-
appPackage.dependencies = {}
|
|
13
12
|
|
|
14
13
|
const gitInfo = (...args) => {
|
|
15
14
|
return execFileSync('git', args, {
|
|
@@ -52,12 +51,54 @@ const buildinfoPlugin = () => {
|
|
|
52
51
|
if (config.command === 'serve') {
|
|
53
52
|
return
|
|
54
53
|
}
|
|
54
|
+
// check package.json exports and files
|
|
55
|
+
try {
|
|
56
|
+
appPackage.exports = appPackage.exports || {}
|
|
57
|
+
|
|
58
|
+
if (!appPackage.exports.airiot) {
|
|
59
|
+
const inputs = config.build && config.build.rollupOptions && config.build.rollupOptions.input
|
|
60
|
+
const outputTemplate = config.build && config.build.rollupOptions && config.build.rollupOptions.output && config.build.rollupOptions.output.entryFileNames
|
|
61
|
+
? config.build.rollupOptions.output.entryFileNames
|
|
62
|
+
: '[name].js'
|
|
63
|
+
const outDirName = (config.build && config.build.outDir) ? config.build.outDir : 'dist'
|
|
64
|
+
const makeFileName = (name) => outputTemplate.replace(/\[name\]/g, name)
|
|
65
|
+
|
|
66
|
+
const exportsObj = {}
|
|
67
|
+
|
|
68
|
+
if (inputs && typeof inputs === 'object') {
|
|
69
|
+
for (const name of Object.keys(inputs)) {
|
|
70
|
+
const fileName = makeFileName(name)
|
|
71
|
+
const exportKey = name
|
|
72
|
+
const relPath = './' + join(outDirName, fileName).replace(/\\/g, '/') + '?type=module'
|
|
73
|
+
exportsObj[exportKey] = relPath
|
|
74
|
+
}
|
|
75
|
+
} else if (typeof inputs === 'string') {
|
|
76
|
+
const base = 'index'
|
|
77
|
+
const fileName = makeFileName(base)
|
|
78
|
+
exportsObj[base] = './' + join(outDirName, fileName).replace(/\\/g, '/') + '?type=module'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
appPackage.exports.airiot = exportsObj
|
|
82
|
+
|
|
83
|
+
// ensure files includes outDir so published package contains built files
|
|
84
|
+
appPackage.files = Array.isArray(appPackage.files) ? appPackage.files : []
|
|
85
|
+
if (!appPackage.files.includes(outDirName)) {
|
|
86
|
+
appPackage.files.push(outDirName)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
writeFileSync(paths.appPackageJson, JSON.stringify(appPackage, 0, 2), { flag: 'w' })
|
|
90
|
+
}
|
|
91
|
+
} catch (e) {
|
|
92
|
+
// silently ignore errors here
|
|
93
|
+
}
|
|
55
94
|
|
|
56
95
|
if (!isCI) {
|
|
57
96
|
try {
|
|
58
97
|
gitInfo('log')
|
|
59
98
|
const branch = gitInfo('rev-parse', '--abbrev-ref', 'HEAD')
|
|
60
99
|
const longHead = gitInfo('rev-parse', 'HEAD')
|
|
100
|
+
|
|
101
|
+
appPackage.dependencies = {}
|
|
61
102
|
appPackage.gitHead = longHead
|
|
62
103
|
|
|
63
104
|
if (branch != 'master' && branch != 'HEAD') {
|
package/vite-plugin/index.js
CHANGED
|
@@ -37,11 +37,11 @@ const getPlugins = async (mode) => {
|
|
|
37
37
|
}),
|
|
38
38
|
jsInJsxPlugin(),
|
|
39
39
|
svgInline(),
|
|
40
|
-
airiotPlugin(mode),
|
|
40
|
+
mode != 'build' && airiotPlugin(mode),
|
|
41
41
|
lazyImportPlugin(),
|
|
42
42
|
airiotHtmlPlugin(),
|
|
43
43
|
buildinfoPlugin()
|
|
44
|
-
]
|
|
44
|
+
].filter(Boolean)
|
|
45
45
|
|
|
46
46
|
try {
|
|
47
47
|
const appPlugin = await import(new URL(`file://${paths.appVitePlugin}`));
|
package/vite-plugin/plugin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import paths from '../config/paths.js'
|
|
2
2
|
import { promises as fsPromises } from 'fs';
|
|
3
|
+
import fetch from 'node-fetch';
|
|
3
4
|
import { getBaseUrl, getHost, developConfig } from '../config/envs.js';
|
|
4
5
|
|
|
5
6
|
const jsonData = await fsPromises.readFile(paths.appPackageJson, 'utf-8');
|
|
@@ -8,9 +9,10 @@ const htmlTpl = await fsPromises.readFile(paths.appHtml, 'utf-8');
|
|
|
8
9
|
const appPackage = JSON.parse(jsonData);
|
|
9
10
|
|
|
10
11
|
const findModule = (scripts, packageName) => {
|
|
11
|
-
return scripts.find(s => s.indexOf(packageName) >= 0)
|
|
12
|
+
return scripts.find(s => s.src && s.src.indexOf(packageName) >= 0)
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
const loadOnline = true
|
|
14
16
|
const host = getHost()
|
|
15
17
|
const basePath = getBaseUrl() + '/node_modules'
|
|
16
18
|
|
|
@@ -18,15 +20,11 @@ const defaultModules = [
|
|
|
18
20
|
'@airiot/i18n', '@airiot/theme', '@airiot/core'
|
|
19
21
|
]
|
|
20
22
|
|
|
21
|
-
let scripts
|
|
22
|
-
&& developConfig.scripts(basePath, 'admin') || []
|
|
23
|
+
let scripts, frontScripts;
|
|
23
24
|
|
|
24
|
-
let frontScripts = (developConfig && typeof developConfig.scripts == 'function')
|
|
25
|
-
&& developConfig.scripts(basePath, 'front') || []
|
|
26
|
-
|
|
27
|
-
let scriptsAppend = appPackage.name == '@airiot/core'
|
|
28
25
|
let dllScript = basePath + '/@airiot/dll/dist/iot.min.js',
|
|
29
26
|
dllDevScript = basePath + '/@airiot/dll/dist/iot.js';
|
|
27
|
+
|
|
30
28
|
const filterDll = s => {
|
|
31
29
|
if(s.indexOf("@airiot/dll") >= 0) {
|
|
32
30
|
dllScript = s
|
|
@@ -36,31 +34,109 @@ const filterDll = s => {
|
|
|
36
34
|
return true
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
frontScripts = frontScripts.filter(filterDll);
|
|
37
|
+
const loadPackageScripts = async () => {
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
39
|
+
scripts = (developConfig && typeof developConfig.scripts == 'function')
|
|
40
|
+
&& await developConfig.scripts(basePath, 'admin') || []
|
|
41
|
+
|
|
42
|
+
frontScripts = (developConfig && typeof developConfig.scripts == 'function')
|
|
43
|
+
&& await developConfig.scripts(basePath, 'front') || []
|
|
44
|
+
|
|
45
|
+
scripts = scripts.filter(filterDll).map(s => typeof s === 'string' ? { src: s } : s);
|
|
46
|
+
frontScripts = frontScripts.filter(filterDll).map(s => typeof s === 'string' ? { src: s } : s);
|
|
47
|
+
|
|
48
|
+
const packageNames = [ ...defaultModules, ...(appPackage.iotDependencies||[]) ];
|
|
49
|
+
|
|
50
|
+
const packageScripts = await Promise.all(packageNames.map(async packageName => {
|
|
51
|
+
if(packageName != appPackage.name && !findModule(scripts, packageName)) {
|
|
52
|
+
const packagePath = basePath + '/' + packageName
|
|
53
|
+
|
|
54
|
+
if (loadOnline) {
|
|
55
|
+
try {
|
|
56
|
+
let pkgUrl = packagePath.replace(/\/+$/,'') + '/package.json'
|
|
57
|
+
pkgUrl = (pkgUrl.startsWith("http://") || pkgUrl.startsWith("https://")) ? pkgUrl : (host + pkgUrl)
|
|
58
|
+
const res = await fetch(pkgUrl)
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
return [ packagePath + '/dist/index.js', packagePath + '/dist/front.js' ]
|
|
61
|
+
}
|
|
62
|
+
const pkg = await res.json()
|
|
63
|
+
|
|
64
|
+
const unwrap = entry => {
|
|
65
|
+
if (!entry) return null
|
|
66
|
+
if (typeof entry === 'string') return entry
|
|
67
|
+
if (typeof entry === 'object') {
|
|
68
|
+
// Prefer standard fields or first available value
|
|
69
|
+
return unwrap(entry.import || entry.module || entry.default || Object.values(entry)[0])
|
|
70
|
+
}
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const parseQuery = qs => {
|
|
75
|
+
const obj = {}
|
|
76
|
+
for (const [k, v] of new URLSearchParams(qs)) {
|
|
77
|
+
if (obj[k] === undefined) obj[k] = v
|
|
78
|
+
else if (Array.isArray(obj[k])) obj[k].push(v)
|
|
79
|
+
else obj[k] = [obj[k], v]
|
|
80
|
+
}
|
|
81
|
+
return obj
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const join = (base, rel) => {
|
|
85
|
+
if (!rel) return null
|
|
86
|
+
// allow "./foo.js" or "foo.js" or "/foo.js"
|
|
87
|
+
let url = base.replace(/\/+$/,'') + '/' + rel.replace(/^\.?\/+/,'')
|
|
88
|
+
const qIndex = url.indexOf('?')
|
|
89
|
+
if (qIndex >= 0) {
|
|
90
|
+
const hashIndex = url.indexOf('#', qIndex)
|
|
91
|
+
const qs = url.slice(qIndex + 1, hashIndex >= 0 ? hashIndex : undefined)
|
|
92
|
+
const cleanUrl = hashIndex >= 0 ? url.slice(0, hashIndex) : url.slice(0, qIndex)
|
|
93
|
+
return { src: cleanUrl, ...parseQuery(qs) }
|
|
94
|
+
}
|
|
95
|
+
return { src: url }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let adminRel = null, frontRel = null
|
|
99
|
+
|
|
100
|
+
if (pkg.exports && pkg.exports.airiot) {
|
|
101
|
+
const a = pkg.exports.airiot
|
|
102
|
+
adminRel = unwrap(a.admin || a.index )
|
|
103
|
+
frontRel = unwrap(a.front)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!adminRel && !frontRel) {
|
|
107
|
+
adminRel = pkg.main || null
|
|
108
|
+
frontRel = pkg.iotFront || null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const adminScript = adminRel ? join(packagePath, adminRel) : null
|
|
112
|
+
const frontScript = frontRel ? join(packagePath, frontRel) : null
|
|
113
|
+
|
|
114
|
+
return [ adminScript, frontScript ]
|
|
115
|
+
} catch (e) { }
|
|
116
|
+
}
|
|
117
|
+
return [ packagePath + '/dist/index.js', packagePath + '/dist/front.js' ]
|
|
118
|
+
}
|
|
119
|
+
return null
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
packageScripts.forEach(scriptsArr => {
|
|
123
|
+
if(scriptsArr) {
|
|
124
|
+
const [adminScript, frontScript] = scriptsArr
|
|
125
|
+
adminScript && scripts.push(typeof adminScript === "string" ? { src: adminScript } : adminScript)
|
|
126
|
+
frontScript && frontScripts.push(typeof frontScript === "string" ? { src: frontScript } : frontScript)
|
|
127
|
+
}
|
|
128
|
+
});
|
|
56
129
|
}
|
|
57
130
|
|
|
58
|
-
const getHtmlScripts = (html, isAdmin, mode) => {
|
|
131
|
+
const getHtmlScripts = async (html, isAdmin, mode) => {
|
|
132
|
+
if(!scripts || !frontScripts) {
|
|
133
|
+
await loadPackageScripts()
|
|
134
|
+
}
|
|
59
135
|
const appendScripts = isAdmin ? scripts : frontScripts
|
|
60
136
|
return [
|
|
61
137
|
{ tag: 'script', attrs: { }, children: 'window._r = s => s; window._t1 = s => s', injectTo: 'body-prepend' },
|
|
62
138
|
{ tag: 'script', attrs: { src: mode == 'dev' ? dllDevScript : dllScript }, injectTo: 'body' },
|
|
63
|
-
...appendScripts.map(script => ({ tag: 'script', attrs: {
|
|
139
|
+
...appendScripts.map(script => ({ tag: 'script', attrs: { ...script }, injectTo: 'body' })),
|
|
64
140
|
{ tag: 'script', attrs: { type: 'module' }, children: '__app__.start()', injectTo: 'body' },
|
|
65
141
|
]
|
|
66
142
|
}
|
|
@@ -69,16 +145,16 @@ const airiotPlugin = (mode) => {
|
|
|
69
145
|
return {
|
|
70
146
|
name: 'airiot',
|
|
71
147
|
enforce: 'pre',
|
|
72
|
-
transformIndexHtml(html, ctx) {
|
|
73
|
-
return getHtmlScripts(html, ctx.path == '/admin.html', mode)
|
|
148
|
+
transformIndexHtml: async (html, ctx) => {
|
|
149
|
+
return await getHtmlScripts(html, ctx.path == '/admin.html', mode)
|
|
74
150
|
},
|
|
75
|
-
configurePreviewServer(server) {
|
|
151
|
+
configurePreviewServer: (server) => {
|
|
76
152
|
// 返回一个钩子,会在其他中间件安装完成后调用
|
|
77
153
|
return () => {
|
|
78
|
-
server.middlewares.use((req, res, next) => {
|
|
154
|
+
server.middlewares.use(async (req, res, next) => {
|
|
79
155
|
// 自定义处理请求 ...
|
|
80
156
|
if(req.url == '/index.html') {
|
|
81
|
-
let scripts = getHtmlScripts(htmlTpl, true, mode)
|
|
157
|
+
let scripts = await getHtmlScripts(htmlTpl, true, mode)
|
|
82
158
|
scripts = [ ...scripts.slice(0, scripts.length - 1), {
|
|
83
159
|
tag: 'script', attrs: { src: 'index.js', type: 'module' }, injectTo: 'body'
|
|
84
160
|
}, scripts[scripts.length - 1] ]
|