coda-builder 0.0.0-stage → 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 +89 -2
- 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 +33 -3
package/README.md
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Coda-Builder
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`Coda-Builder` 是一个专为 TypeScript 多平台打造的现代化 Webpack 封装与标准化构建工具。旨在以极低的配置开销,统一管理和输出多平台项目(Node CLI、Node Server、VS Code 扩展、Chrome 扩展、Web等)
|
|
4
|
+
|
|
5
|
+
## 🌟 核心特性
|
|
6
|
+
|
|
7
|
+
1. **全面支持**:支持 Web、Node.js 命令行、Node.js 服务端、VS Code 插件以及 Chrome 扩展等多平台环境的无缝构建与差异化适配。
|
|
8
|
+
|
|
9
|
+
2. **开箱即用**:提供极简的最小配置支持,内置了常用的 TypeScript 编译、样式加载、静态资源处理及 HTML 模板自动注入能力。
|
|
10
|
+
|
|
11
|
+
3. **最佳性能**:内置企业级实践最佳性能配置,支持 Gzip 压缩、Terser 与 CSS 压缩优化、多线程编译(thread-loader)以及智能代码切片。
|
|
12
|
+
|
|
13
|
+
4. **自由扩展**:完美兼容 Webpack 原生属性与丰富的自定义快捷属性,并严格遵循“Webpack 原生属性优先”的合并策略。
|
|
14
|
+
|
|
15
|
+
5. **高度可控**:提供内置的高级钩子函数(configureWebpack),在享受自动化便利的同时保留绝对的控制权。
|
|
16
|
+
|
|
17
|
+
## 📦 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i coda-builder --dev-save
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 🛠 配置接口说明 (CodaUserConfig)
|
|
24
|
+
|
|
25
|
+
| 参数名 | 类型 | 默认值 | 说明 |
|
|
26
|
+
| :--------------- | :------------------------------------------------------------------------------- | :-------------------- | :-------------------------------------------------------------------------------------------- |
|
|
27
|
+
| techRoute | TechRoute | - (必填) | 适配的技术路线 ('typescript' \| 'web') |
|
|
28
|
+
| platformTarget | PlatformTarget | - (必填) | 多平台构建和开发目标 ('nodejs-cli' \| 'node-server' \| 'chrome-ext' \| 'vscode-ext' \| 'web') |
|
|
29
|
+
| mode | BuildMode | - (必填) | Webpack 运行模式 ('production' \| 'development' \| 'analyzer') |
|
|
30
|
+
| entry | WebpackConfiguration['entry'] | - (必填) | 脚本入口配置 |
|
|
31
|
+
| context | WebpackConfiguration['context'] | process.cwd() | 命令执行上下文绝对路径 |
|
|
32
|
+
| output | WebpackConfiguration['output'] | undefined | 构建产物输出配置 |
|
|
33
|
+
| module | WebpackConfiguration['module'] | undefined | 模块匹配与解析规则 (原生优先) |
|
|
34
|
+
| resolve | WebpackConfiguration['resolve'] | undefined | 模块解析配置 (原生优先) |
|
|
35
|
+
| optimization | WebpackConfiguration['optimization'] | undefined | 代码优化与分包配置 |
|
|
36
|
+
| plugins | WebpackConfiguration['plugins'] | undefined | 自定义 Webpack 插件列表 |
|
|
37
|
+
| devServer | DevServerConfiguration | undefined | 开发服务器配置 |
|
|
38
|
+
| cache | WebpackConfiguration['cache'] | undefined | 构建缓存配置 |
|
|
39
|
+
| devtool | WebpackConfiguration['devtool'] | undefined | Source Map 生成方式 |
|
|
40
|
+
| target | WebpackConfiguration['target'] | 自动适配 | 编译目标环境 |
|
|
41
|
+
| watch | WebpackConfiguration['watch'] | undefined | 是否开启文件增量监听 |
|
|
42
|
+
| watchOptions | WebpackConfiguration['watchOptions'] | undefined | 文件监听选项 |
|
|
43
|
+
| externals | WebpackConfiguration['externals'] | 平台内置处理 | 外部依赖处理 |
|
|
44
|
+
| stats | WebpackConfiguration['stats'] | undefined | 构建日志输出控制 |
|
|
45
|
+
| noParse | NonNullable<WebpackConfiguration['module']>['noParse'] | undefined | 不需要解析的第三方大文件正则或数组 |
|
|
46
|
+
| rules | NonNullable<WebpackConfiguration['module']>['rules'] | undefined | 资源加载器规则 (自动映射至 Webpack module.rules) |
|
|
47
|
+
| alias | Record<string, string> | undefined | 模块路径别名(快捷属性,映射至 resolve.alias) |
|
|
48
|
+
| extensions | string[] | ['.ts', '.js'] | 模块解析扩展名列表(快捷属性) |
|
|
49
|
+
| extensionAlias | Record<string, string \| string[]> | undefined | 文件后缀别名映射 |
|
|
50
|
+
| modules | NonNullable<WebpackConfiguration['resolve']>['modules'] | ['node_modules'] | 模块解析查找目录 |
|
|
51
|
+
| mainFields | NonNullable<WebpackConfiguration['resolve']>['mainFields'] | undefined | 依赖包主文件字段 |
|
|
52
|
+
| maxChunks | number | undefined | 限制每个入口生成的最大 Chunk 数量 |
|
|
53
|
+
| splitChunks | WebpackConfiguration['optimization'] extends {splitChunks?: infer S} ? S : never | 智能适配 | 代码切片配置 (继承 Webpack optimization.splitChunks) |
|
|
54
|
+
| minimize | boolean | 生产/分析模式默认开启 | 是否启用代码压缩 minimization |
|
|
55
|
+
| terserOptions | TerserPlugin['options'] | 内置优化配置 | Terser 脚本压缩优化选项 (基于 terser-webpack-plugin) |
|
|
56
|
+
| parallel | number | undefined | 压缩插件启用的 CPU 核心数 (基于 terser-webpack-plugin) |
|
|
57
|
+
| speedMeasure | boolean | false | 是否开启构建打包测速 (基于 speed-measure-webpack-v5-plugin) |
|
|
58
|
+
| thread | boolean | false | 是否开启多线程编译 thread-loader |
|
|
59
|
+
| workerOptions | WorkerOptions | 默认自适应核数 | thread-loader 的自定义 Worker 选项 |
|
|
60
|
+
| html | HtmlWebpackPluginOptions \| boolean | undefined | HTML 模板注入配置 (基于 html-webpack-plugin) |
|
|
61
|
+
| copyRules | CopyRuleItem[] | undefined | 静态资源复制与模板处理规则 |
|
|
62
|
+
| gzip | CompressionPlugin['options'] \| boolean | 生产/分析模式默认开启 | Gzip 压缩配置 (基于 compression-webpack-plugin) |
|
|
63
|
+
| configureWebpack | (config, mode) => WebpackConfiguration \| void | undefined | 高级扩展钩子函数(终极逃生舱) |
|
|
64
|
+
|
|
65
|
+
## 🚀 使用指南
|
|
66
|
+
|
|
67
|
+
在你的业务项目根目录下创建 webpack.config.ts:
|
|
68
|
+
|
|
69
|
+
node服务 配置示例
|
|
70
|
+
|
|
71
|
+
```TypeScript
|
|
72
|
+
import * as path from 'path';
|
|
73
|
+
import type {Configuration} from 'webpack';
|
|
74
|
+
import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
|
|
75
|
+
|
|
76
|
+
const config: CodaUserConfig = {
|
|
77
|
+
platformTarget: 'node-server',
|
|
78
|
+
techRoute: 'typescript',
|
|
79
|
+
mode: 'production',
|
|
80
|
+
entry: './src/main.ts',
|
|
81
|
+
output: {
|
|
82
|
+
filename: 'main.js',
|
|
83
|
+
path: path.resolve(__dirname, 'dist'),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const webpackConfig: Configuration = resolveWebpackConfig(config);
|
|
88
|
+
|
|
89
|
+
export default webpackConfig;
|
|
90
|
+
```
|
|
@@ -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,6 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coda-builder",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"main": "./build/index.js",
|
|
5
|
+
"types": "./build/index.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./build/index.d.ts",
|
|
9
|
+
"require": "./build/index.js",
|
|
10
|
+
"import": "./build/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"webpack": "^5.91.0",
|
|
15
|
+
"webpack-cli": "^5.1.4",
|
|
16
|
+
"webpack-dev-server": "^5.0.4",
|
|
17
|
+
"webpack-node-externals": "^3.0.0",
|
|
18
|
+
"webpackbar": "^7.0.0",
|
|
19
|
+
"webpack-bundle-analyzer": "^4.10.2",
|
|
20
|
+
"html-webpack-plugin": "^5.6.0",
|
|
21
|
+
"css-loader": "^7.1.2",
|
|
22
|
+
"css-minimizer-webpack-plugin": "^7.0.0",
|
|
23
|
+
"mini-css-extract-plugin": "^2.9.0",
|
|
24
|
+
"postcss": "^8.1.1",
|
|
25
|
+
"postcss-loader": "^8.1.1",
|
|
26
|
+
"postcss-preset-env": "^9.6.0",
|
|
27
|
+
"postcss-pxtorem": "^6.1.0",
|
|
28
|
+
"file-loader": "^6.2.0",
|
|
29
|
+
"url-loader": "^4.1.1",
|
|
30
|
+
"style-loader": "^4.0.0",
|
|
31
|
+
"compression-webpack-plugin": "^11.1.0",
|
|
32
|
+
"terser-webpack-plugin": "^5.6.1",
|
|
33
|
+
"speed-measure-webpack-v5-plugin": "^1.5.2",
|
|
34
|
+
"thread-loader": "4.0.2"
|
|
35
|
+
}
|
|
6
36
|
}
|