coda-builder 1.0.8 → 1.2.2

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 CHANGED
@@ -1,281 +1,488 @@
1
1
  # Coda-Builder
2
2
 
3
- `Coda-Builder` 是一个专为 TypeScript 多平台打造的现代化 Webpack 封装与标准化构建工具。旨在以极低的配置开销,统一管理和输出多平台项目(Node CLI、Node Server、VS Code 扩展、Chrome 扩展、Web等)
3
+ [![Version](https://img.shields.io/badge/version-1.2.2-blue.svg)]()
4
+ [![Webpack](https://img.shields.io/badge/webpack-%3E%3D5.91.0-green.svg)]()
5
+ [![TypeScript](https://img.shields.io/badge/typescript-%3E%3D5.5-blue.svg)](https://www.typescriptlang.org/)
6
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D22.0.0-green.svg)](https://nodejs.org/)
7
+ [![Platforms](https://img.shields.io/badge/platforms-web%20%7C%20node%20%7C%20chrome%20%7C%20vscode-orange)]()
8
+ [![npm downloads](https://img.shields.io/npm/dm/coda-builder.svg)](https://www.npmjs.com/package/coda-builder)
9
+ [![License](https://img.shields.io/badge/license-MIT-yellow.svg)]()
4
10
 
5
- ## 🌟 核心特性
11
+ ## 📖 简述
6
12
 
7
- 1. **全面支持**:支持 Web、Node.js 命令行、Node.js 服务端、VS Code 插件以及 Chrome 扩展等多平台环境的无缝构建与差异化适配。
13
+ `Coda-Builder` 是一款基于 TypeScript + Webpack 的企业级构建工具,旨在统一管理多平台项目(WEB、Node、Chrome扩展程序、VS Code扩展程序等),使开发人员享受开箱即用的体验。
8
14
 
9
- 2. **开箱即用**:提供极简的最小配置支持,内置了常用的 TypeScript 编译、样式加载、静态资源处理及 HTML 模板自动注入能力。
15
+ - **核心定位**:Coda-Builder 是一套 TypeScript + Webpack 封装与标准化构建工具引擎。
16
+ - **核心能力**:它深度整合多端差异化适配逻辑,一站式打通从前端 Web、全端主流框架(React 18/19、Vue 2/3)、SDK 库到 Node 命令行、服务端及各类插件扩展(Chrome/VS Code)的全生态构建路径。
17
+ - **达成目标**:旨在化繁为简,让开发者彻底摆脱繁琐的 Webpack 底层配置负担,实现“零配置开箱、企业级性能、绝对化掌控”,全面赋能多平台工程化的高效落地。
10
18
 
11
- 3. **最佳性能**:内置企业级实践最佳性能配置,支持 Gzip 压缩、Terser 与 CSS 压缩优化、多线程编译(thread-loader)以及智能代码切片。
19
+ ## 🌟 核心特性
12
20
 
13
- 4. **自由扩展**:完美兼容 Webpack 原生属性与丰富的自定义快捷属性,并严格遵循“Webpack 原生属性优先”的合并策略。
21
+ 1. **全面支持**:
22
+ - 纵向贯通全场景生态:不仅支持 Web(React/Vue/自研SDK) 应用、更深入打通 Node (Node服务/Node命令工具)应用以及插件类应用( Chrome/VS Code 扩展)等多端环境,实现真正的多平台适配。
23
+
24
+ 2. **开箱即用**:
25
+ - 横向精简开发流:提供极简的最小配置上手体验,底层默认集成 TypeScript 高效编译、多版本框架解析、样式自动提取、静态资源处理及 HTML 模板自动注入,省去繁复的基建搭建。
26
+
27
+ 3. **最佳性能**:
28
+ - 深度赋能构建效能:汇聚企业级最佳实践,内置多线程编译加速(thread-loader)、智能代码切片、双重极致压缩(Terser + CSS)及 Gzip 传输优化,全方位提升打包速度与产物表现。
29
+
30
+ 4. **自由扩展**:
31
+ - 兼顾灵活与规范:既提供丰富的自定义快捷属性以简化日常设置,又完美兼容 Webpack 原生配置,并严格遵循“原生属性优先”的合并策略,从容应对各类复杂定制需求。
32
+
33
+ 5. **高度可控**:
34
+ - 守护底层安全底线:在享受全流程自动化带来极致便利的同时,通过开放内置的高级钩子函数(configureWebpack),赋予开发者随时穿透封装、行使绝对控制权的自由。
35
+
36
+ ## 🛠 配置说明 (CodaUserConfig)
37
+
38
+ | 参数名 | 类型 | 默认值 | 说明 |
39
+ | :----------------- | :------------------------------------------------------------------------------- | :-------------------- | :------------------------------------------------------------- |
40
+ | `techRoute` | TechRoute | - (必填) | 适配的技术路线 ('typescript' \| 'web') |
41
+ | `mode` | BuildMode | - (必填) | Webpack 运行模式 ('production' \| 'development' \| 'analyzer') |
42
+ | `entry` | WebpackConfiguration['entry'] | - (必填) | 脚本入口配置 |
43
+ | `context` | WebpackConfiguration['context'] | process.cwd() | 命令执行上下文绝对路径 |
44
+ | `output` | WebpackConfiguration['output'] | undefined | 构建产物输出配置 |
45
+ | `module` | WebpackConfiguration['module'] | undefined | 模块匹配与解析规则 (原生优先) |
46
+ | `resolve` | WebpackConfiguration['resolve'] | undefined | 模块解析配置 (原生优先) |
47
+ | `optimization` | WebpackConfiguration['optimization'] | undefined | 代码优化与分包配置 |
48
+ | `plugins` | WebpackConfiguration['plugins'] | undefined | 自定义 Webpack 插件列表 |
49
+ | `devServer` | DevServerConfiguration | undefined | 开发服务器配置 |
50
+ | `cache` | WebpackConfiguration['cache'] | undefined | 构建缓存配置 |
51
+ | `devtool` | WebpackConfiguration['devtool'] | undefined | Source Map 生成方式 |
52
+ | `target` | WebpackConfiguration['target'] | 自动适配 | 编译目标环境 |
53
+ | `watch` | WebpackConfiguration['watch'] | undefined | 是否开启文件增量监听 |
54
+ | `watchOptions` | WebpackConfiguration['watchOptions'] | undefined | 文件监听选项 |
55
+ | `externals` | WebpackConfiguration['externals'] | 平台内置处理 | 外部依赖处理 |
56
+ | `stats` | WebpackConfiguration['stats'] | undefined | 构建日志输出控制 |
57
+ | `noParse` | NonNullable<WebpackConfiguration['module']>['noParse'] | undefined | 不需要解析的第三方大文件正则或数组 |
58
+ | `rules` | NonNullable<WebpackConfiguration['module']>['rules'] | undefined | 资源加载器规则 (自动映射至 Webpack module.rules) |
59
+ | `alias` | Record<string, string> | undefined | 模块路径别名(快捷属性,映射至 resolve.alias) |
60
+ | `extensions` | string[] | ['.ts', '.js'] | 模块解析扩展名列表(快捷属性) |
61
+ | `extensionAlias` | Record<string, string \| string[]> | undefined | 文件后缀别名映射 |
62
+ | `modules` | NonNullable<WebpackConfiguration['resolve']>['modules'] | ['node_modules'] | 模块解析查找目录 |
63
+ | `mainFields` | NonNullable<WebpackConfiguration['resolve']>['mainFields'] | undefined | 依赖包主文件字段 |
64
+ | `maxChunks` | number | undefined | 限制每个入口生成的最大 Chunk 数量 |
65
+ | `splitChunks` | WebpackConfiguration['optimization'] extends {splitChunks?: infer S} ? S : never | 智能适配 | 代码切片配置 (继承 Webpack optimization.splitChunks) |
66
+ | `minimize` | boolean | 生产/分析模式默认开启 | 是否启用代码压缩 minimization |
67
+ | `terserOptions` | TerserPlugin['options'] | 内置优化配置 | Terser 脚本压缩优化选项 (基于 terser-webpack-plugin) |
68
+ | `parallel` | number | undefined | 压缩插件启用的 CPU 核心数 (基于 terser-webpack-plugin) |
69
+ | `speedMeasure` | boolean | false | 是否开启构建打包测速 (基于 speed-measure-webpack-v5-plugin) |
70
+ | `thread` | boolean | false | 是否开启多线程编译 thread-loader |
71
+ | `workerOptions` | WorkerOptions | 默认自适应核数 | thread-loader 的自定义 Worker 选项 |
72
+ | `html` | HtmlWebpackPluginOptions \| boolean | undefined | HTML 模板注入配置 (基于 html-webpack-plugin) |
73
+ | `copyRules` | CopyRuleItem[] | undefined | 静态资源复制与模板处理规则 |
74
+ | `gzip` | CompressionPlugin['options'] \| boolean | 生产/分析模式默认开启 | Gzip 压缩配置 (基于 compression-webpack-plugin) |
75
+ | `configureWebpack` | (config, mode) => WebpackConfiguration \| void | undefined | 高级扩展钩子函数(终极逃生舱) |
76
+ | |
14
77
 
15
- 5. **高度可控**:提供内置的高级钩子函数(configureWebpack),在享受自动化便利的同时保留绝对的控制权。
78
+ ## 🚀 使用指南
16
79
 
17
- ## 📦 安装
80
+ 1. 安装coda-builder
18
81
 
19
82
  ```bash
20
83
  npm i coda-builder --dev-save
21
84
  ```
22
85
 
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 | 高级扩展钩子函数(终极逃生舱) |
86
+ 2. 创建配置文件
64
87
 
65
- ## 🚀 使用指南
88
+ - 使用`coda-cli`来自动安装与创建配置文件:
66
89
 
67
- 在你的业务项目根目录下创建 webpack.config.ts:
90
+ ```bash
91
+ coda install builder
92
+ ```
68
93
 
69
- node服务 配置示例
94
+ - 手动创建配置文件
95
+ - 在你的业务项目根目录下创建 webpack.config.js或webpack.config.ts:
70
96
 
71
- ```TypeScript
72
- import * as path from 'path';
73
- import type {Configuration} from 'webpack';
74
- import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
97
+ 3. 增加运行脚本
98
+ 在项目package.json中的scripts中加入以下内容:
75
99
 
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
- };
100
+ ```json
101
+ "scripts": {
102
+ "dev": "cross-env NODE_ENV=development webpack serve --config webpack.config.ts",
103
+ "build:production": "cross-env NODE_ENV=production webpack --config webpack.config.ts",
104
+ "build": "cross-env NODE_ENV=development webpack --config webpack.config.ts",
105
+ }
106
+ ```
86
107
 
87
- const webpackConfig: Configuration = resolveWebpackConfig(config);
108
+ 如果使用coda-builder构建时需要产出.d.ts文件:
88
109
 
89
- export default webpackConfig;
110
+ - 需要在package.json build脚本最末尾加"&& tsc --emitDeclarationOnly"
111
+ ```json
112
+ "scripts": {
113
+ "dev": "cross-env NODE_ENV=development webpack serve --config webpack.config.ts",
114
+ "build:production": "cross-env NODE_ENV=production webpack --config webpack.config.ts && tsc --emitDeclarationOnly",
115
+ "build": "cross-env NODE_ENV=development webpack --config webpack.config.ts && tsc --emitDeclarationOnly",
116
+ }
117
+ ```
118
+ - 在tsconfig.json中开启"declaration"和"emitDeclarationOnly"
119
+ ```json
120
+ "compilerOptions": {
121
+ "target": "es2022",
122
+ "moduleResolution": "bundler", //编译为ESModule
123
+ "declaration": true, //开启生成 .d.ts 文件
124
+ "emitDeclarationOnly": true, //只生成.d.ts
125
+ "strict": true,
126
+ "esModuleInterop": true,
127
+ "skipLibCheck": true,
128
+ "rootDir": "./src",
129
+ "outDir": "./dist"
130
+ },
131
+ ```
132
+
133
+ 【提示】coda-builder只依赖webpack5 相关的工具,业务项目需要的依赖需要自行下载,若运行coda-builder报错,则检查相关loader/plugin是否在项目中安装。
134
+
135
+ coda-builder默认的依赖包如下:
136
+
137
+ ```json
138
+ "dependencies": {
139
+ "webpack": "^>=5.91.0",
140
+ "webpack-cli": "^5.1.4",
141
+ "webpack-dev-server": "^5.0.4",
142
+ "webpack-node-externals": "^3.0.0",
143
+ "webpackbar": "^7.0.0",
144
+ "webpack-bundle-analyzer": "^4.10.2",
145
+ "html-webpack-plugin": "^5.6.0",
146
+ "css-loader": "^7.1.2",
147
+ "css-minimizer-webpack-plugin": "^7.0.0",
148
+ "mini-css-extract-plugin": "^2.9.0",
149
+ "postcss": "^8.1.1",
150
+ "postcss-loader": "^8.1.1",
151
+ "postcss-preset-env": "^9.6.0",
152
+ "postcss-pxtorem": "^6.1.0",
153
+ "file-loader": "^6.2.0",
154
+ "url-loader": "^4.1.1",
155
+ "style-loader": "^4.0.0",
156
+ "compression-webpack-plugin": "^11.1.0",
157
+ "terser-webpack-plugin": "^5.6.1",
158
+ "speed-measure-webpack-v5-plugin": "^1.5.2",
159
+ "thread-loader": "4.0.2"
160
+ }
90
161
  ```
91
162
 
92
- chrome插件 配置示例
93
-
94
- ```TypeScript
95
- import * as path from 'path';
96
- import type {Configuration} from 'webpack';
97
- import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
98
-
99
- const config: CodaUserConfig = {
100
- platformTarget: 'chrome-ext',
101
- techRoute: 'web',
102
- entry: {
103
- background: './src/background.ts',
104
- sidepanel: './src/sidepanel.ts',
105
- },
106
- mode: 'production',
107
- devtool: false, //一定要关闭
108
- optimization: {
109
- runtimeChunk: false, //一定要关闭
110
- splitChunks: false, //一定要关闭
111
- },
112
- output: {
113
- path: path.resolve(__dirname, 'dist'),
114
- },
115
- alias: {
116
- 'chat-shared-ui': path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources'),
117
- },
118
- extensions: ['.ts'],
119
- copyRules: [
120
- {
121
- type: 'single',
122
- from: path.resolve(__dirname, 'manifest.json'),
123
- to: 'manifest.json',
124
- },
125
- {
126
- type: 'template',
127
- from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/chat.html'),
128
- to: 'sidepanel.html',
129
- data: {
130
- '{{styleUri}}': 'main.css',
131
- '{{scriptUri}}': 'sidepanel.js',
132
- },
133
- },
134
- {
135
- type: 'single',
136
- from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/main.css'),
137
- to: 'main.css',
163
+ ## ❓FAQ
164
+
165
+ 1. Q: 如何为Chrome扩展程序应用增加coda-builder的配置
166
+
167
+ - 在tsconfig.ts中配置必须指定 "types": ["chrome"]
168
+
169
+ ```json
170
+ {
171
+ "compilerOptions": {
172
+ "rootDir": "./src",
173
+ "outDir": "./dist",
174
+ "types": ["chrome"]
138
175
  },
139
- ],
140
- };
176
+ "include": ["src/**/*"]
177
+ }
178
+ ```
141
179
 
142
- const webpackConfig: Configuration = resolveWebpackConfig(config);
180
+ - 在webpack.config.ts中配置
143
181
 
144
- export default webpackConfig;
145
- ```
182
+ ```typescript
183
+ import * as path from 'path';
184
+ import type {Configuration} from 'webpack';
185
+ import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
146
186
 
147
- vscode插件 配置示例
148
-
149
- ```TypeScript
150
- import * as path from 'path';
151
- import type {Configuration} from 'webpack';
152
- import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
153
-
154
- const config: CodaUserConfig = {
155
- techRoute: 'typescript',
156
- platformTarget: 'vscode-ext',
157
- entry: './src/extension.ts',
158
- mode: 'production',
159
- output: {
160
- path: path.resolve(__dirname, 'dist'),
161
- filename: 'extension.js',//vscode专属脚本名称
162
- libraryTarget: 'commonjs',//一定要设置成commonjs
163
- },
164
- alias: {
165
- 'chat-shared-ui': path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources'),
166
- },
167
- copyRules: [
168
- {
169
- type: 'single',
170
- from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/chat.html'),
171
- to: 'main.html',
187
+ const config: CodaUserConfig = {
188
+ techRoute: 'chrome-ext', //选择chrome扩展程序类型
189
+ entry: {
190
+ background: './src/background.ts', //有service后台服务,则指定。名称要和manifest.json中的配置对应
191
+ sidepanel: './src/sidepanel.ts', //名称要和manifest.json中的配置对应
172
192
  },
173
- {
174
- type: 'single',
175
- from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/main.css'),
176
- to: 'main.css',
193
+ mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
194
+ devtool: false, //一定要关闭
195
+ optimization: {
196
+ runtimeChunk: false, //一定要关闭
197
+ splitChunks: false, //一定要关闭
177
198
  },
178
- {
179
- type: 'single',
180
- from: path.resolve(__dirname, 'resources', 'main.js'),
181
- to: 'main.js',
199
+ output: {
200
+ path: path.resolve(__dirname, 'dist'),
182
201
  },
183
- {
184
- type: 'single',
185
- from: path.resolve(__dirname, 'resources', 'icon.svg'),
186
- to: 'icon.svg',
202
+ alias: {
203
+ 'chat-shared-ui': path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources'), //此处根据实际页面UI静态资源路径填写
187
204
  },
188
- ],
189
- };
190
-
191
- const webpackConfig: Configuration = resolveWebpackConfig(config);
205
+ extensions: ['.ts'],
206
+ copyRules: [
207
+ {
208
+ type: 'single',
209
+ from: path.resolve(__dirname, 'manifest.json'),
210
+ to: 'manifest.json',
211
+ },
212
+ {
213
+ type: 'template',
214
+ from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/chat.html'),
215
+ to: 'sidepanel.html',
216
+ data: {
217
+ '{{styleUri}}': 'main.css',
218
+ '{{scriptUri}}': 'sidepanel.js',
219
+ },
220
+ },
221
+ {
222
+ type: 'single',
223
+ from: path.resolve(__dirname, '../../coda-ui/chat-shared-ui/resources/main.css'),
224
+ to: 'main.css',
225
+ },
226
+ ],
227
+ };
192
228
 
193
- export default webpackConfig;
229
+ const webpackConfig: Configuration = resolveWebpackConfig(config);
194
230
 
195
- ```
231
+ export default webpackConfig;
232
+ ```
196
233
 
197
- 命令行工具 配置示例
234
+ 2. Q: 如何为node命令工具配置coda-builder的配置
198
235
 
199
- ```TypeScript
200
- import * as path from 'path';
201
- import * as fs from 'fs';
202
- import type {Configuration} from 'webpack';
203
- import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
236
+ - 在tsconfig.ts中配置必须指定 "types": ["node"]
237
+ ```json
238
+ {
239
+ "compilerOptions": {
240
+ "types": ["node"],
241
+ "paths": {
242
+ "@/*": ["./src/*"]
243
+ },
244
+ "module": "nodenext",
245
+ "moduleResolution": "nodenext"
246
+ },
247
+ "include": ["src/**/*"]
248
+ }
249
+ ```
250
+ - 在webpack.config.ts中配置
251
+
252
+ ```typescript
253
+ import * as path from 'path';
254
+ import * as fs from 'fs';
255
+ import type {Configuration} from 'webpack';
256
+ import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
257
+
258
+ function getEntries(srcDir: string) {
259
+ let entries: Record<string, string> = {};
260
+
261
+ function scan(dir: string) {
262
+ const files = fs.readdirSync(dir, {withFileTypes: true});
263
+ files.forEach(file => {
264
+ const fullPath = path.join(dir, file.name);
265
+ if (file.isDirectory()) {
266
+ if (file.name !== 'tmpl' && file.name !== 'templates') {
267
+ scan(fullPath);
268
+ }
269
+ } else if (file.name === 'index.ts' || file.name === 'index.js') {
270
+ const relativePath = path.relative(srcDir, fullPath);
271
+ const entryKey = relativePath.replace(/\\/g, '/').replace(/\.tsx?$/, '');
272
+ entries[entryKey] = fullPath;
273
+ }
274
+ });
275
+ }
204
276
 
205
- function getEntries(srcDir: string) {
206
- let entries: Record<string, string> = {};
277
+ scan(srcDir);
278
+ return entries;
279
+ }
207
280
 
208
- function scan(dir: string) {
209
- const files = fs.readdirSync(dir, {withFileTypes: true});
210
- files.forEach(file => {
211
- const fullPath = path.join(dir, file.name);
212
- if (file.isDirectory()) {
213
- if (file.name !== 'tmpl' && file.name !== 'templates') {
214
- scan(fullPath);
215
- }
216
- } else if (file.name === 'index.ts' || file.name === 'index.js') {
217
- const relativePath = path.relative(srcDir, fullPath);
218
- const entryKey = relativePath.replace(/\\/g, '/').replace(/\.tsx?$/, '');
219
- entries[entryKey] = fullPath;
220
- }
221
- });
281
+ const srcPath = path.resolve(__dirname, 'src');
282
+
283
+ const config: CodaUserConfig = {
284
+ techRoute: 'node-cli', //选择node命令行类型
285
+ entry: getEntries(srcPath), //多入口命令使用函数获取入口文件,单入口命令直接写入口文件路径
286
+ mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
287
+ devtool: process.env.NODE_ENV === 'development' ? 'source-map' : 'cheap-module-source-map',
288
+ gzip: false,
289
+ output: {
290
+ path: path.resolve(__dirname, 'dist'),
291
+ clean: false,
292
+ },
293
+ maxChunks: 1, //一定要设置成1,否则命令文件会被拆分导致无法执行
294
+ alias: {
295
+ '@': path.resolve(__dirname, 'src'),
296
+ },
297
+ extensionAlias: {
298
+ '.js': ['.ts', '.js'], //一定要设置这两个个后缀映射
299
+ '.ts': ['.ts', '.js'],
300
+ },
301
+ copyRules: [
302
+ {
303
+ type: 'single',
304
+ from: path.resolve(__dirname, 'package.json'),
305
+ to: 'package.json',
306
+ },
307
+ {
308
+ type: 'single',
309
+ from: path.resolve(__dirname, 'README.md'),
310
+ to: 'README.md',
311
+ },
312
+ {
313
+ type: 'directory',
314
+ from: path.resolve(__dirname, 'src', 'config'), //非脚本类文件或静态资源要复制到dist
315
+ to: 'config',
316
+ },
317
+ ],
318
+ };
319
+
320
+ const webpackConfig: Configuration = resolveWebpackConfig(config);
321
+
322
+ export default webpackConfig;
323
+ ```
324
+
325
+ 3. Q: 如何为node服务配置coda-builder的配置
326
+
327
+ - 在tsconfig.ts中配置必须指定 "types": ["node"]
328
+
329
+ ```json
330
+ {
331
+ "compilerOptions": {
332
+ "rootDir": "./",
333
+ "outDir": "./dist",
334
+ "module": "NodeNext",
335
+ "moduleResolution": "NodeNext",
336
+ "sourceMap": true,
337
+ "types": ["node"],
338
+ "incremental": true,
339
+ "strictNullChecks": false,
340
+ "noImplicitAny": false,
341
+ "strictBindCallApply": false,
342
+ "forceConsistentCasingInFileNames": false,
343
+ "noFallthroughCasesInSwitch": false,
344
+ "experimentalDecorators": true,
345
+ "emitDecoratorMetadata": true
346
+ },
347
+ "include": ["src/**/*"]
222
348
  }
349
+ ```
223
350
 
224
- scan(srcDir);
225
- return entries;
226
- }
351
+ - 在webpack.config.ts中配置
352
+
353
+ ```typescript
354
+ import * as path from 'path';
355
+ import type {Configuration} from 'webpack';
356
+ import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
227
357
 
228
- const srcPath = path.resolve(__dirname, 'src');
229
-
230
- const config: CodaUserConfig = {
231
- techRoute: 'typescript',
232
- platformTarget: 'nodejs-cli',
233
- entry: getEntries(srcPath),
234
- mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
235
- devtool: process.env.NODE_ENV === 'development' ? 'source-map' : 'cheap-module-source-map',
236
- gzip: false,
237
- output: {
238
- path: path.resolve(__dirname, 'dist'),
239
- clean: false,
240
- },
241
- maxChunks: 1,
242
- alias: {
243
- '@': path.resolve(__dirname, 'src'),
244
- },
245
- extensionAlias: {
246
- '.js': ['.ts', '.js'],
247
- '.ts': ['.ts', '.js'],
248
- },//命令行工具一定要配置这个后缀映射关系
249
- copyRules: [
250
- {
251
- type: 'single',
252
- from: path.resolve(__dirname, 'package.json'),
253
- to: 'package.json',
358
+ const config: CodaUserConfig = {
359
+ techRoute: 'node-server', //选择node服务类型
360
+ entry: './src/main.ts',
361
+ output: {
362
+ filename: 'main.js',
363
+ path: path.resolve(__dirname, 'dist'),
364
+ },
365
+ mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
366
+ gzip: false,
367
+ copyRules: [
368
+ {
369
+ type: 'single',
370
+ from: path.resolve(__dirname, 'package.json'),
371
+ to: 'package.json',
372
+ },
373
+ {
374
+ type: 'single',
375
+ from: path.resolve(__dirname, 'README.md'),
376
+ to: 'README.md',
377
+ },
378
+ {type: 'single', from: path.resolve(__dirname, '.env'), to: '.env'},
379
+ ],
380
+ };
381
+
382
+ const webpackConfig: Configuration = resolveWebpackConfig(config);
383
+
384
+ export default webpackConfig;
385
+ ```
386
+
387
+ 4. Q: 如何为SDK应用增加coda-builder的配置
388
+
389
+ - 在tsconfig.ts中配置,"moduleResolution": "bundler", "declaration": true
390
+
391
+ ```json
392
+ {
393
+ "compilerOptions": {
394
+ "target": "es2022",
395
+ "moduleResolution": "bundler", //编译为ESModule
396
+ "declaration": true, //开启生成 .d.ts 文件
397
+ "emitDeclarationOnly": true, //只生成.d.ts
398
+ "strict": true,
399
+ "esModuleInterop": true,
400
+ "skipLibCheck": true,
401
+ "rootDir": "./src",
402
+ "outDir": "./dist"
254
403
  },
255
- {
256
- type: 'single',
257
- from: path.resolve(__dirname, 'README.md'),
258
- to: 'README.md',
404
+ "include": ["src/**/*"]
405
+ }
406
+ ```
407
+
408
+ - 在webpack.config.ts中配置
409
+
410
+ ```typescript
411
+ import * as path from 'path';
412
+ import type {Configuration} from 'webpack';
413
+ import {resolveWebpackConfig, CodaUserConfig} from 'coda-builder';
414
+
415
+ const config: CodaUserConfig = {
416
+ techRoute: 'sdk', // 选择sdk类型
417
+ entry: './src/index.ts',
418
+ output: {
419
+ filename: 'index.js',
420
+ path: path.resolve(__dirname, 'dist'),
421
+ library: {
422
+ type: 'module', // 开启ES Module 格式
423
+ },
259
424
  },
260
- {
261
- type: 'directory',
262
- from: path.resolve(__dirname, 'src', 'config'),
263
- to: 'config',
425
+ mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
426
+ extensions: ['.ts', '.css'],
427
+ optimization: {
428
+ //关闭代码切片
429
+ splitChunks: false,
430
+ runtimeChunk: false,
264
431
  },
265
- {
266
- type: 'directory',
267
- from: path.resolve(__dirname, 'src', 'service'),
268
- to: 'service',
432
+ gzip: false,
433
+ module: {
434
+ rules: [
435
+ {
436
+ test: /\.m?js$/,
437
+ resolve: {
438
+ fullySpecified: false, // 允许省略文件后缀并兼容旧版模块导入
439
+ },
440
+ },
441
+ ],
269
442
  },
270
- {
271
- type: 'directory',
272
- from: path.resolve(__dirname, 'templates'),
273
- to: 'templates',
443
+ copyRules: [
444
+ {
445
+ type: 'single',
446
+ from: path.resolve(__dirname, 'package.json'),
447
+ to: 'package.json',
448
+ },
449
+ {
450
+ type: 'single',
451
+ from: path.resolve(__dirname, 'README.md'),
452
+ to: 'README.md',
453
+ },
454
+ ],
455
+ configureWebpack: (webpackConfig: Configuration) => {
456
+ // 1. 开启 outputModule 兼容 ESM
457
+ webpackConfig.experiments = {
458
+ ...(webpackConfig.experiments || {}),
459
+ outputModule: true,
460
+ };
461
+
462
+ // 2. 覆盖 CSS Rule:让生产环境也使用 style-loader,将样式直接打包进 JS 内联注入
463
+ if (webpackConfig.module && webpackConfig.module.rules) {
464
+ webpackConfig.module.rules.forEach((rule: any) => {
465
+ if (rule.test && rule.test.toString().includes('css')) {
466
+ rule.use = [
467
+ 'style-loader',
468
+ {
469
+ loader: 'css-loader',
470
+ options: {
471
+ sourceMap: true,
472
+ importLoaders: 1,
473
+ },
474
+ },
475
+ 'postcss-loader',
476
+ ];
477
+ }
478
+ });
479
+ }
480
+
481
+ return webpackConfig;
274
482
  },
275
- ],
276
- };
483
+ };
277
484
 
278
- const webpackConfig: Configuration = resolveWebpackConfig(config);
485
+ const webpackConfig: Configuration = resolveWebpackConfig(config);
279
486
 
280
- export default webpackConfig;
281
- ```
487
+ export default webpackConfig;
488
+ ```