remove-comments-plugin 1.0.0-beta-1
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 +102 -0
- package/package.json +27 -0
- package/remove-comments.js +231 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# remove-comments-plugin
|
|
2
|
+
|
|
3
|
+
A tool to remove comments from JavaScript, CSS, and HTML files.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install remove-comments-plugin
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Command Line
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# 使用默认配置
|
|
17
|
+
remove-comments
|
|
18
|
+
|
|
19
|
+
# 指定目录
|
|
20
|
+
remove-comments --distPath ./dist
|
|
21
|
+
|
|
22
|
+
# 指定文件类型
|
|
23
|
+
remove-comments --fileTypes .js,.css,.html
|
|
24
|
+
|
|
25
|
+
# 指定文件名过滤规则
|
|
26
|
+
remove-comments --fileIncludePatterns chunk-vendors,app
|
|
27
|
+
|
|
28
|
+
# 指定版本信息过滤规则
|
|
29
|
+
remove-comments --versionPatterns Vue.js,vuex
|
|
30
|
+
|
|
31
|
+
# 禁用详细日志
|
|
32
|
+
remove-comments --verbose false
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Package.json Scripts
|
|
36
|
+
|
|
37
|
+
在package.json中配置脚本,方便项目中使用:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"scripts": {
|
|
42
|
+
"remove-comments": "remove-comments -v Vue.js,vuex"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
然后运行:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm run remove-comments
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Programmatic Usage
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
const { main, removeJavaScriptComments, removeCssComments, removeHtmlComments } = require('remove-comments-plugin');
|
|
57
|
+
|
|
58
|
+
// 使用默认配置
|
|
59
|
+
main();
|
|
60
|
+
|
|
61
|
+
// 使用自定义配置
|
|
62
|
+
main({
|
|
63
|
+
distPath: './dist',
|
|
64
|
+
fileTypes: ['.js', '.css'],
|
|
65
|
+
fileIncludePatterns: ['chunk-vendors'],
|
|
66
|
+
verbose: true,
|
|
67
|
+
versionPatterns: ['Vue.js v2.6.11', 'vuex v3.6.2']
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 单独使用注释移除函数
|
|
71
|
+
const jsCode = '// This is a comment\nconsole.log("Hello World");';
|
|
72
|
+
const cleanJsCode = removeJavaScriptComments(jsCode);
|
|
73
|
+
|
|
74
|
+
const cssCode = '/* This is a comment */\nbody { margin: 0; }';
|
|
75
|
+
const cleanCssCode = removeCssComments(cssCode);
|
|
76
|
+
|
|
77
|
+
const htmlCode = '<!-- This is a comment -->\n<div>Hello World</div>';
|
|
78
|
+
const cleanHtmlCode = removeHtmlComments(htmlCode);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
- Removes comments from JavaScript, CSS, and HTML files
|
|
84
|
+
- Supports custom directory paths
|
|
85
|
+
- Supports custom file types
|
|
86
|
+
- Supports custom filename filtering patterns
|
|
87
|
+
- Provides detailed logging
|
|
88
|
+
- Can be used both as a command-line tool and as a library
|
|
89
|
+
|
|
90
|
+
## Configuration Options
|
|
91
|
+
|
|
92
|
+
| Option | Description | Default |
|
|
93
|
+
| ------ | ----------- | ------- |
|
|
94
|
+
| distPath | The directory path to process | `./dist` |
|
|
95
|
+
| fileTypes | An array of file extensions to process | `['.js']` |
|
|
96
|
+
| fileIncludePatterns | An array of filename patterns to filter files | `['chunk-vendors', 'app']` |
|
|
97
|
+
| versionPatterns | An array of version patterns to filter comments | `['Vue.js v2.6.11', 'vuex v3.6.2']` |
|
|
98
|
+
| verbose | Whether to print detailed logs | `true` |
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "remove-comments-plugin",
|
|
3
|
+
"version": "1.0.0-beta-1",
|
|
4
|
+
"description": "A tool to remove comments from JavaScript, CSS, and HTML files",
|
|
5
|
+
"main": "remove-comments.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"remove-comments": "./remove-comments.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"remove",
|
|
14
|
+
"comments",
|
|
15
|
+
"javascript",
|
|
16
|
+
"css",
|
|
17
|
+
"html"
|
|
18
|
+
],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"commander": "^6.2.0"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=10"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { Command } = require('commander');
|
|
5
|
+
|
|
6
|
+
// 默认配置项
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
// dist目录路径
|
|
9
|
+
// distPath: path.join(__dirname, 'unpackage', 'dist', 'build'),
|
|
10
|
+
distPath: path.join(process.cwd(), 'unpackage/dist'),
|
|
11
|
+
// 需要处理的文件类型
|
|
12
|
+
fileTypes: ['.js'],
|
|
13
|
+
// 是否打印详细日志
|
|
14
|
+
verbose: true,
|
|
15
|
+
// 文件名过滤规则 - 只处理包含以下关键词的文件
|
|
16
|
+
fileIncludePatterns: ['chunk-vendors', 'app'],
|
|
17
|
+
// 版本信息过滤规则 - 只处理包含以下关键词的注释
|
|
18
|
+
versionPatterns: ['Vue.js','vuex']
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// 解析命令行参数
|
|
22
|
+
const program = new Command();
|
|
23
|
+
program
|
|
24
|
+
.version('1.0.0')
|
|
25
|
+
.option('-d, --distPath <path>', '指定dist目录路径')
|
|
26
|
+
.option('-t, --fileTypes <types>', '指定需要处理的文件类型,用逗号分隔', (value) => value.split(','))
|
|
27
|
+
.option('-v, --verbose', '启用详细日志', true)
|
|
28
|
+
.option('-p, --fileIncludePatterns <patterns>', '指定文件名过滤规则,用逗号分隔', (value) => value.split(','))
|
|
29
|
+
.option('-v, --versionPatterns <patterns>', '指定版本信息过滤规则,用逗号分隔', (value) => value.split(','))
|
|
30
|
+
.parse(process.argv);
|
|
31
|
+
|
|
32
|
+
// 合并配置
|
|
33
|
+
const opts = program.opts();
|
|
34
|
+
const CONFIG = {
|
|
35
|
+
...DEFAULT_CONFIG,
|
|
36
|
+
// 只有当命令行参数存在时才覆盖默认值
|
|
37
|
+
...(opts.distPath && { distPath: opts.distPath }),
|
|
38
|
+
...(opts.fileTypes && { fileTypes: opts.fileTypes }),
|
|
39
|
+
...(typeof opts.verbose === 'boolean' && { verbose: opts.verbose }),
|
|
40
|
+
...(opts.fileIncludePatterns && { fileIncludePatterns: opts.fileIncludePatterns }),
|
|
41
|
+
...(opts.versionPatterns && { versionPatterns: opts.versionPatterns })
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// 颜色代码
|
|
45
|
+
const COLORS = {
|
|
46
|
+
reset: '\x1b[0m',
|
|
47
|
+
green: '\x1b[32m',
|
|
48
|
+
yellow: '\x1b[33m',
|
|
49
|
+
blue: '\x1b[34m',
|
|
50
|
+
red: '\x1b[31m'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 递归遍历目录,处理所有匹配的文件
|
|
55
|
+
* @param {string} dirPath - 目录路径
|
|
56
|
+
* @param {Object} config - 配置选项
|
|
57
|
+
*/
|
|
58
|
+
function traverseDirectory(dirPath, config) {
|
|
59
|
+
try {
|
|
60
|
+
const files = fs.readdirSync(dirPath);
|
|
61
|
+
|
|
62
|
+
files.forEach(file => {
|
|
63
|
+
const filePath = path.join(dirPath, file);
|
|
64
|
+
const stats = fs.statSync(filePath);
|
|
65
|
+
|
|
66
|
+
if (stats.isDirectory()) {
|
|
67
|
+
// 递归处理子目录
|
|
68
|
+
traverseDirectory(filePath, config);
|
|
69
|
+
} else if (stats.isFile() && config.fileTypes.includes(path.extname(filePath))) {
|
|
70
|
+
// 获取文件名
|
|
71
|
+
const fileName = path.basename(filePath);
|
|
72
|
+
|
|
73
|
+
// 检查文件名是否匹配过滤规则
|
|
74
|
+
const shouldProcess = !config.fileIncludePatterns || config.fileIncludePatterns.length === 0 ||
|
|
75
|
+
config.fileIncludePatterns.some(pattern => {
|
|
76
|
+
const match = fileName.includes(pattern);
|
|
77
|
+
return match;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (shouldProcess) {
|
|
81
|
+
console.log(`${COLORS.green} 匹配成功,${fileName}${COLORS.reset}-将处理文件: ${filePath}${COLORS.reset}`);
|
|
82
|
+
// 处理匹配的文件
|
|
83
|
+
processFile(filePath, config);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(`遍历目录失败: ${dirPath}`, error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 处理单个文件,删除注释
|
|
94
|
+
* @param {string} filePath - 文件路径
|
|
95
|
+
* @param {Object} config - 配置选项
|
|
96
|
+
*/
|
|
97
|
+
function processFile(filePath, config) {
|
|
98
|
+
try {
|
|
99
|
+
// 读取文件内容
|
|
100
|
+
console.log(`${COLORS.blue}开始处理文件: ${filePath}${COLORS.reset}`);
|
|
101
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
102
|
+
const originalSize = content.length;
|
|
103
|
+
|
|
104
|
+
// 获取文件扩展名
|
|
105
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
106
|
+
|
|
107
|
+
// 根据文件类型删除注释
|
|
108
|
+
if (ext === '.js') {
|
|
109
|
+
console.log(`${COLORS.yellow}检测到JS文件,应用JavaScript注释移除规则${COLORS.reset}`);
|
|
110
|
+
content = removeJavaScriptComments(content, config);
|
|
111
|
+
} else if (ext === '.css') {
|
|
112
|
+
console.log(`${COLORS.yellow}检测到CSS文件,应用CSS注释移除规则${COLORS.reset}`);
|
|
113
|
+
content = removeCssComments(content);
|
|
114
|
+
} else if (ext === '.html') {
|
|
115
|
+
console.log(`${COLORS.yellow}检测到HTML文件,应用HTML注释移除规则${COLORS.reset}`);
|
|
116
|
+
content = removeHtmlComments(content);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const newSize = content.length;
|
|
120
|
+
const removedSize = originalSize - newSize;
|
|
121
|
+
|
|
122
|
+
// 写回文件
|
|
123
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
124
|
+
|
|
125
|
+
console.log(`${COLORS.green}处理完成: ${filePath},移除了 ${removedSize} 个字符的注释${COLORS.reset}`);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error(`${COLORS.red}处理文件失败: ${filePath}${COLORS.reset}`, error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* 移除JavaScript注释
|
|
133
|
+
* @param {string} code - JavaScript代码
|
|
134
|
+
* @param {Object} config - 配置选项
|
|
135
|
+
* @returns {string} - 移除注释后的代码
|
|
136
|
+
*/
|
|
137
|
+
function removeJavaScriptComments(code, config) {
|
|
138
|
+
// 确保 versionPatterns 存在
|
|
139
|
+
const versionPatterns = config.versionPatterns || [];
|
|
140
|
+
|
|
141
|
+
// 只移除包含特定版本信息的多行注释
|
|
142
|
+
// 找出所有多行注释
|
|
143
|
+
const commentRegex = /\/\*[\s\S]*?\*\//g;
|
|
144
|
+
code = code.replace(commentRegex, (match) => {
|
|
145
|
+
// 检查注释是否包含版本信息
|
|
146
|
+
const containsVersion = versionPatterns.some(pattern => match.includes(pattern));
|
|
147
|
+
// 如果包含版本信息,则移除;否则保留
|
|
148
|
+
return containsVersion ? '' : match;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// 移除多余的空白行
|
|
152
|
+
code = code.replace(/\n{3,}/g, '\n\n');
|
|
153
|
+
return code;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 移除CSS注释
|
|
158
|
+
* @param {string} code - CSS代码
|
|
159
|
+
* @returns {string} - 移除注释后的代码
|
|
160
|
+
*/
|
|
161
|
+
function removeCssComments(code) {
|
|
162
|
+
// 移除CSS注释,但保留含有 @charset 的注释
|
|
163
|
+
code = code.replace(/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g, '');
|
|
164
|
+
// 移除多余的空白行
|
|
165
|
+
code = code.replace(/\n{3,}/g, '\n\n');
|
|
166
|
+
return code;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 移除HTML注释
|
|
171
|
+
* @param {string} code - HTML代码
|
|
172
|
+
* @returns {string} - 移除注释后的代码
|
|
173
|
+
*/
|
|
174
|
+
function removeHtmlComments(code) {
|
|
175
|
+
// 移除HTML注释,但保留IE条件注释
|
|
176
|
+
code = code.replace(/<!--[^>]*-->/g, '');
|
|
177
|
+
// 移除多余的空白行
|
|
178
|
+
code = code.replace(/\n{3,}/g, '\n\n');
|
|
179
|
+
return code;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 主函数
|
|
184
|
+
* @param {Object} options - 配置选项
|
|
185
|
+
*/
|
|
186
|
+
function main(options = {}) {
|
|
187
|
+
// 合并配置
|
|
188
|
+
const config = {
|
|
189
|
+
...CONFIG,
|
|
190
|
+
...options
|
|
191
|
+
};
|
|
192
|
+
console.log(`${COLORS.blue}开始处理目录中的注释...${COLORS.reset}`);
|
|
193
|
+
console.log(`${COLORS.blue}目标目录: ${config.distPath}${COLORS.reset}`);
|
|
194
|
+
console.log(`${COLORS.blue}处理文件类型: ${config.fileTypes.join(',')}${COLORS.reset}`);
|
|
195
|
+
if (config.fileIncludePatterns && config.fileIncludePatterns.length > 0) {
|
|
196
|
+
console.log(`${COLORS.yellow}文件名过滤规则: 只处理包含以下关键词的文件: ${config.fileIncludePatterns.join(', ')}${COLORS.reset}`);
|
|
197
|
+
}
|
|
198
|
+
if(config.versionPatterns && config.versionPatterns.length > 0) {
|
|
199
|
+
console.log(`${COLORS.yellow}注释过滤规则: 只移除包含以下关键词的注释: ${config.versionPatterns.join(', ')}${COLORS.reset}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
// 检查目录是否存在
|
|
204
|
+
if (!fs.existsSync(config.distPath)) {
|
|
205
|
+
console.error(`${COLORS.red}错误: 目录不存在 - ${config.distPath}${COLORS.reset}`);
|
|
206
|
+
console.error(`${COLORS.red}请先运行打包命令生成目录${COLORS.reset}`);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 开始遍历处理
|
|
211
|
+
traverseDirectory(config.distPath, config);
|
|
212
|
+
|
|
213
|
+
console.log(`${COLORS.green}注释清理完成!${COLORS.reset}`);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error(`${COLORS.red}处理过程中发生错误:${COLORS.reset}`, error);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// 执行主函数
|
|
221
|
+
if (require.main === module) {
|
|
222
|
+
main();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = {
|
|
226
|
+
main,
|
|
227
|
+
removeJavaScriptComments,
|
|
228
|
+
removeCssComments,
|
|
229
|
+
removeHtmlComments,
|
|
230
|
+
DEFAULT_CONFIG
|
|
231
|
+
};
|