coda-builder 1.0.0 → 1.0.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 +1 -191
- package/build/index.d.mts +174 -0
- package/build/index.d.ts +174 -0
- package/build/index.js +1 -0
- package/build/index.mjs +1 -0
- package/package.json +8 -25
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ npm i coda-builder --dev-save
|
|
|
66
66
|
|
|
67
67
|
在你的业务项目根目录下创建 webpack.config.ts:
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
node服务 配置示例
|
|
70
70
|
|
|
71
71
|
```TypeScript
|
|
72
72
|
import * as path from 'path';
|
|
@@ -88,193 +88,3 @@ const webpackConfig: Configuration = resolveWebpackConfig(config);
|
|
|
88
88
|
|
|
89
89
|
export default webpackConfig;
|
|
90
90
|
```
|
|
91
|
-
|
|
92
|
-
2. node命令行工具 配置示例
|
|
93
|
-
|
|
94
|
-
```TypeScript
|
|
95
|
-
import * as path from 'path';
|
|
96
|
-
import * as fs from 'fs';
|
|
97
|
-
import type {Configuration} from 'webpack';
|
|
98
|
-
import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 递归扫描 src 目录,自动获取所有 index.ts 作为入口
|
|
102
|
-
*/
|
|
103
|
-
function getEntries(srcDir: string) {
|
|
104
|
-
let entries: Record<string, string> = {};
|
|
105
|
-
|
|
106
|
-
function scan(dir: string) {
|
|
107
|
-
const files = fs.readdirSync(dir, {withFileTypes: true});
|
|
108
|
-
files.forEach(file => {
|
|
109
|
-
const fullPath = path.join(dir, file.name);
|
|
110
|
-
if (file.isDirectory()) {
|
|
111
|
-
if (file.name !== 'tmpl' && file.name !== 'templates') {
|
|
112
|
-
scan(fullPath);
|
|
113
|
-
}
|
|
114
|
-
} else if (file.name === 'index.ts' || file.name === 'index.js') {
|
|
115
|
-
const relativePath = path.relative(srcDir, fullPath);
|
|
116
|
-
const entryKey = relativePath.replace(/\\/g, '/').replace(/\.tsx?$/, '');
|
|
117
|
-
entries[entryKey] = fullPath;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
scan(srcDir);
|
|
123
|
-
return entries;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const srcPath = path.resolve(__dirname, 'src');
|
|
127
|
-
|
|
128
|
-
const config: CodaUserConfig = {
|
|
129
|
-
techRoute: 'typescript',
|
|
130
|
-
platformTarget: 'nodejs-cli',
|
|
131
|
-
entry: getEntries(srcPath),
|
|
132
|
-
mode: 'development',
|
|
133
|
-
output: {
|
|
134
|
-
path: path.resolve(__dirname, 'dist'),
|
|
135
|
-
},
|
|
136
|
-
maxChunks: 1,
|
|
137
|
-
alias: {
|
|
138
|
-
'@': path.resolve(__dirname, 'src'),
|
|
139
|
-
},
|
|
140
|
-
extensionAlias: {
|
|
141
|
-
'.js': ['.ts', '.js'],
|
|
142
|
-
'.ts': ['.ts', '.js'],
|
|
143
|
-
},
|
|
144
|
-
copyRules: [
|
|
145
|
-
// 复制根目录基础文件
|
|
146
|
-
{
|
|
147
|
-
type: 'single',
|
|
148
|
-
from: path.resolve(__dirname, 'package.json'),
|
|
149
|
-
to: 'package.json',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
type: 'single',
|
|
153
|
-
from: path.resolve(__dirname, 'README.md'),
|
|
154
|
-
to: 'README.md',
|
|
155
|
-
},
|
|
156
|
-
// 复制目录
|
|
157
|
-
{
|
|
158
|
-
type: 'directory',
|
|
159
|
-
from: path.resolve(__dirname, 'src', 'config'),
|
|
160
|
-
to: 'config',
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
type: 'directory',
|
|
164
|
-
from: path.resolve(__dirname, 'src', 'service'),
|
|
165
|
-
to: 'service',
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
type: 'directory',
|
|
169
|
-
from: path.resolve(__dirname, 'templates'),
|
|
170
|
-
to: 'templates',
|
|
171
|
-
},
|
|
172
|
-
],
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const webpackConfig: Configuration = resolveWebpackConfig(config);
|
|
176
|
-
|
|
177
|
-
export default webpackConfig;
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
3. chrome扩展程序 配置示例
|
|
181
|
-
|
|
182
|
-
```TypeScript
|
|
183
|
-
import * as path from 'path';
|
|
184
|
-
import type {Configuration} from 'webpack';
|
|
185
|
-
import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
|
|
186
|
-
|
|
187
|
-
const config: CodaUserConfig = {
|
|
188
|
-
platformTarget: 'chrome-ext',
|
|
189
|
-
techRoute: 'web',
|
|
190
|
-
entry: {
|
|
191
|
-
background: './src/background.ts',
|
|
192
|
-
sidepanel: './src/sidepanel.ts',
|
|
193
|
-
},
|
|
194
|
-
mode: 'production',
|
|
195
|
-
output: {
|
|
196
|
-
path: path.resolve(__dirname, 'dist'),
|
|
197
|
-
},
|
|
198
|
-
alias: {
|
|
199
|
-
'chat-shared-ui': path.resolve(__dirname, '../../coda-ui/resources'),
|
|
200
|
-
},
|
|
201
|
-
copyRules: [
|
|
202
|
-
{
|
|
203
|
-
type: 'single',
|
|
204
|
-
from: path.resolve(__dirname, 'manifest.json'),
|
|
205
|
-
to: 'manifest.json',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
type: 'template',
|
|
209
|
-
from: path.resolve(__dirname, '../../coda-ui/resources/chat.html'),
|
|
210
|
-
to: 'sidepanel.html',
|
|
211
|
-
data: {
|
|
212
|
-
'{{styleUri}}': 'main.css',
|
|
213
|
-
'{{scriptUri}}': 'sidepanel.js',
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
type: 'single',
|
|
218
|
-
from: path.resolve(__dirname, '../../coda-ui/resources/main.css'),
|
|
219
|
-
to: 'main.css',
|
|
220
|
-
},
|
|
221
|
-
],
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const webpackConfig: Configuration = resolveWebpackConfig(config);
|
|
225
|
-
|
|
226
|
-
export default webpackConfig
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
4. vs code扩展程序 配置示例
|
|
230
|
-
|
|
231
|
-
```TypeScript
|
|
232
|
-
import * as path from 'path';
|
|
233
|
-
import type {Configuration} from 'webpack';
|
|
234
|
-
import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
|
|
235
|
-
|
|
236
|
-
const config: CodaUserConfig = {
|
|
237
|
-
techRoute: 'typescript',
|
|
238
|
-
platformTarget: 'vscode-ext',
|
|
239
|
-
entry: './src/extension.ts',
|
|
240
|
-
mode: 'production',
|
|
241
|
-
output: {
|
|
242
|
-
path: path.resolve(__dirname, 'dist'),
|
|
243
|
-
filename: 'extension.js',
|
|
244
|
-
libraryTarget: 'commonjs',
|
|
245
|
-
},
|
|
246
|
-
alias: {
|
|
247
|
-
'chat-shared-ui': path.resolve(__dirname, '../../coda-ui/resources'),
|
|
248
|
-
},
|
|
249
|
-
copyRules: [
|
|
250
|
-
// 1. 复制共享的 chat.html
|
|
251
|
-
{
|
|
252
|
-
type: 'single',
|
|
253
|
-
from: path.resolve(__dirname, '../../coda-ui/resources/chat.html'),
|
|
254
|
-
to: 'main.html',
|
|
255
|
-
},
|
|
256
|
-
// 2. 复制共享的 main.css
|
|
257
|
-
{
|
|
258
|
-
type: 'single',
|
|
259
|
-
from: path.resolve(__dirname, '../../coda-ui/resources/main.css'),
|
|
260
|
-
to: 'main.css',
|
|
261
|
-
},
|
|
262
|
-
// 3. 复制 main.js
|
|
263
|
-
{
|
|
264
|
-
type: 'single',
|
|
265
|
-
from: path.resolve(__dirname, 'resources', 'main.js'),
|
|
266
|
-
to: 'main.js',
|
|
267
|
-
},
|
|
268
|
-
// 4. 复制 icon.svg
|
|
269
|
-
{
|
|
270
|
-
type: 'single',
|
|
271
|
-
from: path.resolve(__dirname, 'resources', 'icon.svg'),
|
|
272
|
-
to: 'icon.svg',
|
|
273
|
-
},
|
|
274
|
-
],
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
const webpackConfig: Configuration = resolveWebpackConfig(config);
|
|
278
|
-
|
|
279
|
-
export default webpackConfig;
|
|
280
|
-
```
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Configuration } from 'webpack';
|
|
2
|
+
import { Configuration as Configuration$1 } from 'webpack-dev-server';
|
|
3
|
+
import { Options } from 'html-webpack-plugin';
|
|
4
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
|
5
|
+
import CompressionPlugin from 'compression-webpack-plugin';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 技术路线类型定义(必选)
|
|
9
|
+
* - typescript: 纯 TS 项目编译
|
|
10
|
+
* - web: HTML/React/Vue 项目(预留扩展)
|
|
11
|
+
*/
|
|
12
|
+
type TechRoute = 'typescript' | 'web';
|
|
13
|
+
/**
|
|
14
|
+
* 平台目标类型定义(必选)
|
|
15
|
+
* - nodejs-cli: Node.js 命令行工具(仅支持 TS)
|
|
16
|
+
* - node-server: Node.js 服务端应用(仅支持 TS)
|
|
17
|
+
* - chrome-ext: Chrome 浏览器扩展程序(仅支持 TS)
|
|
18
|
+
* - vscode-ext: VS Code 插件扩展(仅支持 TS)
|
|
19
|
+
* - web: Web 平台应用(预留扩展)
|
|
20
|
+
*/
|
|
21
|
+
type PlatformTarget = 'nodejs-cli' | 'node-server' | 'chrome-ext' | 'vscode-ext' | 'web';
|
|
22
|
+
/**
|
|
23
|
+
* Webpack 运行模式(必选)
|
|
24
|
+
* - production: 生产模式
|
|
25
|
+
* - development: 开发模式
|
|
26
|
+
* - analyzer: 性能分析模式
|
|
27
|
+
*/
|
|
28
|
+
type BuildMode = 'production' | 'development' | 'analyzer';
|
|
29
|
+
/** 单文件复制规则 */
|
|
30
|
+
type CopySingleRule = {
|
|
31
|
+
type: 'single';
|
|
32
|
+
/** 源文件路径 */
|
|
33
|
+
from: string;
|
|
34
|
+
/** 目标输出路径 */
|
|
35
|
+
to: string;
|
|
36
|
+
};
|
|
37
|
+
/** 目录递归复制规则 */
|
|
38
|
+
type CopyDirectoryRule = {
|
|
39
|
+
type: 'directory';
|
|
40
|
+
/** 源目录路径 */
|
|
41
|
+
from: string;
|
|
42
|
+
/** 目标输出目录路径 */
|
|
43
|
+
to: string;
|
|
44
|
+
/** 需要忽略的文件或文件夹模式数组 */
|
|
45
|
+
ignore?: string[];
|
|
46
|
+
};
|
|
47
|
+
/** 模板文件处理规则(支持占位符替换) */
|
|
48
|
+
type CopyTemplateRule = {
|
|
49
|
+
type: 'template';
|
|
50
|
+
/** 模板文件源路径 */
|
|
51
|
+
from: string;
|
|
52
|
+
/** 目标输出路径 */
|
|
53
|
+
to: string;
|
|
54
|
+
/** 占位符对应的数据字典值键值对 */
|
|
55
|
+
data: Record<string, string | number>;
|
|
56
|
+
};
|
|
57
|
+
/** 静态资源复制规则联合类型 */
|
|
58
|
+
type CopyRuleItem = CopySingleRule | CopyDirectoryRule | CopyTemplateRule;
|
|
59
|
+
/**
|
|
60
|
+
* WorkerOptions 多线程配置选项
|
|
61
|
+
*/
|
|
62
|
+
interface WorkerOptions {
|
|
63
|
+
name?: string;
|
|
64
|
+
workers?: number;
|
|
65
|
+
workerParallelJobs?: number;
|
|
66
|
+
workerNodeArgs?: string | string[];
|
|
67
|
+
poolRespawn?: boolean;
|
|
68
|
+
poolTimeout?: number;
|
|
69
|
+
poolParallelJobs?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 用户自定义通用配置接口
|
|
73
|
+
*/
|
|
74
|
+
interface CodaUserConfig {
|
|
75
|
+
/**************************自定义属性************************************ */
|
|
76
|
+
/** 1. 适配技术路线 (必选) */
|
|
77
|
+
techRoute: TechRoute;
|
|
78
|
+
/** 2. 多平台构建和开发 (必选) */
|
|
79
|
+
platformTarget: PlatformTarget;
|
|
80
|
+
/** 3. Webpack 运行模式 (必选) */
|
|
81
|
+
mode: BuildMode;
|
|
82
|
+
/**************************webpack自身常用属性**************************** */
|
|
83
|
+
/** 1. 脚本入口 entry (必选,继承 Webpack) */
|
|
84
|
+
entry: Configuration['entry'];
|
|
85
|
+
/** 2. 命令执行上下文 (可选,继承 Webpack)*/
|
|
86
|
+
context?: Configuration['context'];
|
|
87
|
+
/** 3. 构建输出 output (可选,继承 Webpack) */
|
|
88
|
+
output?: Configuration['output'];
|
|
89
|
+
/** 4. 模块匹配与解析规则 module (可选,继承 Webpack module) */
|
|
90
|
+
module?: Configuration['module'];
|
|
91
|
+
/** 5. 模块解析 resolve (可选,继承 Webpack) */
|
|
92
|
+
resolve?: Configuration['resolve'];
|
|
93
|
+
/** 6. 代码优化与分包配置 optimization (可选,继承 Webpack) */
|
|
94
|
+
optimization?: Configuration['optimization'];
|
|
95
|
+
/** 7. 自定义 Webpack 插件列表 plugins (可选,继承 Webpack plugins) */
|
|
96
|
+
plugins?: Configuration['plugins'];
|
|
97
|
+
/** 8. 开发服务器配置 devServer (可选,继承 Webpack devServer) */
|
|
98
|
+
devServer?: Configuration$1;
|
|
99
|
+
/** 9. 缓存配置 (可选,继承 Webpack) */
|
|
100
|
+
cache?: Configuration['cache'];
|
|
101
|
+
/** 10. source map 生成 devtool (可选,继承 Webpack) */
|
|
102
|
+
devtool?: Configuration['devtool'];
|
|
103
|
+
/** 11. 编译目标环境 target (可选,继承 Webpack) */
|
|
104
|
+
target?: Configuration['target'];
|
|
105
|
+
/** 12. 是否开启文件监听 watch (可选,继承 Webpack watch) */
|
|
106
|
+
watch?: Configuration['watch'];
|
|
107
|
+
/** 13. 文件监听选项 watchOptions (可选,继承 Webpack watchOptions) */
|
|
108
|
+
watchOptions?: Configuration['watchOptions'];
|
|
109
|
+
/** 14. 外部依赖处理 externals (可选,继承 Webpack) */
|
|
110
|
+
externals?: Configuration['externals'];
|
|
111
|
+
/** 15. 构建日志输出控制 stats (可选,继承 Webpack) */
|
|
112
|
+
stats?: Configuration['stats'];
|
|
113
|
+
/*****************************webpack属性快捷设置************************************** */
|
|
114
|
+
/** 1. 不需要解析的目录 noParse (可选,自动映射至 Webpack module.noParse) */
|
|
115
|
+
noParse?: Configuration['module'] extends {
|
|
116
|
+
noParse?: infer NP;
|
|
117
|
+
} ? NP : never;
|
|
118
|
+
/** 2. 资源加载器规则(可选,自动映射至 Webpack module.rules) */
|
|
119
|
+
rules?: Configuration['module'] extends {
|
|
120
|
+
rules?: infer NP;
|
|
121
|
+
} ? NP : never;
|
|
122
|
+
/** 1. 模块路径别名 (可选,自动映射至 Webpack resolve.alias) */
|
|
123
|
+
alias?: Record<string, string>;
|
|
124
|
+
/** 2. 模块解析扩展名 extensions (可选,自动映射至 Webpack resolve.extensions) */
|
|
125
|
+
extensions?: string[];
|
|
126
|
+
/** 3. 文件后缀别名映射(可选,自动映射至Webpack resolve.extensionAlias) */
|
|
127
|
+
extensionAlias?: Record<string, string | string[]>;
|
|
128
|
+
/** 4. 模块解析目录 modules (可选,自动映射至 Webpack resolve.modules) */
|
|
129
|
+
modules?: Configuration['resolve'] extends {
|
|
130
|
+
modules?: infer M;
|
|
131
|
+
} ? M : never;
|
|
132
|
+
/** 5. 依赖包主文件字段 mainFields (可选,自动映射至 Webpack resolve.mainFields) */
|
|
133
|
+
mainFields?: Configuration['resolve'] extends {
|
|
134
|
+
mainFields?: infer MF;
|
|
135
|
+
} ? MF : never;
|
|
136
|
+
/** 1. 限制每个入口生成的最大 Chunk 数 (可选) */
|
|
137
|
+
maxChunks?: number;
|
|
138
|
+
/** 2. 代码切片配置 (可选,继承 Webpack optimization.splitChunks) */
|
|
139
|
+
splitChunks?: Configuration['optimization'] extends {
|
|
140
|
+
splitChunks?: infer S;
|
|
141
|
+
} ? S : never;
|
|
142
|
+
/** 3. 是否启用代码压缩 minimization (可选,继承webpack.optimization) */
|
|
143
|
+
minimize?: boolean;
|
|
144
|
+
/** 4. Terser 脚本压缩优化选项 (可选,继承webpack.optimization,基于 terser-webpack-plugin) */
|
|
145
|
+
terserOptions?: TerserPlugin['options'];
|
|
146
|
+
/** 5. 压缩插件启用的 CPU 核心数 (可选,继承webpack.optimization,基于 terser-webpack-plugin) */
|
|
147
|
+
parallel?: number;
|
|
148
|
+
/** 1. 是否开启构建打包测速 (可选,基于 speed-measure-webpack-v5-plugin) */
|
|
149
|
+
speedMeasure?: boolean;
|
|
150
|
+
/** 2. 是否开启多线程编译 thread-loader (可选,基于 thread-loader) */
|
|
151
|
+
thread?: boolean;
|
|
152
|
+
/** 3. thread-loader 的自定义 Worker 选项 (可选,基于 thread-loader) */
|
|
153
|
+
workerOptions?: WorkerOptions;
|
|
154
|
+
/** 1. HTML 模板注入配置 (可选,基于 html-webpack-plugin) */
|
|
155
|
+
html?: Options | boolean;
|
|
156
|
+
/** 2. 静态资源复制规则 (可选) */
|
|
157
|
+
copyRules?: CopyRuleItem[];
|
|
158
|
+
/** 3. Gzip 压缩配置 (可选,基于 compression-webpack-plugin) */
|
|
159
|
+
gzip?: CompressionPlugin['options'] | boolean;
|
|
160
|
+
/*****************************webpack外部通过钩子函数进行高级设置***************************** */
|
|
161
|
+
/** 允许外部修改配置的钩子函数 (可选) */
|
|
162
|
+
configureWebpack?: (config: Configuration, mode: BuildMode) => Configuration | void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 解析并转换外部传入的通用配置,生成最终的标准 Webpack 配置对象
|
|
167
|
+
* @param {CodaUserConfig} userConfig 用户传入的通用配置
|
|
168
|
+
* @param {boolean} isLogger 是否显示日志
|
|
169
|
+
* @returns {WebpackConfiguration} 标准的 Webpack 配置对象
|
|
170
|
+
*/
|
|
171
|
+
declare function resolveWebpackConfig(userConfig: CodaUserConfig, isLogger?: boolean): Configuration;
|
|
172
|
+
|
|
173
|
+
export { resolveWebpackConfig };
|
|
174
|
+
export type { BuildMode, CodaUserConfig, CopyDirectoryRule, CopyRuleItem, CopySingleRule, CopyTemplateRule, PlatformTarget, TechRoute, WorkerOptions };
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Configuration } from 'webpack';
|
|
2
|
+
import { Configuration as Configuration$1 } from 'webpack-dev-server';
|
|
3
|
+
import { Options } from 'html-webpack-plugin';
|
|
4
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
|
5
|
+
import CompressionPlugin from 'compression-webpack-plugin';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 技术路线类型定义(必选)
|
|
9
|
+
* - typescript: 纯 TS 项目编译
|
|
10
|
+
* - web: HTML/React/Vue 项目(预留扩展)
|
|
11
|
+
*/
|
|
12
|
+
type TechRoute = 'typescript' | 'web';
|
|
13
|
+
/**
|
|
14
|
+
* 平台目标类型定义(必选)
|
|
15
|
+
* - nodejs-cli: Node.js 命令行工具(仅支持 TS)
|
|
16
|
+
* - node-server: Node.js 服务端应用(仅支持 TS)
|
|
17
|
+
* - chrome-ext: Chrome 浏览器扩展程序(仅支持 TS)
|
|
18
|
+
* - vscode-ext: VS Code 插件扩展(仅支持 TS)
|
|
19
|
+
* - web: Web 平台应用(预留扩展)
|
|
20
|
+
*/
|
|
21
|
+
type PlatformTarget = 'nodejs-cli' | 'node-server' | 'chrome-ext' | 'vscode-ext' | 'web';
|
|
22
|
+
/**
|
|
23
|
+
* Webpack 运行模式(必选)
|
|
24
|
+
* - production: 生产模式
|
|
25
|
+
* - development: 开发模式
|
|
26
|
+
* - analyzer: 性能分析模式
|
|
27
|
+
*/
|
|
28
|
+
type BuildMode = 'production' | 'development' | 'analyzer';
|
|
29
|
+
/** 单文件复制规则 */
|
|
30
|
+
type CopySingleRule = {
|
|
31
|
+
type: 'single';
|
|
32
|
+
/** 源文件路径 */
|
|
33
|
+
from: string;
|
|
34
|
+
/** 目标输出路径 */
|
|
35
|
+
to: string;
|
|
36
|
+
};
|
|
37
|
+
/** 目录递归复制规则 */
|
|
38
|
+
type CopyDirectoryRule = {
|
|
39
|
+
type: 'directory';
|
|
40
|
+
/** 源目录路径 */
|
|
41
|
+
from: string;
|
|
42
|
+
/** 目标输出目录路径 */
|
|
43
|
+
to: string;
|
|
44
|
+
/** 需要忽略的文件或文件夹模式数组 */
|
|
45
|
+
ignore?: string[];
|
|
46
|
+
};
|
|
47
|
+
/** 模板文件处理规则(支持占位符替换) */
|
|
48
|
+
type CopyTemplateRule = {
|
|
49
|
+
type: 'template';
|
|
50
|
+
/** 模板文件源路径 */
|
|
51
|
+
from: string;
|
|
52
|
+
/** 目标输出路径 */
|
|
53
|
+
to: string;
|
|
54
|
+
/** 占位符对应的数据字典值键值对 */
|
|
55
|
+
data: Record<string, string | number>;
|
|
56
|
+
};
|
|
57
|
+
/** 静态资源复制规则联合类型 */
|
|
58
|
+
type CopyRuleItem = CopySingleRule | CopyDirectoryRule | CopyTemplateRule;
|
|
59
|
+
/**
|
|
60
|
+
* WorkerOptions 多线程配置选项
|
|
61
|
+
*/
|
|
62
|
+
interface WorkerOptions {
|
|
63
|
+
name?: string;
|
|
64
|
+
workers?: number;
|
|
65
|
+
workerParallelJobs?: number;
|
|
66
|
+
workerNodeArgs?: string | string[];
|
|
67
|
+
poolRespawn?: boolean;
|
|
68
|
+
poolTimeout?: number;
|
|
69
|
+
poolParallelJobs?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 用户自定义通用配置接口
|
|
73
|
+
*/
|
|
74
|
+
interface CodaUserConfig {
|
|
75
|
+
/**************************自定义属性************************************ */
|
|
76
|
+
/** 1. 适配技术路线 (必选) */
|
|
77
|
+
techRoute: TechRoute;
|
|
78
|
+
/** 2. 多平台构建和开发 (必选) */
|
|
79
|
+
platformTarget: PlatformTarget;
|
|
80
|
+
/** 3. Webpack 运行模式 (必选) */
|
|
81
|
+
mode: BuildMode;
|
|
82
|
+
/**************************webpack自身常用属性**************************** */
|
|
83
|
+
/** 1. 脚本入口 entry (必选,继承 Webpack) */
|
|
84
|
+
entry: Configuration['entry'];
|
|
85
|
+
/** 2. 命令执行上下文 (可选,继承 Webpack)*/
|
|
86
|
+
context?: Configuration['context'];
|
|
87
|
+
/** 3. 构建输出 output (可选,继承 Webpack) */
|
|
88
|
+
output?: Configuration['output'];
|
|
89
|
+
/** 4. 模块匹配与解析规则 module (可选,继承 Webpack module) */
|
|
90
|
+
module?: Configuration['module'];
|
|
91
|
+
/** 5. 模块解析 resolve (可选,继承 Webpack) */
|
|
92
|
+
resolve?: Configuration['resolve'];
|
|
93
|
+
/** 6. 代码优化与分包配置 optimization (可选,继承 Webpack) */
|
|
94
|
+
optimization?: Configuration['optimization'];
|
|
95
|
+
/** 7. 自定义 Webpack 插件列表 plugins (可选,继承 Webpack plugins) */
|
|
96
|
+
plugins?: Configuration['plugins'];
|
|
97
|
+
/** 8. 开发服务器配置 devServer (可选,继承 Webpack devServer) */
|
|
98
|
+
devServer?: Configuration$1;
|
|
99
|
+
/** 9. 缓存配置 (可选,继承 Webpack) */
|
|
100
|
+
cache?: Configuration['cache'];
|
|
101
|
+
/** 10. source map 生成 devtool (可选,继承 Webpack) */
|
|
102
|
+
devtool?: Configuration['devtool'];
|
|
103
|
+
/** 11. 编译目标环境 target (可选,继承 Webpack) */
|
|
104
|
+
target?: Configuration['target'];
|
|
105
|
+
/** 12. 是否开启文件监听 watch (可选,继承 Webpack watch) */
|
|
106
|
+
watch?: Configuration['watch'];
|
|
107
|
+
/** 13. 文件监听选项 watchOptions (可选,继承 Webpack watchOptions) */
|
|
108
|
+
watchOptions?: Configuration['watchOptions'];
|
|
109
|
+
/** 14. 外部依赖处理 externals (可选,继承 Webpack) */
|
|
110
|
+
externals?: Configuration['externals'];
|
|
111
|
+
/** 15. 构建日志输出控制 stats (可选,继承 Webpack) */
|
|
112
|
+
stats?: Configuration['stats'];
|
|
113
|
+
/*****************************webpack属性快捷设置************************************** */
|
|
114
|
+
/** 1. 不需要解析的目录 noParse (可选,自动映射至 Webpack module.noParse) */
|
|
115
|
+
noParse?: Configuration['module'] extends {
|
|
116
|
+
noParse?: infer NP;
|
|
117
|
+
} ? NP : never;
|
|
118
|
+
/** 2. 资源加载器规则(可选,自动映射至 Webpack module.rules) */
|
|
119
|
+
rules?: Configuration['module'] extends {
|
|
120
|
+
rules?: infer NP;
|
|
121
|
+
} ? NP : never;
|
|
122
|
+
/** 1. 模块路径别名 (可选,自动映射至 Webpack resolve.alias) */
|
|
123
|
+
alias?: Record<string, string>;
|
|
124
|
+
/** 2. 模块解析扩展名 extensions (可选,自动映射至 Webpack resolve.extensions) */
|
|
125
|
+
extensions?: string[];
|
|
126
|
+
/** 3. 文件后缀别名映射(可选,自动映射至Webpack resolve.extensionAlias) */
|
|
127
|
+
extensionAlias?: Record<string, string | string[]>;
|
|
128
|
+
/** 4. 模块解析目录 modules (可选,自动映射至 Webpack resolve.modules) */
|
|
129
|
+
modules?: Configuration['resolve'] extends {
|
|
130
|
+
modules?: infer M;
|
|
131
|
+
} ? M : never;
|
|
132
|
+
/** 5. 依赖包主文件字段 mainFields (可选,自动映射至 Webpack resolve.mainFields) */
|
|
133
|
+
mainFields?: Configuration['resolve'] extends {
|
|
134
|
+
mainFields?: infer MF;
|
|
135
|
+
} ? MF : never;
|
|
136
|
+
/** 1. 限制每个入口生成的最大 Chunk 数 (可选) */
|
|
137
|
+
maxChunks?: number;
|
|
138
|
+
/** 2. 代码切片配置 (可选,继承 Webpack optimization.splitChunks) */
|
|
139
|
+
splitChunks?: Configuration['optimization'] extends {
|
|
140
|
+
splitChunks?: infer S;
|
|
141
|
+
} ? S : never;
|
|
142
|
+
/** 3. 是否启用代码压缩 minimization (可选,继承webpack.optimization) */
|
|
143
|
+
minimize?: boolean;
|
|
144
|
+
/** 4. Terser 脚本压缩优化选项 (可选,继承webpack.optimization,基于 terser-webpack-plugin) */
|
|
145
|
+
terserOptions?: TerserPlugin['options'];
|
|
146
|
+
/** 5. 压缩插件启用的 CPU 核心数 (可选,继承webpack.optimization,基于 terser-webpack-plugin) */
|
|
147
|
+
parallel?: number;
|
|
148
|
+
/** 1. 是否开启构建打包测速 (可选,基于 speed-measure-webpack-v5-plugin) */
|
|
149
|
+
speedMeasure?: boolean;
|
|
150
|
+
/** 2. 是否开启多线程编译 thread-loader (可选,基于 thread-loader) */
|
|
151
|
+
thread?: boolean;
|
|
152
|
+
/** 3. thread-loader 的自定义 Worker 选项 (可选,基于 thread-loader) */
|
|
153
|
+
workerOptions?: WorkerOptions;
|
|
154
|
+
/** 1. HTML 模板注入配置 (可选,基于 html-webpack-plugin) */
|
|
155
|
+
html?: Options | boolean;
|
|
156
|
+
/** 2. 静态资源复制规则 (可选) */
|
|
157
|
+
copyRules?: CopyRuleItem[];
|
|
158
|
+
/** 3. Gzip 压缩配置 (可选,基于 compression-webpack-plugin) */
|
|
159
|
+
gzip?: CompressionPlugin['options'] | boolean;
|
|
160
|
+
/*****************************webpack外部通过钩子函数进行高级设置***************************** */
|
|
161
|
+
/** 允许外部修改配置的钩子函数 (可选) */
|
|
162
|
+
configureWebpack?: (config: Configuration, mode: BuildMode) => Configuration | void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 解析并转换外部传入的通用配置,生成最终的标准 Webpack 配置对象
|
|
167
|
+
* @param {CodaUserConfig} userConfig 用户传入的通用配置
|
|
168
|
+
* @param {boolean} isLogger 是否显示日志
|
|
169
|
+
* @returns {WebpackConfiguration} 标准的 Webpack 配置对象
|
|
170
|
+
*/
|
|
171
|
+
declare function resolveWebpackConfig(userConfig: CodaUserConfig, isLogger?: boolean): Configuration;
|
|
172
|
+
|
|
173
|
+
export { resolveWebpackConfig };
|
|
174
|
+
export type { BuildMode, CodaUserConfig, CopyDirectoryRule, CopyRuleItem, CopySingleRule, CopyTemplateRule, PlatformTarget, TechRoute, WorkerOptions };
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var j=Object.create;var h=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var i in e)h(t,i,{get:e[i],enumerable:!0})},C=(t,e,i,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of T(e))!F.call(t,s)&&s!==i&&h(t,s,{get:()=>e[s],enumerable:!(o=q(e,s))||o.enumerable});return t};var d=(t,e,i)=>(i=t!=null?j(N(t)):{},C(e||!t||!t.__esModule?h(i,"default",{value:t,enumerable:!0}):i,t)),U=t=>C(h({},"__esModule",{value:!0}),t);var G={};D(G,{resolveWebpackConfig:()=>M});module.exports=U(G);var v=d(require("webpack-node-externals")),O=require("webpack-bundle-analyzer");var w=d(require("path")),z=d(require("os")),S=d(require("webpackbar")),u={js:/\.(ts|js)$/,css:/\.css$/,image:/\.(png|jpg|jpeg|gif|svg)$/,font:/\.(woff|woff2|eot|ttf|otf)$/,media:/\.(mp4|webm|ogg|mp3|wav)$/},y=(t={},e="development")=>{let i=z.default.cpus().length||4;return{name:t.name||"ts-thread",workers:t.workers||(e==="development"?2:Math.max(1,Math.floor((i-2)/2))),workerParallelJobs:t.workerParallelJobs||(e==="development"?40:20),workerNodeArgs:Array.isArray(t.workerNodeArgs)?t.workerNodeArgs:[t.workerNodeArgs||(e==="development"?"--max-old-space-size=512":"--max-old-space-size=256")],poolRespawn:t.poolRespawn??e!=="development",poolTimeout:t.poolTimeout||500,poolParallelJobs:t.poolParallelJobs||(e==="development"?200:100)}},A=(t=!1,e)=>{let i=[];if(e?.thread){let o=y(e.workerOptions,e.mode);i.push({loader:"thread-loader",options:o})}return i.push({loader:"ts-loader",options:{compilerOptions:{declaration:!1,declarationMap:!1}}}),{mode:"none",output:{path:w.default.resolve(__dirname,"dist"),clean:!0},resolve:{extensions:[".ts",".js"],modules:["node_modules"]},module:{rules:[{test:u.js,use:i,exclude:/node_modules/},{test:u.css,use:[t?{loader:require("mini-css-extract-plugin").loader}:"style-loader",{loader:"css-loader",options:{sourceMap:!0,importLoaders:1}},"postcss-loader"]},{test:u.image,type:"asset/resource",generator:{filename:"assets/img/[hash][ext]"}},{test:u.font,type:"asset/resource",generator:{filename:"assets/font/[name][ext]"}},{test:u.media,type:"asset/resource",generator:{filename:"assets/media/[name][ext]"}}]},plugins:[new S.default({name:"coda-builder",color:"#0052cc"})],devServer:{historyApiFallback:!0,port:8080,compress:!1,open:!1,hot:!0,static:{directory:w.default.join(process.cwd(),"dist")}},stats:"minimal"}};var g=class{config;constructor(e){this.config={...e}}setMode(e){return this.config.mode=e,this}setEntry(e){return this.config.entry=e,this}setContext(e){return e!==void 0&&(this.config.context=e),this}setOutput(e){return e?(this.config.output={...this.config.output,...e},this):this}setDevtool(e){return e!==void 0&&(this.config.devtool=e),this}setTarget(e){return e!==void 0&&(this.config.target=e),this}setCache(e){return e!==void 0&&(this.config.cache=e),this}setResolve(e,i){let o=i?.modules,s=i?.mainFields,n=i?.alias,r=i?.extensions,a=i?.extensionAlias;return this.config.resolve={...this.config.resolve,...o?{modules:o}:{},...s?{mainFields:s}:{},...n?{alias:n}:{},...r?{extensions:r}:{},...a?{extensionAlias:a}:{},...e},this}setModule(e,i){let o=this.config.module?.rules||[],s=i?.rules||[],n=i?.noParse;return this.config.module={...this.config.module||{},...n?{noParse:n}:{},rules:[...o,...s],...e},this}setOptimization(e,i,o,s,n,r,a){let l=i;l===void 0&&(s==="web"||s==="chrome-ext")&&(l={chunks:"all",minSize:2e4,maxSize:2e5,minChunks:1,maxAsyncRequests:6,maxInitialRequests:6,cacheGroups:{libs:{name:"chunk-libs",test:/[\\/]node_modules[\\/]/,chunks:"initial",priority:20,reuseExistingChunk:!0},common:{name:"chunk-common",minChunks:2,priority:2,reuseExistingChunk:!0}}});let m=r!==void 0?r:n==="production"||n==="analyzer",p=e?.minimizer||this.config.optimization?.minimizer;if(m&&!p)try{let P=require("terser-webpack-plugin"),E=require("css-minimizer-webpack-plugin"),R=o!==void 0?o:{parse:{ecma:8},compress:{ecma:5,comparisons:!1,inline:2,warnings:!1},mangle:!0,module:!1,output:{ecma:5,comments:!1},toplevel:!1,ie8:!1,safari10:!1},W=a||2;p=[new P({parallel:W,terserOptions:R}),new E({parallel:W})]}catch{}let f=e?.runtimeChunk||this.config.optimization?.runtimeChunk;return l!==void 0&&!f&&(f={name:"manifest"}),this.config.optimization={...this.config.optimization||{},minimize:m,...l!==void 0?{splitChunks:l}:{},...p!==void 0?{minimizer:p}:{},...f!==void 0?{runtimeChunk:f}:{},...e},this}setStats(e){return e!==void 0&&(this.config.stats=e),this}setDevServer(e){if(!e)return this;let i=this.config.devServer||{};return this.config.devServer={...i,...e,...e.static?{static:typeof e.static=="object"&&typeof i.static=="object"?{...i.static,...e.static}:e.static}:{}},this}setWatch(e){return e!==void 0&&(this.config.watch=e),this}setWatchOptions(e){return e?(this.config.watchOptions={...this.config.watchOptions,...e},this):this}setExternals(e){return e!==void 0&&(this.config.externals=e),this}addPlugin(e){return this.config.plugins=this.config.plugins||[],this.config.plugins.push(e),this}addPlugins(e){return!e||!Array.isArray(e)?this:(e.forEach(i=>{i&&this.addPlugin(i)}),this)}setMaxChunks(e){if(e===void 0)return this;let i=require("webpack");return this.addPlugin(new i.optimize.LimitChunkCountPlugin({maxChunks:e})),this}getConfig(){return this.config}setConfig(e){return this.config={...this.config,...e},this}};var c=d(require("fs")),b=d(require("path")),k=class{rules;constructor(e=[]){this.rules=e}apply(e){e.hooks.thisCompilation.tap("CodaCopyWebpackPlugin",i=>{i.hooks.processAssets.tap({name:"CodaCopyWebpackPlugin",stage:e.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS},()=>{this.rules.forEach(o=>{c.default.existsSync(o.from)&&(o.type==="single"?this.processSingleFile(i,o.from,o.to):o.type==="directory"?this.processDirectory(i,o.from,o.to,o.ignore||[]):o.type==="template"&&this.processTemplate(i,o.from,o.to,o.data))})})})}processSingleFile(e,i,o){let s=c.default.readFileSync(i);e.emitAsset(o,new e.compiler.webpack.sources.RawSource(s))}processDirectory(e,i,o,s){c.default.readdirSync(i,{recursive:!0}).forEach(r=>{let a=b.default.join(i,r);if(c.default.statSync(a).isDirectory())return;let l=b.default.relative(i,a);if(s.some(p=>l.includes(p)))return;let x=b.default.join(o,l).replace(/\\/g,"/"),m=c.default.readFileSync(a);e.emitAsset(x,new e.compiler.webpack.sources.RawSource(m))})}processTemplate(e,i,o,s){let n=c.default.readFileSync(i,"utf-8");Object.keys(s).forEach(r=>{let a=r.replace(/{{\s*|\s*}}/g,""),l=new RegExp(`{{\\s*${a}\\s*}}`,"g");n=n.replace(l,String(s[r]))}),e.emitAsset(o,new e.compiler.webpack.sources.RawSource(Buffer.from(n)))}};function _(t){if(!t.techRoute)throw new Error("[coda-builder] Missing required config: techRoute");if(!t.platformTarget)throw new Error("[coda-builder] Missing required config: platformTarget");if(!t.mode)throw new Error("[coda-builder] Missing required config: mode");if(!t.entry)throw new Error("[coda-builder] Missing required config: entry")}function I(t){let e=t.mode==="production"||t.mode==="analyzer";return A(e,t)}function B(t,e){let{platformTarget:i}=t;["nodejs-cli","node-server","vscode-ext"].includes(i)?(e.setTarget("node"),i==="vscode-ext"?e.setExternals([(0,v.default)(),{vscode:"commonjs vscode"}]):e.setExternals([(0,v.default)()])):i==="chrome-ext"&&e.setTarget("web")}function $(t,e){let i=t.mode==="analyzer"?"production":t.mode;e.setMode(i).setEntry(t.entry).setContext(t.context).setOutput(t.output).setDevtool(t.devtool).setCache(t.cache).setMaxChunks(t.maxChunks).setStats(t.stats).setDevServer(t.devServer).setWatch(t.watch).setWatchOptions(t.watchOptions),e.setOptimization(t.optimization,t.splitChunks,t.terserOptions,t.platformTarget,i,t.minimize,t.parallel),e.setResolve(t.resolve,{alias:t.alias,extensions:t.extensions,extensionAlias:t.extensionAlias,modules:t.modules,mainFields:t.mainFields}),e.setModule(t.module,{noParse:t.noParse,rules:t.rules}),t.target&&e.setTarget(t.target),t.externals&&e.setExternals(t.externals)}function J(t,e){let i=t.mode==="production"||t.mode==="analyzer";if(t.copyRules&&t.copyRules.length>0&&e.addPlugin(new k(t.copyRules)),t.html)try{let o=require("html-webpack-plugin"),s=typeof t.html=="object"?t.html:{};e.addPlugin(new o(s))}catch{throw new Error('[coda-builder] html-webpack-plugin is required when using "html" config. Please install it.')}if(i)try{let o=require("mini-css-extract-plugin");e.addPlugin(new o({filename:"css/[name].[contenthash:8].css",chunkFilename:"css/[name].[contenthash:8].chunk.css"}))}catch{throw new Error("[coda-builder] mini-css-extract-plugin is required in production mode. Please install it.")}if(t.gzip!==!1&&(t.gzip||i))try{let o=require("compression-webpack-plugin"),s={filename:"[path][base].gz",algorithm:"gzip",test:/\.(js|css|png|jpg|jpeg|svg)(\?.*)?$/i,threshold:8192,minRatio:.8,deleteOriginalAssets:!1,exclude:[/node_modules/]},n=typeof t.gzip=="object"?{...s,...t.gzip}:s;e.addPlugin(new o(n))}catch{throw new Error('[coda-builder] compression-webpack-plugin is required when using "gzip" config. Please install it.')}t.plugins&&t.plugins.length>0&&e.addPlugins(t.plugins),t.mode==="analyzer"&&e.addPlugin(new O.BundleAnalyzerPlugin({analyzerMode:"server"}))}function L(t,e){if(t.configureWebpack&&typeof t.configureWebpack=="function"){let i=t.configureWebpack(e,t.mode);if(i)return i}return e}function M(t,e){if(_(t),t.thread&&t.mode==="development")try{let n=require("thread-loader"),r=y(t.workerOptions||{name:"ts-thread",workers:2,workerParallelJobs:40,workerNodeArgs:"--max-old-space-size=512",poolRespawn:!1,poolParallelJobs:200},t.mode);n.warmup({workerBabelArgs:r},["ts-loader"])}catch{}let i=I(t),o=new g(i);o.setConfig({context:process.cwd()}),B(t,o),$(t,o),J(t,o);let s=o.getConfig();if(s=L(t,s),t.speedMeasure&&(t.mode==="development"||t.mode==="analyzer"))try{let n=require("speed-measure-webpack-v5-plugin");s=new n().wrap(s)}catch{throw new Error('[coda-builder] speed-measure-webpack-v5-plugin is required when using "speedMeasure" config. Please install it.')}return e&&(console.log("webpack\u914D\u7F6E:"),console.dir(i,{depth:null})),s}0&&(module.exports={resolveWebpackConfig});
|
package/build/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,i)=>(typeof require<"u"?require:e)[i]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});import W from"webpack-node-externals";import{BundleAnalyzerPlugin as O}from"webpack-bundle-analyzer";import x from"path";import S from"os";import A from"webpackbar";var u={js:/\.(ts|js)$/,css:/\.css$/,image:/\.(png|jpg|jpeg|gif|svg)$/,font:/\.(woff|woff2|eot|ttf|otf)$/,media:/\.(mp4|webm|ogg|mp3|wav)$/},b=(t={},e="development")=>{let i=S.cpus().length||4;return{name:t.name||"ts-thread",workers:t.workers||(e==="development"?2:Math.max(1,Math.floor((i-2)/2))),workerParallelJobs:t.workerParallelJobs||(e==="development"?40:20),workerNodeArgs:Array.isArray(t.workerNodeArgs)?t.workerNodeArgs:[t.workerNodeArgs||(e==="development"?"--max-old-space-size=512":"--max-old-space-size=256")],poolRespawn:t.poolRespawn??e!=="development",poolTimeout:t.poolTimeout||500,poolParallelJobs:t.poolParallelJobs||(e==="development"?200:100)}},P=(t=!1,e)=>{let i=[];if(e?.thread){let o=b(e.workerOptions,e.mode);i.push({loader:"thread-loader",options:o})}return i.push({loader:"ts-loader",options:{compilerOptions:{declaration:!1,declarationMap:!1}}}),{mode:"none",output:{path:x.resolve(__dirname,"dist"),clean:!0},resolve:{extensions:[".ts",".js"],modules:["node_modules"]},module:{rules:[{test:u.js,use:i,exclude:/node_modules/},{test:u.css,use:[t?{loader:c("mini-css-extract-plugin").loader}:"style-loader",{loader:"css-loader",options:{sourceMap:!0,importLoaders:1}},"postcss-loader"]},{test:u.image,type:"asset/resource",generator:{filename:"assets/img/[hash][ext]"}},{test:u.font,type:"asset/resource",generator:{filename:"assets/font/[name][ext]"}},{test:u.media,type:"asset/resource",generator:{filename:"assets/media/[name][ext]"}}]},plugins:[new A({name:"coda-builder",color:"#0052cc"})],devServer:{historyApiFallback:!0,port:8080,compress:!1,open:!1,hot:!0,static:{directory:x.join(process.cwd(),"dist")}},stats:"minimal"}};var h=class{config;constructor(e){this.config={...e}}setMode(e){return this.config.mode=e,this}setEntry(e){return this.config.entry=e,this}setContext(e){return e!==void 0&&(this.config.context=e),this}setOutput(e){return e?(this.config.output={...this.config.output,...e},this):this}setDevtool(e){return e!==void 0&&(this.config.devtool=e),this}setTarget(e){return e!==void 0&&(this.config.target=e),this}setCache(e){return e!==void 0&&(this.config.cache=e),this}setResolve(e,i){let o=i?.modules,s=i?.mainFields,n=i?.alias,r=i?.extensions,a=i?.extensionAlias;return this.config.resolve={...this.config.resolve,...o?{modules:o}:{},...s?{mainFields:s}:{},...n?{alias:n}:{},...r?{extensions:r}:{},...a?{extensionAlias:a}:{},...e},this}setModule(e,i){let o=this.config.module?.rules||[],s=i?.rules||[],n=i?.noParse;return this.config.module={...this.config.module||{},...n?{noParse:n}:{},rules:[...o,...s],...e},this}setOptimization(e,i,o,s,n,r,a){let l=i;l===void 0&&(s==="web"||s==="chrome-ext")&&(l={chunks:"all",minSize:2e4,maxSize:2e5,minChunks:1,maxAsyncRequests:6,maxInitialRequests:6,cacheGroups:{libs:{name:"chunk-libs",test:/[\\/]node_modules[\\/]/,chunks:"initial",priority:20,reuseExistingChunk:!0},common:{name:"chunk-common",minChunks:2,priority:2,reuseExistingChunk:!0}}});let m=r!==void 0?r:n==="production"||n==="analyzer",p=e?.minimizer||this.config.optimization?.minimizer;if(m&&!p)try{let y=c("terser-webpack-plugin"),C=c("css-minimizer-webpack-plugin"),z=o!==void 0?o:{parse:{ecma:8},compress:{ecma:5,comparisons:!1,inline:2,warnings:!1},mangle:!0,module:!1,output:{ecma:5,comments:!1},toplevel:!1,ie8:!1,safari10:!1},v=a||2;p=[new y({parallel:v,terserOptions:z}),new C({parallel:v})]}catch{}let f=e?.runtimeChunk||this.config.optimization?.runtimeChunk;return l!==void 0&&!f&&(f={name:"manifest"}),this.config.optimization={...this.config.optimization||{},minimize:m,...l!==void 0?{splitChunks:l}:{},...p!==void 0?{minimizer:p}:{},...f!==void 0?{runtimeChunk:f}:{},...e},this}setStats(e){return e!==void 0&&(this.config.stats=e),this}setDevServer(e){if(!e)return this;let i=this.config.devServer||{};return this.config.devServer={...i,...e,...e.static?{static:typeof e.static=="object"&&typeof i.static=="object"?{...i.static,...e.static}:e.static}:{}},this}setWatch(e){return e!==void 0&&(this.config.watch=e),this}setWatchOptions(e){return e?(this.config.watchOptions={...this.config.watchOptions,...e},this):this}setExternals(e){return e!==void 0&&(this.config.externals=e),this}addPlugin(e){return this.config.plugins=this.config.plugins||[],this.config.plugins.push(e),this}addPlugins(e){return!e||!Array.isArray(e)?this:(e.forEach(i=>{i&&this.addPlugin(i)}),this)}setMaxChunks(e){if(e===void 0)return this;let i=c("webpack");return this.addPlugin(new i.optimize.LimitChunkCountPlugin({maxChunks:e})),this}getConfig(){return this.config}setConfig(e){return this.config={...this.config,...e},this}};import d from"fs";import k from"path";var g=class{rules;constructor(e=[]){this.rules=e}apply(e){e.hooks.thisCompilation.tap("CodaCopyWebpackPlugin",i=>{i.hooks.processAssets.tap({name:"CodaCopyWebpackPlugin",stage:e.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS},()=>{this.rules.forEach(o=>{d.existsSync(o.from)&&(o.type==="single"?this.processSingleFile(i,o.from,o.to):o.type==="directory"?this.processDirectory(i,o.from,o.to,o.ignore||[]):o.type==="template"&&this.processTemplate(i,o.from,o.to,o.data))})})})}processSingleFile(e,i,o){let s=d.readFileSync(i);e.emitAsset(o,new e.compiler.webpack.sources.RawSource(s))}processDirectory(e,i,o,s){d.readdirSync(i,{recursive:!0}).forEach(r=>{let a=k.join(i,r);if(d.statSync(a).isDirectory())return;let l=k.relative(i,a);if(s.some(p=>l.includes(p)))return;let w=k.join(o,l).replace(/\\/g,"/"),m=d.readFileSync(a);e.emitAsset(w,new e.compiler.webpack.sources.RawSource(m))})}processTemplate(e,i,o,s){let n=d.readFileSync(i,"utf-8");Object.keys(s).forEach(r=>{let a=r.replace(/{{\s*|\s*}}/g,""),l=new RegExp(`{{\\s*${a}\\s*}}`,"g");n=n.replace(l,String(s[r]))}),e.emitAsset(o,new e.compiler.webpack.sources.RawSource(Buffer.from(n)))}};function M(t){if(!t.techRoute)throw new Error("[coda-builder] Missing required config: techRoute");if(!t.platformTarget)throw new Error("[coda-builder] Missing required config: platformTarget");if(!t.mode)throw new Error("[coda-builder] Missing required config: mode");if(!t.entry)throw new Error("[coda-builder] Missing required config: entry")}function E(t){let e=t.mode==="production"||t.mode==="analyzer";return P(e,t)}function R(t,e){let{platformTarget:i}=t;["nodejs-cli","node-server","vscode-ext"].includes(i)?(e.setTarget("node"),i==="vscode-ext"?e.setExternals([W(),{vscode:"commonjs vscode"}]):e.setExternals([W()])):i==="chrome-ext"&&e.setTarget("web")}function j(t,e){let i=t.mode==="analyzer"?"production":t.mode;e.setMode(i).setEntry(t.entry).setContext(t.context).setOutput(t.output).setDevtool(t.devtool).setCache(t.cache).setMaxChunks(t.maxChunks).setStats(t.stats).setDevServer(t.devServer).setWatch(t.watch).setWatchOptions(t.watchOptions),e.setOptimization(t.optimization,t.splitChunks,t.terserOptions,t.platformTarget,i,t.minimize,t.parallel),e.setResolve(t.resolve,{alias:t.alias,extensions:t.extensions,extensionAlias:t.extensionAlias,modules:t.modules,mainFields:t.mainFields}),e.setModule(t.module,{noParse:t.noParse,rules:t.rules}),t.target&&e.setTarget(t.target),t.externals&&e.setExternals(t.externals)}function q(t,e){let i=t.mode==="production"||t.mode==="analyzer";if(t.copyRules&&t.copyRules.length>0&&e.addPlugin(new g(t.copyRules)),t.html)try{let o=c("html-webpack-plugin"),s=typeof t.html=="object"?t.html:{};e.addPlugin(new o(s))}catch{throw new Error('[coda-builder] html-webpack-plugin is required when using "html" config. Please install it.')}if(i)try{let o=c("mini-css-extract-plugin");e.addPlugin(new o({filename:"css/[name].[contenthash:8].css",chunkFilename:"css/[name].[contenthash:8].chunk.css"}))}catch{throw new Error("[coda-builder] mini-css-extract-plugin is required in production mode. Please install it.")}if(t.gzip!==!1&&(t.gzip||i))try{let o=c("compression-webpack-plugin"),s={filename:"[path][base].gz",algorithm:"gzip",test:/\.(js|css|png|jpg|jpeg|svg)(\?.*)?$/i,threshold:8192,minRatio:.8,deleteOriginalAssets:!1,exclude:[/node_modules/]},n=typeof t.gzip=="object"?{...s,...t.gzip}:s;e.addPlugin(new o(n))}catch{throw new Error('[coda-builder] compression-webpack-plugin is required when using "gzip" config. Please install it.')}t.plugins&&t.plugins.length>0&&e.addPlugins(t.plugins),t.mode==="analyzer"&&e.addPlugin(new O({analyzerMode:"server"}))}function T(t,e){if(t.configureWebpack&&typeof t.configureWebpack=="function"){let i=t.configureWebpack(e,t.mode);if(i)return i}return e}function N(t,e){if(M(t),t.thread&&t.mode==="development")try{let n=c("thread-loader"),r=b(t.workerOptions||{name:"ts-thread",workers:2,workerParallelJobs:40,workerNodeArgs:"--max-old-space-size=512",poolRespawn:!1,poolParallelJobs:200},t.mode);n.warmup({workerBabelArgs:r},["ts-loader"])}catch{}let i=E(t),o=new h(i);o.setConfig({context:process.cwd()}),R(t,o),j(t,o),q(t,o);let s=o.getConfig();if(s=T(t,s),t.speedMeasure&&(t.mode==="development"||t.mode==="analyzer"))try{let n=c("speed-measure-webpack-v5-plugin");s=new n().wrap(s)}catch{throw new Error('[coda-builder] speed-measure-webpack-v5-plugin is required when using "speedMeasure" config. Please install it.')}return e&&(console.log("webpack\u914D\u7F6E:"),console.dir(i,{depth:null})),s}export{N as resolveWebpackConfig};
|
package/package.json
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coda-builder",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"typecheck": "tsc --noEmit"
|
|
7
|
-
},
|
|
8
|
-
"main": "dist/src/index.js",
|
|
9
|
-
"types": "dist/src/index.d.ts",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"main": "./build/index.js",
|
|
5
|
+
"types": "./build/index.d.ts",
|
|
10
6
|
"exports": {
|
|
11
7
|
".": {
|
|
12
|
-
"types": "./
|
|
13
|
-
"require": "./
|
|
14
|
-
"import": "./
|
|
8
|
+
"types": "./build/index.d.ts",
|
|
9
|
+
"require": "./build/index.js",
|
|
10
|
+
"import": "./build/index.js"
|
|
15
11
|
}
|
|
16
12
|
},
|
|
17
13
|
"dependencies": {
|
|
@@ -36,18 +32,5 @@
|
|
|
36
32
|
"terser-webpack-plugin": "^5.6.1",
|
|
37
33
|
"speed-measure-webpack-v5-plugin": "^1.5.2",
|
|
38
34
|
"thread-loader": "4.0.2"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
"@types/node": "^22.0.0",
|
|
42
|
-
"@types/webpack": "^5.28.5",
|
|
43
|
-
"@types/webpack-dev-server": "^4.7.2",
|
|
44
|
-
"@types/webpackbar": "^5.0.0",
|
|
45
|
-
"@types/webpack-node-externals": "^3.0.4",
|
|
46
|
-
"@types/webpack-bundle-analyzer": "^4.7.0",
|
|
47
|
-
"ts-node": "^10.9.2",
|
|
48
|
-
"typescript": "^5.5.0"
|
|
49
|
-
},
|
|
50
|
-
"files": [
|
|
51
|
-
"dist"
|
|
52
|
-
]
|
|
53
|
-
}
|
|
35
|
+
}
|
|
36
|
+
}
|