neo-cmp-cli 1.2.10 → 1.2.11
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/package.json
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
2
|
const _ = require('lodash');
|
|
4
3
|
const { resolveToCurrentRoot } = require('../utils/pathUtils');
|
|
5
|
-
const getCmpRegister = require('./getCmpRegister');
|
|
6
|
-
const getCmpModelRegister = require('./getCmpModelRegister');
|
|
7
4
|
/**
|
|
8
5
|
* 更新发布日志
|
|
9
6
|
*/
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* 注入 neoRequire 函数
|
|
3
3
|
* 备注:用于实现和 Neo 平台共享依赖
|
|
4
4
|
*/
|
|
5
|
-
(function(
|
|
5
|
+
(function(NeoCustomCmpFileFactory) {
|
|
6
6
|
if (!window.neoRequire) {
|
|
7
7
|
throw new Error('neoRequire 不存在,请在 NeoCRM 平台中加载此脚本。');
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
NeoCustomCmpFileFactory(window.neoRequire);
|
|
10
10
|
})(function(require) {
|
|
11
11
|
/**
|
|
12
12
|
* 这里放自定义组件相关内容代码
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const { ConcatSource } = require('webpack-sources');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 注入 neoRequire 函数
|
|
5
|
+
* 备注:用于实现和 Neo 平台共享依赖
|
|
6
|
+
*/
|
|
7
|
+
class AddNeoRequirePlugin {
|
|
8
|
+
apply(compiler) {
|
|
9
|
+
compiler.hooks.compilation.tap('AddNeoRequirePlugin', (compilation) => {
|
|
10
|
+
compilation.hooks.processAssets.tap(
|
|
11
|
+
{
|
|
12
|
+
name: 'AddNeoRequirePlugin',
|
|
13
|
+
stage: -100
|
|
14
|
+
},
|
|
15
|
+
() => {
|
|
16
|
+
for (const chunk of compilation.chunks) {
|
|
17
|
+
if (!chunk.canBeInitial() || !chunk.rendered) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const file of chunk.files) {
|
|
22
|
+
if (/.css$/.test(file)) {
|
|
23
|
+
// 不处理 css 文件
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const Header = `
|
|
28
|
+
(function(cmpFileFactory) {
|
|
29
|
+
if (!window.neoRequire) {
|
|
30
|
+
throw new Error('neoRequire 不存在,请在 NeoCRM 平台中加载此脚本。');
|
|
31
|
+
}
|
|
32
|
+
cmpFileFactory(window.neoRequire);
|
|
33
|
+
})(function(require) {
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const Footer = `})`;
|
|
37
|
+
|
|
38
|
+
compilation.updateAsset(file, (oldFileContent) => new ConcatSource(Header, oldFileContent, Footer));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = AddNeoRequirePlugin;
|
|
@@ -5,6 +5,83 @@ const { ConcatSource } = require('webpack-sources');
|
|
|
5
5
|
* 备注:用于实现和 Neo 平台共享依赖
|
|
6
6
|
*/
|
|
7
7
|
class AddNeoRequirePlugin {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.options = {
|
|
10
|
+
// 是否启用详细日志
|
|
11
|
+
verbose: options.verbose || false,
|
|
12
|
+
// 是否跳过已注入的文件
|
|
13
|
+
skipInjected: options.skipInjected !== false,
|
|
14
|
+
// 需要跳过的文件扩展名
|
|
15
|
+
skipExtensions: options.skipExtensions || ['.css', '.map', '.txt', '.html'],
|
|
16
|
+
// 需要跳过的文件名模式
|
|
17
|
+
skipPatterns: options.skipPatterns || [/\.map$/, /\.LICENSE\.txt$/, /\.html$/],
|
|
18
|
+
...options
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// 记录已处理的文件,避免重复处理
|
|
22
|
+
this.processedFiles = new Set();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 检查文件是否应该被跳过
|
|
27
|
+
*/
|
|
28
|
+
shouldSkipFile(filename) {
|
|
29
|
+
// 检查扩展名
|
|
30
|
+
for (const ext of this.options.skipExtensions) {
|
|
31
|
+
if (filename.endsWith(ext)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 检查文件名模式
|
|
37
|
+
for (const pattern of this.options.skipPatterns) {
|
|
38
|
+
if (pattern.test(filename)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 检查文件是否已经被注入过
|
|
48
|
+
*/
|
|
49
|
+
isAlreadyInjected(content) {
|
|
50
|
+
if (!content || typeof content !== 'string') {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 检查是否包含注入的标识
|
|
55
|
+
return content.includes('NeoCustomCmpFileFactory(window.neoRequire)') &&
|
|
56
|
+
content.includes('if (!window.neoRequire)');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 验证文件内容是否有效
|
|
61
|
+
*/
|
|
62
|
+
isValidFile(content) {
|
|
63
|
+
if (!content || typeof content !== 'string') {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 检查文件是否为空或只包含空白字符
|
|
68
|
+
if (content.trim().length === 0) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 记录日志
|
|
77
|
+
*/
|
|
78
|
+
log(message, level = 'info') {
|
|
79
|
+
if (this.options.verbose || level === 'error') {
|
|
80
|
+
const prefix = `[AddNeoRequirePlugin]`;
|
|
81
|
+
console[level](`${prefix} ${message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
8
85
|
apply(compiler) {
|
|
9
86
|
compiler.hooks.compilation.tap('AddNeoRequirePlugin', (compilation) => {
|
|
10
87
|
compilation.hooks.processAssets.tap(
|
|
@@ -12,36 +89,94 @@ class AddNeoRequirePlugin {
|
|
|
12
89
|
name: 'AddNeoRequirePlugin',
|
|
13
90
|
stage: -100
|
|
14
91
|
},
|
|
15
|
-
() => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
92
|
+
(assets) => {
|
|
93
|
+
this.log('开始处理资源文件...');
|
|
94
|
+
|
|
95
|
+
let processedCount = 0;
|
|
96
|
+
let skippedCount = 0;
|
|
97
|
+
let errorCount = 0;
|
|
20
98
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
99
|
+
// 遍历所有资源文件
|
|
100
|
+
for (const [filename, asset] of Object.entries(assets)) {
|
|
101
|
+
try {
|
|
102
|
+
// 检查是否应该跳过此文件
|
|
103
|
+
if (this.shouldSkipFile(filename)) {
|
|
104
|
+
this.log(`跳过文件: ${filename} (匹配跳过规则)`);
|
|
105
|
+
skippedCount++;
|
|
24
106
|
continue;
|
|
25
107
|
}
|
|
26
108
|
|
|
27
|
-
|
|
28
|
-
(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
})(function(require) {
|
|
34
|
-
`;
|
|
109
|
+
// 检查是否已经处理过
|
|
110
|
+
if (this.processedFiles.has(filename)) {
|
|
111
|
+
this.log(`跳过文件: ${filename} (已处理过)`);
|
|
112
|
+
skippedCount++;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
35
115
|
|
|
36
|
-
|
|
116
|
+
// 获取文件内容
|
|
117
|
+
const source = asset.source();
|
|
118
|
+
const content = typeof source === 'string' ? source : source.toString();
|
|
37
119
|
|
|
38
|
-
|
|
120
|
+
// 验证文件内容
|
|
121
|
+
if (!this.isValidFile(content)) {
|
|
122
|
+
this.log(`跳过文件: ${filename} (内容无效)`, 'warn');
|
|
123
|
+
skippedCount++;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 检查是否已经注入过
|
|
128
|
+
if (this.options.skipInjected && this.isAlreadyInjected(content)) {
|
|
129
|
+
this.log(`跳过文件: ${filename} (已注入过)`);
|
|
130
|
+
skippedCount++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 执行注入
|
|
135
|
+
this.injectNeoRequire(compilation, filename, content);
|
|
136
|
+
this.processedFiles.add(filename);
|
|
137
|
+
processedCount++;
|
|
138
|
+
|
|
139
|
+
this.log(`成功处理文件: ${filename}`);
|
|
140
|
+
|
|
141
|
+
} catch (error) {
|
|
142
|
+
errorCount++;
|
|
143
|
+
this.log(`处理文件失败: ${filename}, 错误: ${error.message}`, 'error');
|
|
144
|
+
console.error(`[AddNeoRequirePlugin] 详细错误:`, error);
|
|
39
145
|
}
|
|
40
146
|
}
|
|
147
|
+
|
|
148
|
+
// 输出处理统计
|
|
149
|
+
this.log(`处理完成 - 成功: ${processedCount}, 跳过: ${skippedCount}, 错误: ${errorCount}`);
|
|
150
|
+
|
|
151
|
+
if (errorCount > 0) {
|
|
152
|
+
this.log(`警告: 有 ${errorCount} 个文件处理失败`, 'warn');
|
|
153
|
+
}
|
|
41
154
|
}
|
|
42
155
|
);
|
|
43
156
|
});
|
|
44
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 执行 neoRequire 注入
|
|
161
|
+
*/
|
|
162
|
+
injectNeoRequire(compilation, filename, content) {
|
|
163
|
+
const Header = `
|
|
164
|
+
(function(NeoCustomCmpFileFactory) {
|
|
165
|
+
if (!window.neoRequire) {
|
|
166
|
+
throw new Error('neoRequire 不存在,请在 NeoCRM 平台中加载此脚本。');
|
|
167
|
+
}
|
|
168
|
+
NeoCustomCmpFileFactory(window.neoRequire);
|
|
169
|
+
})(function(require) {
|
|
170
|
+
`;
|
|
171
|
+
|
|
172
|
+
const Footer = `})`;
|
|
173
|
+
|
|
174
|
+
// 创建新的资源
|
|
175
|
+
const newSource = new ConcatSource(Header, content, Footer);
|
|
176
|
+
|
|
177
|
+
// 更新资源
|
|
178
|
+
compilation.updateAsset(filename, newSource);
|
|
179
|
+
}
|
|
45
180
|
}
|
|
46
181
|
|
|
47
182
|
module.exports = AddNeoRequirePlugin;
|
package/src/plugins/README.md
CHANGED
|
@@ -1,2 +1,109 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# AddNeoRequirePlugin 使用说明
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
`AddNeoRequirePlugin` 是一个 webpack 插件,用于在构建过程中自动为 JavaScript 文件注入 `neoRequire` 包装代码,实现与 Neo 平台的依赖共享。
|
|
6
|
+
|
|
7
|
+
## 使用方法
|
|
8
|
+
|
|
9
|
+
### 基本使用
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const AddNeoRequirePlugin = require('./AddNeoRequirePlugin');
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
// ... 其他配置
|
|
16
|
+
plugins: [
|
|
17
|
+
new AddNeoRequirePlugin()
|
|
18
|
+
]
|
|
19
|
+
};
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 高级配置
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
const AddNeoRequirePlugin = require('./AddNeoRequirePlugin');
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
// ... 其他配置
|
|
29
|
+
plugins: [
|
|
30
|
+
new AddNeoRequirePlugin({
|
|
31
|
+
// 启用详细日志
|
|
32
|
+
verbose: true,
|
|
33
|
+
|
|
34
|
+
// 跳过已注入的文件(默认: true)
|
|
35
|
+
skipInjected: true,
|
|
36
|
+
|
|
37
|
+
// 需要跳过的文件扩展名
|
|
38
|
+
skipExtensions: ['.css', '.map', '.txt', '.html', '.svg'],
|
|
39
|
+
|
|
40
|
+
// 需要跳过的文件名模式(正则表达式)
|
|
41
|
+
skipPatterns: [
|
|
42
|
+
/\.map$/,
|
|
43
|
+
/\.LICENSE\.txt$/,
|
|
44
|
+
/\.html$/,
|
|
45
|
+
/vendor\./,
|
|
46
|
+
/chunk\./
|
|
47
|
+
]
|
|
48
|
+
})
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 配置选项
|
|
54
|
+
|
|
55
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
56
|
+
|------|------|--------|------|
|
|
57
|
+
| `verbose` | boolean | false | 是否启用详细日志输出 |
|
|
58
|
+
| `skipInjected` | boolean | true | 是否跳过已经注入过的文件 |
|
|
59
|
+
| `skipExtensions` | string[] | ['.css', '.map', '.txt', '.html'] | 需要跳过的文件扩展名列表 |
|
|
60
|
+
| `skipPatterns` | RegExp[] | [/\.map$/, /\.LICENSE\.txt$/, /\.html$/] | 需要跳过的文件名模式 |
|
|
61
|
+
|
|
62
|
+
## 注入的代码结构
|
|
63
|
+
|
|
64
|
+
插件会为每个 JavaScript 文件添加以下包装代码:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
(function(NeoCustomCmpFileFactory) {
|
|
68
|
+
if (!window.neoRequire) {
|
|
69
|
+
throw new Error('neoRequire 不存在,请在 NeoCRM 平台中加载此脚本。');
|
|
70
|
+
}
|
|
71
|
+
NeoCustomCmpFileFactory(window.neoRequire);
|
|
72
|
+
})(function(require) {
|
|
73
|
+
// 原始文件内容
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 日志输出示例
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
[AddNeoRequirePlugin] 开始处理资源文件...
|
|
81
|
+
[AddNeoRequirePlugin] 跳过文件: main.css (匹配跳过规则)
|
|
82
|
+
[AddNeoRequirePlugin] 跳过文件: main.js.map (匹配跳过规则)
|
|
83
|
+
[AddNeoRequirePlugin] 成功处理文件: main.js
|
|
84
|
+
[AddNeoRequirePlugin] 成功处理文件: chunk.1.js
|
|
85
|
+
[AddNeoRequirePlugin] 处理完成 - 成功: 2, 跳过: 2, 错误: 0
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 故障排除
|
|
89
|
+
|
|
90
|
+
### 1. 文件未被注入
|
|
91
|
+
- 检查文件是否匹配跳过规则
|
|
92
|
+
- 启用 `verbose: true` 查看详细日志
|
|
93
|
+
- 确认文件内容有效且不为空
|
|
94
|
+
|
|
95
|
+
### 2. 重复注入
|
|
96
|
+
- 启用 `skipInjected: true` 选项
|
|
97
|
+
- 检查文件是否已经被处理过
|
|
98
|
+
|
|
99
|
+
### 3. 构建错误
|
|
100
|
+
- 查看错误日志中的详细错误信息
|
|
101
|
+
- 检查文件内容是否包含特殊字符
|
|
102
|
+
- 确认 webpack 版本兼容性
|
|
103
|
+
|
|
104
|
+
## 注意事项
|
|
105
|
+
|
|
106
|
+
1. 插件会在 webpack 的 `processAssets` 阶段执行,优先级为 -100
|
|
107
|
+
2. 只处理 JavaScript 文件,自动跳过 CSS、Map 等非 JS 文件
|
|
108
|
+
3. 支持 SourceMap 文件,但不会修改它们
|
|
109
|
+
4. 建议在生产环境中关闭详细日志以提高性能
|