@esmx/rspack 3.0.0-rc.10
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 +29 -0
- package/dist/app.d.ts +160 -0
- package/dist/app.mjs +130 -0
- package/dist/build-target.d.ts +8 -0
- package/dist/build-target.mjs +0 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.mjs +142 -0
- package/dist/html-app.d.ts +299 -0
- package/dist/html-app.mjs +214 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +7 -0
- package/dist/loader.d.ts +30 -0
- package/dist/loader.mjs +33 -0
- package/dist/pack.d.ts +2 -0
- package/dist/pack.mjs +69 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.mjs +1 -0
- package/dist/utils/rsbuild.d.ts +12 -0
- package/dist/utils/rsbuild.mjs +97 -0
- package/package.json +108 -0
- package/src/app.ts +319 -0
- package/src/build-target.ts +8 -0
- package/src/config.ts +171 -0
- package/src/html-app.ts +560 -0
- package/src/index.ts +12 -0
- package/src/loader.ts +34 -0
- package/src/pack.ts +79 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/rsbuild.ts +105 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import type { Esmx } from '@esmx/core';
|
|
2
|
+
import { type SwcLoaderOptions } from '@rspack/core';
|
|
3
|
+
import { type RspackAppOptions } from './app';
|
|
4
|
+
import type { BuildTarget } from './build-target';
|
|
5
|
+
import { RSPACK_LOADER } from './loader';
|
|
6
|
+
/**
|
|
7
|
+
* Rspack HTML 应用配置选项接口
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // entry.node.ts
|
|
12
|
+
* export default {
|
|
13
|
+
* async devApp(esmx) {
|
|
14
|
+
* return import('@esmx/rspack').then((m) =>
|
|
15
|
+
* m.createRspackHtmlApp(esmx, {
|
|
16
|
+
* // 将 CSS 输出到独立的 CSS 文件中
|
|
17
|
+
* css: 'css',
|
|
18
|
+
* // 自定义 loader
|
|
19
|
+
* loaders: {
|
|
20
|
+
* styleLoader: 'vue-style-loader'
|
|
21
|
+
* },
|
|
22
|
+
* // 配置 CSS 相关 loader
|
|
23
|
+
* styleLoader: {
|
|
24
|
+
* injectType: 'singletonStyleTag'
|
|
25
|
+
* },
|
|
26
|
+
* cssLoader: {
|
|
27
|
+
* modules: true
|
|
28
|
+
* },
|
|
29
|
+
* // 配置构建目标
|
|
30
|
+
* target: {
|
|
31
|
+
* web: ['chrome>=87'],
|
|
32
|
+
* node: ['node>=16']
|
|
33
|
+
* },
|
|
34
|
+
* // 定义全局常量
|
|
35
|
+
* definePlugin: {
|
|
36
|
+
* 'process.env.APP_ENV': JSON.stringify('production')
|
|
37
|
+
* }
|
|
38
|
+
* })
|
|
39
|
+
* );
|
|
40
|
+
* }
|
|
41
|
+
* };
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export interface RspackHtmlAppOptions extends RspackAppOptions {
|
|
45
|
+
/**
|
|
46
|
+
* CSS 输出模式配置
|
|
47
|
+
*
|
|
48
|
+
* @default 根据环境自动选择:
|
|
49
|
+
* - 生产环境: 'css',将CSS输出到独立文件中,有利于缓存和并行加载
|
|
50
|
+
* - 开发环境: 'js',将CSS打包到JS中以支持热更新(HMR),实现样式的即时更新
|
|
51
|
+
*
|
|
52
|
+
* - 'css': 将 CSS 输出到独立的 CSS 文件中
|
|
53
|
+
* - 'js': 将 CSS 打包到 JS 文件中,运行时动态插入样式
|
|
54
|
+
* - false: 关闭默认的 CSS 处理配置,需要手动配置 loader 规则
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* // 使用环境默认配置
|
|
59
|
+
* css: undefined
|
|
60
|
+
*
|
|
61
|
+
* // 强制输出到独立的 CSS 文件
|
|
62
|
+
* css: 'css'
|
|
63
|
+
*
|
|
64
|
+
* // 强制打包到 JS 中
|
|
65
|
+
* css: 'js'
|
|
66
|
+
*
|
|
67
|
+
* // 自定义 CSS 处理
|
|
68
|
+
* css: false
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
css?: 'css' | 'js' | false;
|
|
72
|
+
/**
|
|
73
|
+
* 自定义 loader 配置
|
|
74
|
+
*
|
|
75
|
+
* 允许替换默认的 loader 实现,可用于切换到特定框架的 loader
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // 使用 Vue 的 style-loader
|
|
80
|
+
* loaders: {
|
|
81
|
+
* styleLoader: 'vue-style-loader'
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
loaders?: Partial<Record<keyof typeof RSPACK_LOADER, string>>;
|
|
86
|
+
/**
|
|
87
|
+
* style-loader 配置项
|
|
88
|
+
*
|
|
89
|
+
* 用于配置样式注入方式,完整选项参考:
|
|
90
|
+
* https://github.com/webpack-contrib/style-loader
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* styleLoader: {
|
|
95
|
+
* injectType: 'singletonStyleTag',
|
|
96
|
+
* attributes: { id: 'app-styles' }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
styleLoader?: Record<string, any>;
|
|
101
|
+
/**
|
|
102
|
+
* css-loader 配置项
|
|
103
|
+
*
|
|
104
|
+
* 用于配置 CSS 模块化、URL 解析等,完整选项参考:
|
|
105
|
+
* https://github.com/webpack-contrib/css-loader
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* cssLoader: {
|
|
110
|
+
* modules: true,
|
|
111
|
+
* url: false
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
cssLoader?: Record<string, any>;
|
|
116
|
+
/**
|
|
117
|
+
* less-loader 配置项
|
|
118
|
+
*
|
|
119
|
+
* 用于配置 Less 编译选项,完整选项参考:
|
|
120
|
+
* https://github.com/webpack-contrib/less-loader
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* lessLoader: {
|
|
125
|
+
* lessOptions: {
|
|
126
|
+
* javascriptEnabled: true,
|
|
127
|
+
* modifyVars: { '@primary-color': '#1DA57A' }
|
|
128
|
+
* }
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
lessLoader?: Record<string, any>;
|
|
133
|
+
/**
|
|
134
|
+
* style-resources-loader 配置项
|
|
135
|
+
*
|
|
136
|
+
* 用于自动注入全局的样式资源,完整选项参考:
|
|
137
|
+
* https://github.com/yenshih/style-resources-loader
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* styleResourcesLoader: {
|
|
142
|
+
* patterns: [
|
|
143
|
+
* './src/styles/variables.less',
|
|
144
|
+
* './src/styles/mixins.less'
|
|
145
|
+
* ]
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
styleResourcesLoader?: Record<string, any>;
|
|
150
|
+
/**
|
|
151
|
+
* SWC loader 配置项
|
|
152
|
+
*
|
|
153
|
+
* 用于配置 TypeScript/JavaScript 编译选项,完整选项参考:
|
|
154
|
+
* https://rspack.dev/guide/features/builtin-swc-loader
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* swcLoader: {
|
|
159
|
+
* jsc: {
|
|
160
|
+
* parser: {
|
|
161
|
+
* syntax: 'typescript',
|
|
162
|
+
* decorators: true
|
|
163
|
+
* },
|
|
164
|
+
* transform: {
|
|
165
|
+
* legacyDecorator: true
|
|
166
|
+
* }
|
|
167
|
+
* }
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
swcLoader?: SwcLoaderOptions;
|
|
172
|
+
/**
|
|
173
|
+
* DefinePlugin 配置项
|
|
174
|
+
*
|
|
175
|
+
* 用于定义编译时的全局常量,支持针对不同构建目标设置不同的值
|
|
176
|
+
* 完整说明参考: https://rspack.dev/plugins/webpack/define-plugin
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* // 统一的值
|
|
181
|
+
* definePlugin: {
|
|
182
|
+
* 'process.env.APP_ENV': JSON.stringify('production')
|
|
183
|
+
* }
|
|
184
|
+
*
|
|
185
|
+
* // 针对不同构建目标的值
|
|
186
|
+
* definePlugin: {
|
|
187
|
+
* 'process.env.IS_SERVER': {
|
|
188
|
+
* server: 'true',
|
|
189
|
+
* client: 'false'
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
definePlugin?: Record<string, string | Partial<Record<BuildTarget, string>>>;
|
|
195
|
+
/**
|
|
196
|
+
* 构建目标配置
|
|
197
|
+
*
|
|
198
|
+
* 用于设置代码的目标运行环境,影响代码的编译降级和 polyfill 注入
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* target: {
|
|
203
|
+
* // 浏览器构建目标
|
|
204
|
+
* web: ['chrome>=87', 'firefox>=78', 'safari>=14'],
|
|
205
|
+
* // Node.js 构建目标
|
|
206
|
+
* node: ['node>=16']
|
|
207
|
+
* }
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
target?: {
|
|
211
|
+
/**
|
|
212
|
+
* 浏览器构建目标
|
|
213
|
+
*
|
|
214
|
+
* @default ['chrome>=87', 'edge>=88', 'firefox>=78', 'safari>=14']
|
|
215
|
+
*/
|
|
216
|
+
web?: string[];
|
|
217
|
+
/**
|
|
218
|
+
* Node.js 构建目标
|
|
219
|
+
*
|
|
220
|
+
* @default ['node>=22.6']
|
|
221
|
+
*/
|
|
222
|
+
node?: string[];
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* 创建 Rspack HTML 应用实例。
|
|
227
|
+
*
|
|
228
|
+
* 该函数提供了完整的 Web 应用构建配置,支持以下资源类型的处理:
|
|
229
|
+
* - TypeScript/JavaScript
|
|
230
|
+
* - Web Worker
|
|
231
|
+
* - JSON
|
|
232
|
+
* - CSS/Less
|
|
233
|
+
* - 视频/图片
|
|
234
|
+
* - 字体文件
|
|
235
|
+
*
|
|
236
|
+
* @param esmx - Esmx 框架实例
|
|
237
|
+
* @param options - Rspack HTML 应用配置选项
|
|
238
|
+
* @returns 返回应用实例,包含中间件、渲染函数和构建函数
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* // 开发环境配置
|
|
243
|
+
* // entry.node.ts
|
|
244
|
+
* export default {
|
|
245
|
+
* async devApp(esmx) {
|
|
246
|
+
* return import('@esmx/rspack').then((m) =>
|
|
247
|
+
* m.createRspackHtmlApp(esmx, {
|
|
248
|
+
* // 配置 CSS 输出模式
|
|
249
|
+
* css: 'css',
|
|
250
|
+
* // 配置 TypeScript 编译选项
|
|
251
|
+
* swcLoader: {
|
|
252
|
+
* jsc: {
|
|
253
|
+
* parser: {
|
|
254
|
+
* syntax: 'typescript',
|
|
255
|
+
* decorators: true
|
|
256
|
+
* }
|
|
257
|
+
* }
|
|
258
|
+
* },
|
|
259
|
+
* // 配置构建目标
|
|
260
|
+
* target: {
|
|
261
|
+
* web: ['chrome>=87'],
|
|
262
|
+
* node: ['node>=16']
|
|
263
|
+
* },
|
|
264
|
+
* // 自定义 Rspack 配置
|
|
265
|
+
* config({ config }) {
|
|
266
|
+
* // 添加自定义 loader
|
|
267
|
+
* config.module.rules.push({
|
|
268
|
+
* test: /\.vue$/,
|
|
269
|
+
* loader: 'vue-loader'
|
|
270
|
+
* });
|
|
271
|
+
* }
|
|
272
|
+
* })
|
|
273
|
+
* );
|
|
274
|
+
* }
|
|
275
|
+
* };
|
|
276
|
+
*
|
|
277
|
+
* // 生产环境配置
|
|
278
|
+
* // entry.node.ts
|
|
279
|
+
* export default {
|
|
280
|
+
* async buildApp(esmx) {
|
|
281
|
+
* return import('@esmx/rspack').then((m) =>
|
|
282
|
+
* m.createRspackHtmlApp(esmx, {
|
|
283
|
+
* // 启用代码压缩
|
|
284
|
+
* minimize: true,
|
|
285
|
+
* // 配置全局常量
|
|
286
|
+
* definePlugin: {
|
|
287
|
+
* 'process.env.NODE_ENV': JSON.stringify('production'),
|
|
288
|
+
* 'process.env.IS_SERVER': {
|
|
289
|
+
* server: 'true',
|
|
290
|
+
* client: 'false'
|
|
291
|
+
* }
|
|
292
|
+
* }
|
|
293
|
+
* })
|
|
294
|
+
* );
|
|
295
|
+
* }
|
|
296
|
+
* };
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
export declare function createRspackHtmlApp(esmx: Esmx, options?: RspackHtmlAppOptions): Promise<import("@esmx/core").App>;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import {
|
|
2
|
+
rspack
|
|
3
|
+
} from "@rspack/core";
|
|
4
|
+
import NodePolyfillPlugin from "node-polyfill-webpack-plugin";
|
|
5
|
+
import {
|
|
6
|
+
createRspackApp
|
|
7
|
+
} from "./app.mjs";
|
|
8
|
+
import { RSPACK_LOADER } from "./loader.mjs";
|
|
9
|
+
export async function createRspackHtmlApp(esmx, options) {
|
|
10
|
+
options = {
|
|
11
|
+
...options,
|
|
12
|
+
target: {
|
|
13
|
+
web: ["chrome>=87", "edge>=88", "firefox>=78", "safari>=14"],
|
|
14
|
+
node: ["node>=22.6"],
|
|
15
|
+
...options?.target
|
|
16
|
+
},
|
|
17
|
+
css: options?.css ? options.css : esmx.isProd ? "css" : "js"
|
|
18
|
+
};
|
|
19
|
+
return createRspackApp(esmx, {
|
|
20
|
+
...options,
|
|
21
|
+
config(context) {
|
|
22
|
+
const { config, buildTarget } = context;
|
|
23
|
+
config.stats = "errors-warnings";
|
|
24
|
+
config.module = {
|
|
25
|
+
...config.module,
|
|
26
|
+
rules: [
|
|
27
|
+
...config.module?.rules ?? [],
|
|
28
|
+
{
|
|
29
|
+
test: /\.(jpe?g|png|gif|bmp|webp|svg)$/i,
|
|
30
|
+
type: "asset/resource",
|
|
31
|
+
generator: {
|
|
32
|
+
filename: filename(esmx, "images")
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/i,
|
|
37
|
+
type: "asset/resource",
|
|
38
|
+
generator: {
|
|
39
|
+
filename: filename(esmx, "media")
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
test: /\.(woff|woff2|eot|ttf|otf)(\?.*)?$/i,
|
|
44
|
+
type: "asset/resource",
|
|
45
|
+
generator: {
|
|
46
|
+
filename: filename(esmx, "fonts")
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
test: /\.json$/i,
|
|
51
|
+
type: "json"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
test: /\.worker\.(c|m)?(t|j)s$/i,
|
|
55
|
+
loader: options.loaders?.workerRspackLoader ?? RSPACK_LOADER.workerRspackLoader,
|
|
56
|
+
options: {
|
|
57
|
+
esModule: false,
|
|
58
|
+
filename: `${esmx.name}/workers/[name].[contenthash]${esmx.isProd ? ".final" : ""}.js`
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
test: /\.(ts|mts)$/i,
|
|
63
|
+
loader: options.loaders?.builtinSwcLoader ?? RSPACK_LOADER.builtinSwcLoader,
|
|
64
|
+
options: {
|
|
65
|
+
env: {
|
|
66
|
+
targets: buildTarget === "client" ? options?.target?.web : options?.target?.node,
|
|
67
|
+
...options?.swcLoader?.env
|
|
68
|
+
},
|
|
69
|
+
jsc: {
|
|
70
|
+
parser: {
|
|
71
|
+
syntax: "typescript",
|
|
72
|
+
...options?.swcLoader?.jsc?.parser
|
|
73
|
+
},
|
|
74
|
+
...options?.swcLoader?.jsc
|
|
75
|
+
},
|
|
76
|
+
...options?.swcLoader
|
|
77
|
+
},
|
|
78
|
+
type: "javascript/auto"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
};
|
|
82
|
+
config.optimization = {
|
|
83
|
+
...config.optimization,
|
|
84
|
+
minimizer: [
|
|
85
|
+
new rspack.SwcJsMinimizerRspackPlugin({
|
|
86
|
+
minimizerOptions: {
|
|
87
|
+
format: {
|
|
88
|
+
comments: false
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
new rspack.LightningCssMinimizerRspackPlugin({
|
|
93
|
+
minimizerOptions: {
|
|
94
|
+
targets: options.target?.web,
|
|
95
|
+
errorRecovery: false
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
config.plugins = [
|
|
101
|
+
new NodePolyfillPlugin(),
|
|
102
|
+
...config.plugins ?? []
|
|
103
|
+
];
|
|
104
|
+
config.devtool = false;
|
|
105
|
+
config.cache = false;
|
|
106
|
+
if (options.definePlugin) {
|
|
107
|
+
const defineOptions = {};
|
|
108
|
+
Object.entries(options.definePlugin).forEach(
|
|
109
|
+
([name, value]) => {
|
|
110
|
+
const targetValue = typeof value === "string" ? value : value[buildTarget];
|
|
111
|
+
if (typeof targetValue === "string" && name !== targetValue) {
|
|
112
|
+
defineOptions[name] = targetValue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
if (Object.keys(defineOptions).length) {
|
|
117
|
+
config.plugins.push(new rspack.DefinePlugin(defineOptions));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
config.resolve = {
|
|
121
|
+
...config.resolve,
|
|
122
|
+
extensions: ["...", ".ts"]
|
|
123
|
+
};
|
|
124
|
+
addCssConfig(esmx, options, context);
|
|
125
|
+
options?.config?.(context);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function filename(esmx, name, ext = "[ext]") {
|
|
130
|
+
return esmx.isProd ? `${name}/[name].[contenthash:8].final${ext}` : `${name}/[path][name]${ext}`;
|
|
131
|
+
}
|
|
132
|
+
function addCssConfig(esmx, options, { config }) {
|
|
133
|
+
if (options.css === false) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (options.css === "js") {
|
|
137
|
+
const cssRule = [
|
|
138
|
+
{
|
|
139
|
+
loader: options.loaders?.styleLoader ?? RSPACK_LOADER.styleLoader,
|
|
140
|
+
options: options.styleLoader
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
loader: options.loaders?.cssLoader ?? RSPACK_LOADER.cssLoader,
|
|
144
|
+
options: options.cssLoader
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
loader: options.loaders?.lightningcssLoader ?? RSPACK_LOADER.lightningcssLoader,
|
|
148
|
+
options: {
|
|
149
|
+
targets: options.target?.web ?? [],
|
|
150
|
+
minify: esmx.isProd
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
];
|
|
154
|
+
const lessRule = [
|
|
155
|
+
{
|
|
156
|
+
loader: options.loaders?.lessLoader ?? RSPACK_LOADER.lessLoader,
|
|
157
|
+
options: options.lessLoader
|
|
158
|
+
}
|
|
159
|
+
];
|
|
160
|
+
if (options.styleResourcesLoader) {
|
|
161
|
+
lessRule.push({
|
|
162
|
+
loader: options.loaders?.styleResourcesLoader ?? RSPACK_LOADER.styleResourcesLoader,
|
|
163
|
+
options: options.styleResourcesLoader
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
config.module = {
|
|
167
|
+
...config.module,
|
|
168
|
+
rules: [
|
|
169
|
+
...config.module?.rules ?? [],
|
|
170
|
+
{
|
|
171
|
+
test: /\.less$/,
|
|
172
|
+
use: [...cssRule, ...lessRule],
|
|
173
|
+
type: "javascript/auto"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
test: /\.css$/,
|
|
177
|
+
use: cssRule,
|
|
178
|
+
type: "javascript/auto"
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
config.experiments = {
|
|
185
|
+
...config.experiments,
|
|
186
|
+
css: true
|
|
187
|
+
};
|
|
188
|
+
if (!config.experiments.css) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const lessLoaders = [
|
|
192
|
+
{
|
|
193
|
+
loader: options.loaders?.lessLoader ?? RSPACK_LOADER.lessLoader,
|
|
194
|
+
options: options.lessLoader
|
|
195
|
+
}
|
|
196
|
+
];
|
|
197
|
+
if (options.styleResourcesLoader) {
|
|
198
|
+
lessLoaders.push({
|
|
199
|
+
loader: options.loaders?.styleResourcesLoader ?? RSPACK_LOADER.styleResourcesLoader,
|
|
200
|
+
options: options.styleResourcesLoader
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
config.module = {
|
|
204
|
+
...config.module,
|
|
205
|
+
rules: [
|
|
206
|
+
...config.module?.rules ?? [],
|
|
207
|
+
{
|
|
208
|
+
test: /\.less$/,
|
|
209
|
+
use: [...lessLoaders],
|
|
210
|
+
type: "css"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
};
|
|
214
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type RspackAppConfigContext, type RspackAppOptions, createRspackApp } from './app';
|
|
2
|
+
export { createRspackHtmlApp, type RspackHtmlAppOptions } from './html-app';
|
|
3
|
+
export type { BuildTarget } from './build-target';
|
|
4
|
+
export { RSPACK_LOADER } from './loader';
|
|
5
|
+
import * as rspack from '@rspack/core';
|
|
6
|
+
export { rspack };
|
package/dist/index.mjs
ADDED
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const RSPACK_LOADER: {
|
|
2
|
+
/**
|
|
3
|
+
* Rspack 内置的 builtin:swc-loader
|
|
4
|
+
*/
|
|
5
|
+
builtinSwcLoader: string;
|
|
6
|
+
/**
|
|
7
|
+
* Rspack 内置的 lightningcss-loader
|
|
8
|
+
*/
|
|
9
|
+
lightningcssLoader: string;
|
|
10
|
+
/**
|
|
11
|
+
* css-loader
|
|
12
|
+
*/
|
|
13
|
+
cssLoader: string;
|
|
14
|
+
/**
|
|
15
|
+
* style-loader
|
|
16
|
+
*/
|
|
17
|
+
styleLoader: string;
|
|
18
|
+
/**
|
|
19
|
+
* less-loader
|
|
20
|
+
*/
|
|
21
|
+
lessLoader: string;
|
|
22
|
+
/**
|
|
23
|
+
* style-resources-loader
|
|
24
|
+
*/
|
|
25
|
+
styleResourcesLoader: string;
|
|
26
|
+
/**
|
|
27
|
+
* worker-rspack-loader
|
|
28
|
+
*/
|
|
29
|
+
workerRspackLoader: string;
|
|
30
|
+
};
|
package/dist/loader.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function resolve(name) {
|
|
2
|
+
return new URL(import.meta.resolve(name)).pathname;
|
|
3
|
+
}
|
|
4
|
+
export const RSPACK_LOADER = {
|
|
5
|
+
/**
|
|
6
|
+
* Rspack 内置的 builtin:swc-loader
|
|
7
|
+
*/
|
|
8
|
+
builtinSwcLoader: "builtin:swc-loader",
|
|
9
|
+
/**
|
|
10
|
+
* Rspack 内置的 lightningcss-loader
|
|
11
|
+
*/
|
|
12
|
+
lightningcssLoader: "builtin:lightningcss-loader",
|
|
13
|
+
/**
|
|
14
|
+
* css-loader
|
|
15
|
+
*/
|
|
16
|
+
cssLoader: resolve("css-loader"),
|
|
17
|
+
/**
|
|
18
|
+
* style-loader
|
|
19
|
+
*/
|
|
20
|
+
styleLoader: resolve("style-loader"),
|
|
21
|
+
/**
|
|
22
|
+
* less-loader
|
|
23
|
+
*/
|
|
24
|
+
lessLoader: resolve("less-loader"),
|
|
25
|
+
/**
|
|
26
|
+
* style-resources-loader
|
|
27
|
+
*/
|
|
28
|
+
styleResourcesLoader: resolve("style-resources-loader"),
|
|
29
|
+
/**
|
|
30
|
+
* worker-rspack-loader
|
|
31
|
+
*/
|
|
32
|
+
workerRspackLoader: resolve("worker-rspack-loader")
|
|
33
|
+
};
|
package/dist/pack.d.ts
ADDED
package/dist/pack.mjs
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import Arborist from "@npmcli/arborist";
|
|
3
|
+
import pacote from "pacote";
|
|
4
|
+
export async function pack(esmx) {
|
|
5
|
+
const { packConfig } = esmx;
|
|
6
|
+
const pkgJson = await packConfig.packageJson(
|
|
7
|
+
esmx,
|
|
8
|
+
await buildPackageJson(esmx)
|
|
9
|
+
);
|
|
10
|
+
esmx.writeSync(
|
|
11
|
+
esmx.resolvePath("dist/package.json"),
|
|
12
|
+
JSON.stringify(pkgJson, null, 4)
|
|
13
|
+
);
|
|
14
|
+
if (!packConfig.enable) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
await packConfig.onBefore(esmx, pkgJson);
|
|
18
|
+
const data = await pacote.tarball(esmx.resolvePath("dist"), {
|
|
19
|
+
Arborist
|
|
20
|
+
});
|
|
21
|
+
const hash = contentHash(data);
|
|
22
|
+
packConfig.outputs.forEach((file) => {
|
|
23
|
+
const tgz = esmx.resolvePath("./", file);
|
|
24
|
+
const txt = tgz.replace(/\.tgz$/, ".txt");
|
|
25
|
+
esmx.writeSync(tgz, data);
|
|
26
|
+
esmx.writeSync(txt, hash);
|
|
27
|
+
});
|
|
28
|
+
await packConfig.onAfter(esmx, pkgJson, data);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
async function buildPackageJson(esmx) {
|
|
32
|
+
const [clientJson, serverJson, curJson] = await Promise.all([
|
|
33
|
+
esmx.readJson(esmx.resolvePath("dist/client/manifest.json")),
|
|
34
|
+
esmx.readJson(esmx.resolvePath("dist/server/manifest.json")),
|
|
35
|
+
esmx.readJson(esmx.resolvePath("package.json"))
|
|
36
|
+
]);
|
|
37
|
+
const exports = {
|
|
38
|
+
...curJson?.exports
|
|
39
|
+
};
|
|
40
|
+
const set = /* @__PURE__ */ new Set([
|
|
41
|
+
...Object.keys(clientJson.exports),
|
|
42
|
+
...Object.keys(serverJson.exports)
|
|
43
|
+
]);
|
|
44
|
+
set.forEach((name) => {
|
|
45
|
+
const client = clientJson.exports[name];
|
|
46
|
+
const server = serverJson.exports[name];
|
|
47
|
+
const exportName = `./${name}`;
|
|
48
|
+
if (client && server) {
|
|
49
|
+
exports[exportName] = {
|
|
50
|
+
default: `./server/${server}`,
|
|
51
|
+
browser: `./client/${client}`
|
|
52
|
+
};
|
|
53
|
+
} else if (client) {
|
|
54
|
+
exports[exportName] = `./client/${client}`;
|
|
55
|
+
} else if (server) {
|
|
56
|
+
exports[exportName] = `./server/${server}`;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const buildJson = {
|
|
60
|
+
...curJson,
|
|
61
|
+
exports
|
|
62
|
+
};
|
|
63
|
+
return buildJson;
|
|
64
|
+
}
|
|
65
|
+
function contentHash(buffer, algorithm = "sha256") {
|
|
66
|
+
const hash = crypto.createHash("sha256");
|
|
67
|
+
hash.update(buffer);
|
|
68
|
+
return `${algorithm}-${hash.digest("hex")}`;
|
|
69
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './rsbuild';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./rsbuild.mjs";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Compiler, type RspackOptions } from '@rspack/core';
|
|
2
|
+
export declare function createRsBuild(options: RspackOptions[]): {
|
|
3
|
+
readonly compilers: Compiler[];
|
|
4
|
+
build(): Promise<boolean>;
|
|
5
|
+
watch(): void;
|
|
6
|
+
};
|
|
7
|
+
export declare class RsBuild {
|
|
8
|
+
private compiler;
|
|
9
|
+
constructor(options: RspackOptions);
|
|
10
|
+
build(): Promise<boolean>;
|
|
11
|
+
watch(): void;
|
|
12
|
+
}
|