@qingtian/qtcli 1.0.4 → 1.0.5-beta.10
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 +193 -198
- package/dist/favicon.ico +0 -1
- package/dist/index.html +141 -279
- package/dist/manifest.json +14 -31
- package/dist/package.json +2 -1
- package/dist/src/cores/context.js +1 -1
- package/dist/src/processEnv/loader.js +5 -4
- package/dist/src/utils/childProcess.js +20 -13
- package/dist/src/utils/cookie.js +1 -0
- package/dist/src/utils/logger.js +1 -1
- package/dist/src/utils/set.js +1 -0
- package/dist/src/webpack/web/index.js +1 -0
- package/dist/src/webpack/web/webpack.analy.js +4 -5
- package/dist/src/webpack/web/webpack.base.js +29 -28
- package/dist/src/webpack/web/webpack.prod.js +6 -3
- package/package.json +3 -2
- package/dist/README.md +0 -198
|
@@ -99,6 +99,7 @@ function dev() {
|
|
|
99
99
|
}
|
|
100
100
|
function build() {
|
|
101
101
|
var compiler = (0, webpack_1.default)((argCmd === null || argCmd === void 0 ? void 0 : argCmd.analy) ? webpackAnalyConfig : webpackProdConfig);
|
|
102
|
+
console.log('webpackAnalyConfig::', webpackAnalyConfig);
|
|
102
103
|
compiler.run(function (err, stats) {
|
|
103
104
|
if (err) {
|
|
104
105
|
if (process && process.send) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var prodConfig = require('./webpack.prod');
|
|
4
|
-
var SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
|
|
5
|
-
var smp = new SpeedMeasurePlugin();
|
|
3
|
+
var prodConfig = require('./webpack.prod').default;
|
|
6
4
|
var merge = require('webpack-merge').merge;
|
|
7
5
|
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
8
|
-
|
|
6
|
+
// 基于生产配置,仅附加 BundleAnalyzer,去掉 SpeedMeasurePlugin,避免插件重复注册/丢失
|
|
7
|
+
exports.default = merge(prodConfig, {
|
|
9
8
|
plugins: [new BundleAnalyzerPlugin()],
|
|
10
|
-
})
|
|
9
|
+
});
|
|
@@ -22,7 +22,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
22
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
24
|
};
|
|
25
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
25
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
var loader_1 = require("../../processEnv/loader");
|
|
28
28
|
var manager_1 = require("../../processEnv/manager");
|
|
@@ -31,6 +31,7 @@ var DonePlugin_1 = __importDefault(require("../plugins/DonePlugin"));
|
|
|
31
31
|
var FileListPlugin_1 = __importDefault(require("../plugins/FileListPlugin"));
|
|
32
32
|
var InjectScriptPlugin_1 = __importDefault(require("../plugins/InjectScriptPlugin"));
|
|
33
33
|
var path = require('path');
|
|
34
|
+
var fs = require('fs');
|
|
34
35
|
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
35
36
|
var HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin');
|
|
36
37
|
var webpack = require('webpack');
|
|
@@ -62,11 +63,13 @@ var qtConfig = envLoader.getQtConfig() || {
|
|
|
62
63
|
plugins: [],
|
|
63
64
|
},
|
|
64
65
|
};
|
|
66
|
+
// 入口配置:优先 qt.conf.js 中的 entry,若无则默认 index
|
|
67
|
+
var baseEntries = ((_a = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.webpackConfig) === null || _a === void 0 ? void 0 : _a.entry) || {
|
|
68
|
+
index: path.resolve(process.cwd(), './src/index.tsx'),
|
|
69
|
+
};
|
|
65
70
|
// 定义基础配置
|
|
66
71
|
var config = {
|
|
67
|
-
entry:
|
|
68
|
-
index: path.resolve(process.cwd(), './src/index.tsx'),
|
|
69
|
-
},
|
|
72
|
+
entry: baseEntries,
|
|
70
73
|
output: {
|
|
71
74
|
filename: 'static/js/[name].[chunkhash].js',
|
|
72
75
|
path: path.resolve(process.cwd(), './dist'),
|
|
@@ -333,23 +336,26 @@ var config = {
|
|
|
333
336
|
},
|
|
334
337
|
],
|
|
335
338
|
},
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
// 根据入口数量动态生成 HtmlWebpackPlugin 实例
|
|
340
|
+
plugins: __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], Object.keys(baseEntries).map(function (name) {
|
|
341
|
+
var _a, _b, _c, _d, _e, _f;
|
|
342
|
+
var entryTemplate = path.resolve(process.cwd(), "./public/".concat(name, ".html"));
|
|
343
|
+
var fallbackTemplate = path.resolve(process.cwd(), './public/index.html');
|
|
344
|
+
var template = fs.existsSync(entryTemplate) ? entryTemplate : fallbackTemplate;
|
|
345
|
+
return new HtmlWebpackPlugin({
|
|
346
|
+
template: template,
|
|
347
|
+
filename: "".concat(name, ".html"),
|
|
348
|
+
chunks: [name],
|
|
340
349
|
inject: true,
|
|
341
350
|
favicon: path.resolve(process.cwd(), './public/favicon.ico'),
|
|
342
|
-
publicPath: envConfig.PUBLIC_URL || '/',
|
|
343
|
-
meta: Array.isArray((
|
|
344
|
-
? qtConfig.config.htmlInject.head
|
|
345
|
-
.filter(function (item) { return item.tag === 'meta'; })
|
|
346
|
-
.map(function (item) { return item.attrs; })
|
|
351
|
+
publicPath: ((_b = (_a = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.webpackConfig) === null || _a === void 0 ? void 0 : _a.output) === null || _b === void 0 ? void 0 : _b.publicPath) || (envConfig === null || envConfig === void 0 ? void 0 : envConfig.PUBLIC_URL) || '/',
|
|
352
|
+
meta: Array.isArray((_d = (_c = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _c === void 0 ? void 0 : _c.htmlInject) === null || _d === void 0 ? void 0 : _d.head)
|
|
353
|
+
? (_f = (_e = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _e === void 0 ? void 0 : _e.htmlInject) === null || _f === void 0 ? void 0 : _f.head.filter(function (item) { return item.tag === 'meta'; }).map(function (item) { return item.attrs; })
|
|
347
354
|
: [],
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
], (Array.isArray((_d = (_c = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _c === void 0 ? void 0 : _c.htmlInject) === null || _d === void 0 ? void 0 : _d.head)
|
|
355
|
+
});
|
|
356
|
+
}), true), [
|
|
357
|
+
new InterpolateHtmlPlugin(HtmlWebpackPlugin, __assign({ PUBLIC_URL: (envConfig === null || envConfig === void 0 ? void 0 : envConfig.PUBLIC_URL) || ((_c = (_b = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.webpackConfig) === null || _b === void 0 ? void 0 : _b.output) === null || _c === void 0 ? void 0 : _c.publicPath) || './' }, (((_e = (_d = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _d === void 0 ? void 0 : _d.env) === null || _e === void 0 ? void 0 : _e[process.env.NODE_ENV || 'development']) || {})))
|
|
358
|
+
], false), (Array.isArray((_g = (_f = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _f === void 0 ? void 0 : _f.htmlInject) === null || _g === void 0 ? void 0 : _g.head)
|
|
353
359
|
? [
|
|
354
360
|
new HtmlWebpackTagsPlugin({
|
|
355
361
|
tags: __spreadArray(__spreadArray([], (qtConfig.config.htmlInject.head
|
|
@@ -369,7 +375,7 @@ var config = {
|
|
|
369
375
|
usePublicPath: true,
|
|
370
376
|
}),
|
|
371
377
|
]
|
|
372
|
-
: []), true), (Array.isArray((
|
|
378
|
+
: []), true), (Array.isArray((_j = (_h = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _h === void 0 ? void 0 : _h.htmlInject) === null || _j === void 0 ? void 0 : _j.body)
|
|
373
379
|
? [
|
|
374
380
|
new HtmlWebpackTagsPlugin({
|
|
375
381
|
tags: qtConfig.config.htmlInject.body
|
|
@@ -393,21 +399,16 @@ var config = {
|
|
|
393
399
|
new FileListPlugin_1.default({
|
|
394
400
|
filename: 'list.md',
|
|
395
401
|
}),
|
|
396
|
-
new webpack.DefinePlugin(__assign(__assign(__assign({}, envConfig), (
|
|
402
|
+
new webpack.DefinePlugin(__assign(__assign(__assign({}, envConfig), (_l = (_k = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _k === void 0 ? void 0 : _k.env) === null || _l === void 0 ? void 0 : _l[process.env.NODE_ENV || 'development']), { 'process.env': JSON.stringify(process.env) })),
|
|
397
403
|
new InjectScriptPlugin_1.default({
|
|
398
|
-
headScripts: ((
|
|
399
|
-
bodyScripts: ((
|
|
404
|
+
headScripts: ((_o = (_m = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _m === void 0 ? void 0 : _m.jsInject) === null || _o === void 0 ? void 0 : _o.head) || [],
|
|
405
|
+
bodyScripts: ((_q = (_p = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.config) === null || _p === void 0 ? void 0 : _p.jsInject) === null || _q === void 0 ? void 0 : _q.body) || [],
|
|
400
406
|
}),
|
|
401
|
-
!isDev() &&
|
|
402
|
-
new MiniCssExtractPlugin({
|
|
403
|
-
filename: 'static/css/[name].[contenthash].css',
|
|
404
|
-
chunkFilename: 'static/css/[name].[contenthash].chunk.css',
|
|
405
|
-
}),
|
|
406
407
|
], false).filter(Boolean),
|
|
407
408
|
resolve: {
|
|
408
409
|
modules: ['node_modules', path.resolve(__dirname, '../../../node_modules')],
|
|
409
410
|
extensions: ['.tsx', '.ts', '.jsx', '.js', '.less', '.scss'],
|
|
410
|
-
alias: __assign({ '@': path.resolve(process.cwd(), './src'), react: path.resolve(process.cwd(), './node_modules/react') }, (
|
|
411
|
+
alias: __assign({ '@': path.resolve(process.cwd(), './src'), react: path.resolve(process.cwd(), './node_modules/react') }, (_s = (_r = qtConfig === null || qtConfig === void 0 ? void 0 : qtConfig.webpackConfig) === null || _r === void 0 ? void 0 : _r.resolve) === null || _s === void 0 ? void 0 : _s.alias),
|
|
411
412
|
},
|
|
412
413
|
resolveLoader: {
|
|
413
414
|
modules: [path.resolve(__filename, '../../../node_modules')],
|
|
@@ -5,14 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
var mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
|
|
7
7
|
var path = require('path');
|
|
8
|
-
|
|
8
|
+
var globAll = require('glob-all');
|
|
9
9
|
var CompressionPlugin = require('compression-webpack-plugin');
|
|
10
10
|
var merge = require('webpack-merge').merge;
|
|
11
11
|
var baseConfig = require('./webpack.base').default;
|
|
12
12
|
var CopyPlugin = require('copy-webpack-plugin');
|
|
13
13
|
var CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
|
14
14
|
var TerserPlugin = require('terser-webpack-plugin');
|
|
15
|
-
|
|
15
|
+
var PurgeCSSPlugin = require('purgecss-webpack-plugin');
|
|
16
16
|
exports.default = merge(baseConfig, {
|
|
17
17
|
mode: 'production',
|
|
18
18
|
plugins: [
|
|
@@ -22,7 +22,8 @@ exports.default = merge(baseConfig, {
|
|
|
22
22
|
from: path.resolve(process.cwd(), './public'),
|
|
23
23
|
to: baseConfig.output.path,
|
|
24
24
|
filter: function (source) {
|
|
25
|
-
|
|
25
|
+
// 过滤掉所有 .html 文件,避免与 HtmlWebpackPlugin 生成的文件冲突
|
|
26
|
+
return !source.endsWith('.html');
|
|
26
27
|
},
|
|
27
28
|
},
|
|
28
29
|
],
|
|
@@ -31,11 +32,13 @@ exports.default = merge(baseConfig, {
|
|
|
31
32
|
filename: 'static/css/[name].[contenthash].css',
|
|
32
33
|
}),
|
|
33
34
|
// new PurgeCSSPlugin({
|
|
35
|
+
// // 扫描项目内实际使用的类名,移除未使用的 CSS
|
|
34
36
|
// paths: globAll.sync([
|
|
35
37
|
// `${path.join(process.cwd(), './src')}/**/*.tsx`,
|
|
36
38
|
// `${path.join(process.cwd(), './src')}/**/*.jsx`,
|
|
37
39
|
// path.join(process.cwd(), './public/index.html'),
|
|
38
40
|
// ]),
|
|
41
|
+
// // 防止 antd 等前缀类名被误删
|
|
39
42
|
// safelist: {
|
|
40
43
|
// standard: [/^ant-/],
|
|
41
44
|
// },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qingtian/qtcli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5-beta.10",
|
|
4
4
|
"description": "QTCli是一款基于node的前端工程化底座",
|
|
5
5
|
"homepage": "https://gitee.com/fengrengame/qtnode#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -122,6 +122,7 @@
|
|
|
122
122
|
"postcss-loader": "^6.2.1",
|
|
123
123
|
"postcss-normalize": "^10.0.1",
|
|
124
124
|
"postcss-preset-env": "^7.0.1",
|
|
125
|
+
"postcss-pxtorem": "^6.1.0",
|
|
125
126
|
"prettier": "3.5.3",
|
|
126
127
|
"prettier-config-ali": "1.3.2",
|
|
127
128
|
"progress": "2.0.3",
|
|
@@ -197,4 +198,4 @@
|
|
|
197
198
|
"jest-watch-typeahead": "^1.0.0"
|
|
198
199
|
},
|
|
199
200
|
"email": "296963166@qq.com"
|
|
200
|
-
}
|
|
201
|
+
}
|
package/dist/README.md
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# QTCli
|
|
2
|
-
|
|
3
|
-
QTCli 是一款基于 Node.js 的前端工程化底座,提供了完整的项目构建、开发和部署解决方案。
|
|
4
|
-
|
|
5
|
-
## 特性
|
|
6
|
-
|
|
7
|
-
- 🚀 快速创建和初始化项目
|
|
8
|
-
- 📦 内置 Webpack 构建配置
|
|
9
|
-
- 🔥 支持 React + TypeScript 开发
|
|
10
|
-
- 🎨 支持 Less、Sass、CSS Modules
|
|
11
|
-
- 📱 支持移动端适配
|
|
12
|
-
- 🔍 内置 ESLint、StyleLint 代码规范检查
|
|
13
|
-
- 🛠 支持自定义配置和插件扩展
|
|
14
|
-
|
|
15
|
-
## 环境要求
|
|
16
|
-
Node.js >= v22.14.0
|
|
17
|
-
f2elint 4.7.1
|
|
18
|
-
npm 10.9.2
|
|
19
|
-
|
|
20
|
-
## 安装
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm install -g qtcli
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 使用方法
|
|
27
|
-
|
|
28
|
-
### 查看帮助
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
qtcli --help
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 初始化项目
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
qtcli init [options]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 开发模式
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
qtcli dev [options]
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 构建项目
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
qtcli build [options]
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## 全局选项
|
|
53
|
-
|
|
54
|
-
-V, --version: 显示版本号
|
|
55
|
-
-D, --debug: 启用调试模式
|
|
56
|
-
-h, --help: 显示帮助信息
|
|
57
|
-
|
|
58
|
-
## 项目结构
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
my-project/
|
|
62
|
-
├── src/ # 源代码目录
|
|
63
|
-
├── public/ # 静态资源目录
|
|
64
|
-
├── dist/ # 构建输出目录
|
|
65
|
-
└── qt.conf.js # 项目配置文件
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## 配置说明
|
|
69
|
-
|
|
70
|
-
在项目根目录创建 `qt.conf.js` 文件进行自定义配置:
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
export default {
|
|
74
|
-
// 构建类型
|
|
75
|
-
buildType: 'WEB',
|
|
76
|
-
|
|
77
|
-
// 解决方案名称
|
|
78
|
-
solutionName: 'my-project',
|
|
79
|
-
|
|
80
|
-
// 构建模式
|
|
81
|
-
buildMode: {
|
|
82
|
-
development: 'DEVELOPMENT',
|
|
83
|
-
production: 'PRODUCTION',
|
|
84
|
-
test: 'TEST',
|
|
85
|
-
analyze: 'ANALYZE'
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
// 项目配置
|
|
89
|
-
config: {
|
|
90
|
-
// HTML 注入配置
|
|
91
|
-
htmlInject: {
|
|
92
|
-
head: [
|
|
93
|
-
// meta 标签
|
|
94
|
-
{
|
|
95
|
-
tag: 'meta',
|
|
96
|
-
attrs: {
|
|
97
|
-
charset: 'utf-8'
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
tag: 'meta',
|
|
102
|
-
attrs: {
|
|
103
|
-
name: 'viewport',
|
|
104
|
-
content: 'width=device-width, initial-scale=1'
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
// link 标签
|
|
108
|
-
{
|
|
109
|
-
tag: 'link',
|
|
110
|
-
attrs: {
|
|
111
|
-
rel: 'stylesheet',
|
|
112
|
-
href: '/static/css/global.css'
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
],
|
|
116
|
-
body: [
|
|
117
|
-
// body 中的 script
|
|
118
|
-
{
|
|
119
|
-
tag: 'script',
|
|
120
|
-
attrs: {
|
|
121
|
-
src: '/static/js/init.js'
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
]
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
// JavaScript 代码片段注入配置
|
|
128
|
-
jsInject: {
|
|
129
|
-
head: [
|
|
130
|
-
{
|
|
131
|
-
code: `window.APP_CONFIG = {
|
|
132
|
-
version: '1.0.0',
|
|
133
|
-
env: '${process.env.NODE_ENV}',
|
|
134
|
-
apiUrl: '${process.env.API_URL}'
|
|
135
|
-
};`
|
|
136
|
-
}
|
|
137
|
-
],
|
|
138
|
-
body: [
|
|
139
|
-
{
|
|
140
|
-
code: `document.addEventListener('DOMContentLoaded', function() {
|
|
141
|
-
console.log('DOM loaded');
|
|
142
|
-
});`
|
|
143
|
-
}
|
|
144
|
-
]
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
// 环境变量配置
|
|
148
|
-
env: {
|
|
149
|
-
development: {
|
|
150
|
-
NODE_ENV: 'development',
|
|
151
|
-
API_URL: 'http://dev-api.example.com'
|
|
152
|
-
},
|
|
153
|
-
production: {
|
|
154
|
-
NODE_ENV: 'production',
|
|
155
|
-
API_URL: 'http://api.example.com'
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
// webpack 配置
|
|
161
|
-
webpackConfig: {
|
|
162
|
-
// 开发服务器配置
|
|
163
|
-
devServer: {
|
|
164
|
-
port: 3000,
|
|
165
|
-
host: 'localhost'
|
|
166
|
-
},
|
|
167
|
-
// 解析配置
|
|
168
|
-
resolve: {
|
|
169
|
-
alias: {
|
|
170
|
-
'@components': './src/components',
|
|
171
|
-
'@utils': './src/utils'
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
// 模块规则
|
|
175
|
-
module: {
|
|
176
|
-
rules: []
|
|
177
|
-
},
|
|
178
|
-
// 插件配置
|
|
179
|
-
plugins: []
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## 开发环境要求
|
|
185
|
-
|
|
186
|
-
Node.js >= 14.0.0
|
|
187
|
-
npm >= 6.0.0
|
|
188
|
-
|
|
189
|
-
## 作者
|
|
190
|
-
|
|
191
|
-
yujie.guo - 初始作者
|
|
192
|
-
|
|
193
|
-
## 问题反馈
|
|
194
|
-
|
|
195
|
-
如果你遇到任何问题或有任何建议,请通过以下方式联系我们:
|
|
196
|
-
|
|
197
|
-
提交 Issue: [GitHub Issues](https://gitee.com/fengrengame/qtnode/issues)
|
|
198
|
-
邮件联系: 296963166@qq.com
|