@rspack/core 0.0.1 → 0.0.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/CHANGELOG.md +11 -0
- package/README.md +1 -0
- package/bin.js +1 -0
- package/dist/bin/index.d.ts +1 -0
- package/dist/bin/index.js +32 -0
- package/dist/build.d.ts +1 -0
- package/dist/build.js +12 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +25 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +184 -0
- package/dist/server/index.d.ts +0 -0
- package/dist/server/index.js +0 -0
- package/example/basic.ts +43 -0
- package/example/react-example/index.html +12 -0
- package/example/react-example/package.json +17 -0
- package/example/react-example/rspack.config.json +13 -0
- package/example/react-example/src/app.jsx +44 -0
- package/example/react-example/src/base.css +9 -0
- package/example/react-example/src/button.jsx +3 -0
- package/example/react-example/src/dark.svg +1 -0
- package/example/react-example/src/data.json +5 -0
- package/example/react-example/src/file.jpg +0 -0
- package/example/react-example/src/file.png +0 -0
- package/example/react-example/src/file.svg +1 -0
- package/example/react-example/src/foo.css +3 -0
- package/example/react-example/src/index.html +32 -0
- package/example/react-example/src/index.js +1 -0
- package/example/react-example/src/light.svg +48 -0
- package/example/react-example/src/logo.svg +18 -0
- package/example/react-with-sass.ts +28 -0
- package/package.json +28 -12
- package/src/bin/index.ts +36 -0
- package/src/build.ts +8 -0
- package/src/config.ts +66 -0
- package/src/index.ts +252 -0
- package/src/server/index.ts +0 -0
- package/tsconfig.json +13 -0
- package/index.js +0 -1
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# rspack
|
package/bin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require("./dist/bin/index");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commander_1 = require("commander");
|
|
4
|
+
const rspack_dev_server_1 = require("rspack-dev-server");
|
|
5
|
+
const __1 = require("..");
|
|
6
|
+
const build_1 = require("../build");
|
|
7
|
+
const program = new commander_1.Command();
|
|
8
|
+
program
|
|
9
|
+
.option("--env", "env")
|
|
10
|
+
.command("build", {
|
|
11
|
+
isDefault: true
|
|
12
|
+
})
|
|
13
|
+
.description("Rspack build cli")
|
|
14
|
+
.argument("<config-file>", "rspack config file path")
|
|
15
|
+
.action(async (configPath) => {
|
|
16
|
+
const config = require(configPath);
|
|
17
|
+
const stats = await (0, build_1.build)(config);
|
|
18
|
+
console.log(stats);
|
|
19
|
+
});
|
|
20
|
+
program
|
|
21
|
+
.command("dev")
|
|
22
|
+
.description("Rspack build cli")
|
|
23
|
+
.argument("<config-file>", "rspack config file path")
|
|
24
|
+
.action(async (configPath) => {
|
|
25
|
+
const config = require(configPath);
|
|
26
|
+
const rspack = new __1.Rspack(config);
|
|
27
|
+
const { options: { dev: { port = 8080 } = {} } = {} } = rspack;
|
|
28
|
+
await rspack.build();
|
|
29
|
+
const server = await (0, rspack_dev_server_1.createServer)(rspack.options);
|
|
30
|
+
server.listen(port, () => console.log(`Server listening on port: ${port}`));
|
|
31
|
+
});
|
|
32
|
+
program.parse();
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function build(config: any): Promise<void>;
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.build = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
async function build(config) {
|
|
6
|
+
const rspack = new _1.Rspack(config);
|
|
7
|
+
const stats = await rspack.build();
|
|
8
|
+
if (stats.errors.length > 0) {
|
|
9
|
+
throw new Error(stats.errors[0].message);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.build = build;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RawOptions } from "@rspack/binding";
|
|
2
|
+
import type { ModuleRule } from ".";
|
|
3
|
+
export declare type Plugin = {
|
|
4
|
+
name: string;
|
|
5
|
+
done?: () => void | Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export interface RspackOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Entry points of compilation.
|
|
10
|
+
*/
|
|
11
|
+
entry?: RawOptions["entry"];
|
|
12
|
+
/**
|
|
13
|
+
* An **absolute** path pointed the
|
|
14
|
+
*/
|
|
15
|
+
context?: RawOptions["context"];
|
|
16
|
+
/**
|
|
17
|
+
* An array of plugins
|
|
18
|
+
*/
|
|
19
|
+
plugins?: Plugin[];
|
|
20
|
+
/**
|
|
21
|
+
* dev server
|
|
22
|
+
*/
|
|
23
|
+
dev?: {
|
|
24
|
+
port?: Number;
|
|
25
|
+
static?: {
|
|
26
|
+
directory?: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Module configuration.
|
|
31
|
+
*/
|
|
32
|
+
module?: {
|
|
33
|
+
rules?: ModuleRule[];
|
|
34
|
+
parser?: RawOptions["module"]["parser"];
|
|
35
|
+
};
|
|
36
|
+
define?: RawOptions["define"];
|
|
37
|
+
target?: RawOptions["target"];
|
|
38
|
+
mode?: RawOptions["mode"];
|
|
39
|
+
external?: RawOptions["external"];
|
|
40
|
+
}
|
|
41
|
+
export declare function User2Native(config: RspackOptions): RawOptions & {
|
|
42
|
+
plugins: Plugin[];
|
|
43
|
+
};
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.User2Native = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
function User2Native(config) {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
return {
|
|
8
|
+
entry: (_a = config.entry) !== null && _a !== void 0 ? _a : {},
|
|
9
|
+
context: config.context,
|
|
10
|
+
define: config.define,
|
|
11
|
+
target: config.target,
|
|
12
|
+
external: config.external,
|
|
13
|
+
plugins: (_b = config.plugins) !== null && _b !== void 0 ? _b : [],
|
|
14
|
+
module: {
|
|
15
|
+
// TODO: support mutliple rules to support `Module Type`
|
|
16
|
+
rules: ((_d = (_c = config === null || config === void 0 ? void 0 : config.module) === null || _c === void 0 ? void 0 : _c.rules) !== null && _d !== void 0 ? _d : []).map(rule => {
|
|
17
|
+
return {
|
|
18
|
+
...rule,
|
|
19
|
+
uses: (0, _1.createRawModuleRuleUses)(rule.uses || [])
|
|
20
|
+
};
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
exports.User2Native = User2Native;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export * from "./build";
|
|
3
|
+
import * as binding from "@rspack/binding";
|
|
4
|
+
import type { RawModuleRuleUse, RawModuleRule } from "@rspack/binding";
|
|
5
|
+
import type { RspackOptions } from "./config";
|
|
6
|
+
interface ModuleRule {
|
|
7
|
+
test?: RawModuleRule["test"];
|
|
8
|
+
resource?: RawModuleRule["resource"];
|
|
9
|
+
resourceQuery?: RawModuleRule["resourceQuery"];
|
|
10
|
+
uses?: ModuleRuleUse[];
|
|
11
|
+
type?: RawModuleRule["type"];
|
|
12
|
+
}
|
|
13
|
+
declare type ModuleRuleUse = {
|
|
14
|
+
builtinLoader: BuiltinLoader;
|
|
15
|
+
options?: unknown;
|
|
16
|
+
} | {
|
|
17
|
+
loader: JsLoader;
|
|
18
|
+
options?: unknown;
|
|
19
|
+
};
|
|
20
|
+
interface JsLoader {
|
|
21
|
+
(this: LoaderContext, loaderContext: LoaderContext): Promise<LoaderResult | void> | LoaderResult | void;
|
|
22
|
+
displayName?: string;
|
|
23
|
+
}
|
|
24
|
+
declare type BuiltinLoader = string;
|
|
25
|
+
interface LoaderContextInternal {
|
|
26
|
+
source: number[];
|
|
27
|
+
resource: String;
|
|
28
|
+
resourcePath: String;
|
|
29
|
+
resourceQuery: String | null;
|
|
30
|
+
resourceFragment: String | null;
|
|
31
|
+
}
|
|
32
|
+
interface LoaderContext extends Pick<LoaderContextInternal, "resource" | "resourcePath" | "resourceQuery" | "resourceFragment"> {
|
|
33
|
+
source: {
|
|
34
|
+
getCode(): string;
|
|
35
|
+
getBuffer(): Buffer;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface LoaderResult {
|
|
39
|
+
content: Buffer | string;
|
|
40
|
+
meta: Buffer | string;
|
|
41
|
+
}
|
|
42
|
+
declare function createRawModuleRuleUses(uses: ModuleRuleUse[]): RawModuleRuleUse[];
|
|
43
|
+
declare class Rspack {
|
|
44
|
+
#private;
|
|
45
|
+
options: RspackOptions;
|
|
46
|
+
constructor(options: RspackOptions);
|
|
47
|
+
build(): Promise<binding.Stats>;
|
|
48
|
+
rebuild(): Promise<Record<string, string>>;
|
|
49
|
+
}
|
|
50
|
+
export { Rspack, createRawModuleRuleUses };
|
|
51
|
+
export type { ModuleRule };
|
|
52
|
+
export default Rspack;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
29
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
30
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
31
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
32
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
33
|
+
};
|
|
34
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
35
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
36
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
37
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
38
|
+
};
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
var _Rspack_instances, _Rspack_instance, _Rspack_plugins, _Rspack_done;
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.createRawModuleRuleUses = exports.Rspack = void 0;
|
|
45
|
+
__exportStar(require("./build"), exports);
|
|
46
|
+
const binding = __importStar(require("@rspack/binding"));
|
|
47
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
48
|
+
const Config = __importStar(require("./config"));
|
|
49
|
+
const toBuffer = (bufLike) => {
|
|
50
|
+
if (Buffer.isBuffer(bufLike)) {
|
|
51
|
+
return bufLike;
|
|
52
|
+
}
|
|
53
|
+
else if (typeof bufLike === "string") {
|
|
54
|
+
return Buffer.from(bufLike);
|
|
55
|
+
}
|
|
56
|
+
throw new Error("Buffer or string expected");
|
|
57
|
+
};
|
|
58
|
+
function createRawModuleRuleUses(uses) {
|
|
59
|
+
return createRawModuleRuleUsesImpl([...uses].reverse());
|
|
60
|
+
}
|
|
61
|
+
exports.createRawModuleRuleUses = createRawModuleRuleUses;
|
|
62
|
+
function createRawModuleRuleUsesImpl(uses) {
|
|
63
|
+
const index = uses.findIndex(use => "builtinLoader" in use);
|
|
64
|
+
if (index < 0) {
|
|
65
|
+
return [composeJsUse(uses)];
|
|
66
|
+
}
|
|
67
|
+
const before = uses.slice(0, index);
|
|
68
|
+
const after = uses.slice(index + 1);
|
|
69
|
+
return [
|
|
70
|
+
composeJsUse(before),
|
|
71
|
+
createNativeUse(uses[index]),
|
|
72
|
+
...createRawModuleRuleUsesImpl(after)
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
function createNativeUse(use) {
|
|
76
|
+
var _a;
|
|
77
|
+
(0, node_assert_1.default)("builtinLoader" in use);
|
|
78
|
+
if (use.builtinLoader === "sass-loader") {
|
|
79
|
+
((_a = use.options) !== null && _a !== void 0 ? _a : (use.options = {})).__exePath = require.resolve(`@tmp-sass-embedded/${process.platform}-${process.arch}/dart-sass-embedded/dart-sass-embedded${process.platform === "win32" ? ".bat" : ""}`);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
builtinLoader: use.builtinLoader,
|
|
83
|
+
options: JSON.stringify(use.options)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function composeJsUse(uses) {
|
|
87
|
+
async function loader(err, data) {
|
|
88
|
+
if (err) {
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
const loaderThreadsafeContext = JSON.parse(data.toString("utf-8"));
|
|
92
|
+
const { p: payload, id } = loaderThreadsafeContext;
|
|
93
|
+
const loaderContextInternal = {
|
|
94
|
+
source: payload.source,
|
|
95
|
+
resourcePath: payload.resourcePath,
|
|
96
|
+
resourceQuery: payload.resourceQuery,
|
|
97
|
+
resource: payload.resource,
|
|
98
|
+
resourceFragment: payload.resourceFragment
|
|
99
|
+
};
|
|
100
|
+
let sourceBuffer = Buffer.from(loaderContextInternal.source);
|
|
101
|
+
let meta = Buffer.from("");
|
|
102
|
+
// Loader is executed from right to left
|
|
103
|
+
for (const use of uses) {
|
|
104
|
+
(0, node_assert_1.default)("loader" in use);
|
|
105
|
+
const loaderContext = {
|
|
106
|
+
...loaderContextInternal,
|
|
107
|
+
source: {
|
|
108
|
+
getCode() {
|
|
109
|
+
return sourceBuffer.toString("utf-8");
|
|
110
|
+
},
|
|
111
|
+
getBuffer() {
|
|
112
|
+
return sourceBuffer;
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
getOptions() {
|
|
116
|
+
return use.options;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
let loaderResult;
|
|
120
|
+
if ((loaderResult = await Promise.resolve().then(() => use.loader.apply(loaderContext, [loaderContext])))) {
|
|
121
|
+
const content = loaderResult.content;
|
|
122
|
+
meta = meta.length > 0 ? meta : toBuffer(loaderResult.meta);
|
|
123
|
+
sourceBuffer = toBuffer(content);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const loaderResultPayload = {
|
|
127
|
+
content: [...sourceBuffer],
|
|
128
|
+
meta: [...meta]
|
|
129
|
+
};
|
|
130
|
+
const loaderThreadsafeResult = {
|
|
131
|
+
id: id,
|
|
132
|
+
p: loaderResultPayload
|
|
133
|
+
};
|
|
134
|
+
return Buffer.from(JSON.stringify(loaderThreadsafeResult), "utf-8");
|
|
135
|
+
}
|
|
136
|
+
loader.displayName = `NodeLoaderAdapter(${uses
|
|
137
|
+
.map(item => {
|
|
138
|
+
(0, node_assert_1.default)("loader" in item);
|
|
139
|
+
return item.loader.displayName || item.loader.name || "unknown-loader";
|
|
140
|
+
})
|
|
141
|
+
.join(" -> ")})`;
|
|
142
|
+
return {
|
|
143
|
+
loader
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const createDummyResult = (id) => {
|
|
147
|
+
const result = {
|
|
148
|
+
id,
|
|
149
|
+
inner: null
|
|
150
|
+
};
|
|
151
|
+
return JSON.stringify(result);
|
|
152
|
+
};
|
|
153
|
+
class Rspack {
|
|
154
|
+
constructor(options) {
|
|
155
|
+
var _a;
|
|
156
|
+
this.options = options;
|
|
157
|
+
_Rspack_instances.add(this);
|
|
158
|
+
_Rspack_instance.set(this, void 0);
|
|
159
|
+
_Rspack_plugins.set(this, void 0);
|
|
160
|
+
const nativeConfig = Config.User2Native(options);
|
|
161
|
+
__classPrivateFieldSet(this, _Rspack_plugins, (_a = options.plugins) !== null && _a !== void 0 ? _a : [], "f");
|
|
162
|
+
__classPrivateFieldSet(this, _Rspack_instance, binding.newRspack(nativeConfig, {
|
|
163
|
+
doneCallback: __classPrivateFieldGet(this, _Rspack_instances, "m", _Rspack_done).bind(this)
|
|
164
|
+
}), "f");
|
|
165
|
+
}
|
|
166
|
+
async build() {
|
|
167
|
+
const stats = await binding.build(__classPrivateFieldGet(this, _Rspack_instance, "f"));
|
|
168
|
+
return stats;
|
|
169
|
+
}
|
|
170
|
+
async rebuild() {
|
|
171
|
+
const stats = await binding.rebuild(__classPrivateFieldGet(this, _Rspack_instance, "f"));
|
|
172
|
+
return stats;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.Rspack = Rspack;
|
|
176
|
+
_Rspack_instance = new WeakMap(), _Rspack_plugins = new WeakMap(), _Rspack_instances = new WeakSet(), _Rspack_done = async function _Rspack_done(err, value) {
|
|
177
|
+
var _a;
|
|
178
|
+
const context = JSON.parse(value);
|
|
179
|
+
for (const plugin of __classPrivateFieldGet(this, _Rspack_plugins, "f")) {
|
|
180
|
+
await ((_a = plugin.done) === null || _a === void 0 ? void 0 : _a.call(plugin));
|
|
181
|
+
}
|
|
182
|
+
return createDummyResult(context.id);
|
|
183
|
+
};
|
|
184
|
+
exports.default = Rspack;
|
|
File without changes
|
|
File without changes
|
package/example/basic.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import postcssLoader from "rspack-plugin-postcss";
|
|
3
|
+
import { Rspack } from "../src";
|
|
4
|
+
|
|
5
|
+
const rspack = new Rspack({
|
|
6
|
+
entry: {
|
|
7
|
+
main: path.resolve(__dirname, "../../../examples/postcss/index.js")
|
|
8
|
+
},
|
|
9
|
+
context: path.resolve(__dirname, "../../../examples/postcss"),
|
|
10
|
+
plugins: ["html"],
|
|
11
|
+
module: {
|
|
12
|
+
rules: [
|
|
13
|
+
{
|
|
14
|
+
test: ".module.css$",
|
|
15
|
+
uses: [
|
|
16
|
+
{
|
|
17
|
+
loader: postcssLoader,
|
|
18
|
+
options: {
|
|
19
|
+
modules: true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// {
|
|
23
|
+
// loader: function testLoader(loaderContext) {
|
|
24
|
+
// // console.log(loaderContext);
|
|
25
|
+
// return {
|
|
26
|
+
// content: loaderContext.source.getBufFer(),
|
|
27
|
+
// meta: Buffer.from("something")
|
|
28
|
+
// };
|
|
29
|
+
// }
|
|
30
|
+
// }
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
async function main() {
|
|
38
|
+
const stats = await rspack.build();
|
|
39
|
+
console.log(stats);
|
|
40
|
+
// assert(stats.assets.length > 0)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
main();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Document</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "rspack dev rspack.config.json"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@rspack/core": "workspace:*",
|
|
14
|
+
"react": "17.0.0",
|
|
15
|
+
"react-dom": "17.0.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
import './base.css';
|
|
4
|
+
import LogoJPG from './file.jpg';
|
|
5
|
+
import LogoPNG from './file.png';
|
|
6
|
+
import LogoSVG from './file.svg';
|
|
7
|
+
import Json from './data.json';
|
|
8
|
+
// import Dark from './dark.svg';
|
|
9
|
+
// import Light from './light.svg'
|
|
10
|
+
// import LogoUrl from './logo.svg'
|
|
11
|
+
// import Logo from './logo.svg'
|
|
12
|
+
// const Button = React.lazy(() => import('../src/button'))
|
|
13
|
+
|
|
14
|
+
// console.log('LogoUrl', LogoUrl)
|
|
15
|
+
// console.log('Logo', Logo)
|
|
16
|
+
|
|
17
|
+
const App = () => {
|
|
18
|
+
return (
|
|
19
|
+
<React.Suspense fallback={<div>loading...</div>}>
|
|
20
|
+
<div>hello world</div>
|
|
21
|
+
{/* <Button></Button> */}
|
|
22
|
+
|
|
23
|
+
<img
|
|
24
|
+
style={{ width: '40px', height: '40px' }}
|
|
25
|
+
src={LogoJPG}
|
|
26
|
+
alt="logo jpg"
|
|
27
|
+
/>
|
|
28
|
+
<img
|
|
29
|
+
style={{ width: '40px', height: '40px' }}
|
|
30
|
+
src={LogoPNG}
|
|
31
|
+
alt="logo png"
|
|
32
|
+
/>
|
|
33
|
+
<img
|
|
34
|
+
style={{ width: '40px', height: '40px' }}
|
|
35
|
+
src={LogoSVG}
|
|
36
|
+
alt="logo svg"
|
|
37
|
+
/>
|
|
38
|
+
{/* <Logo width={'40px'} height={'40px'} />
|
|
39
|
+
<Light width={'40px'} height={'40px'} />
|
|
40
|
+
<Dark width={'40px'} height={'40px'} /> */}
|
|
41
|
+
</React.Suspense>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
ReactDOM.render(<App />, document.getElementById('root'));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1599669065723" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18411" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M390 250c0-52.6 10.6-102.6 29.8-148.2C237.4 146 102 310.2 102 506c0 229.6 186.4 416 416 416 195.8 0 360-135.4 404.2-317.8-45.6 19.2-95.8 29.8-148.2 29.8-212 0-384-172-384-384z" p-id="18412"></path></svg>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><title>icon-square-small</title><path fill="#FFF" d="M300 .1L565 150v299.9L300 599.8 35 449.9V150z"/><path fill="#8ED6FB" d="M517.7 439.5L308.8 557.8v-92L439 394.1l78.7 45.4zm14.3-12.9V179.4l-76.4 44.1v159l76.4 44.1zM81.5 439.5l208.9 118.2v-92l-130.2-71.6-78.7 45.4zm-14.3-12.9V179.4l76.4 44.1v159l-76.4 44.1zm8.9-263.2L290.4 42.2v89l-137.3 75.5-1.1.6-75.9-43.9zm446.9 0L308.8 42.2v89L446 206.8l1.1.6 75.9-44z"/><path fill="#1C78C0" d="M290.4 444.8L162 374.1V234.2l128.4 74.1v136.5zm18.4 0l128.4-70.6v-140l-128.4 74.1v136.5zM299.6 303zm-129-85l129-70.9L428.5 218l-128.9 74.4-129-74.4z"/></svg>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>React App</title>
|
|
7
|
+
<script>
|
|
8
|
+
process = {
|
|
9
|
+
env: 'production'
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
<script src="./runtime.js"></script>
|
|
13
|
+
<link rel="stylesheet" href="./main.css">
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
18
|
+
<div id="root"></div>
|
|
19
|
+
<!--
|
|
20
|
+
This HTML file is a template.
|
|
21
|
+
If you open it directly in the browser, you will see an empty page.
|
|
22
|
+
|
|
23
|
+
You can add webfonts, meta tags, or analytics to this file.
|
|
24
|
+
The build step will place the bundled scripts into the <body> tag.
|
|
25
|
+
|
|
26
|
+
To begin the development, run `npm start` or `yarn start`.
|
|
27
|
+
To create a production bundle, use `npm run build` or `yarn build`.
|
|
28
|
+
-->
|
|
29
|
+
</body>
|
|
30
|
+
<script src="./main.js"></script>
|
|
31
|
+
|
|
32
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./app.jsx";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
|
4
|
+
y="0px" viewBox="0 0 22 22" style="enable-background:new 0 0 22 22;" xml:space="preserve">
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
.st1 {
|
|
7
|
+
fill: none;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
background: deepskyblue;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
14
|
+
<title>编组 5备份</title>
|
|
15
|
+
<desc>Created with Sketch.</desc>
|
|
16
|
+
<g id="组件页-Web端-_xD83E__xDD1F_">
|
|
17
|
+
<g id="暗黑模式" transform="translate(2.500000, 2.500000)">
|
|
18
|
+
<g id="编组-12">
|
|
19
|
+
<g id="编组-8">
|
|
20
|
+
<g id="编组-7" transform="translate(7.285714, 0.000000)">
|
|
21
|
+
</g>
|
|
22
|
+
|
|
23
|
+
<g id="编组-7备份"
|
|
24
|
+
transform="translate(8.500000, 8.500000) rotate(-270.000000) translate(-8.500000, -8.500000) translate(7.285714, 0.000000)">
|
|
25
|
+
</g>
|
|
26
|
+
|
|
27
|
+
<g id="编组-7备份-2"
|
|
28
|
+
transform="translate(8.500000, 8.500000) rotate(-225.000000) translate(-8.500000, -8.500000) translate(7.285714, 0.000000)">
|
|
29
|
+
</g>
|
|
30
|
+
|
|
31
|
+
<g id="编组-7备份-3"
|
|
32
|
+
transform="translate(8.500000, 8.500000) rotate(-315.000000) translate(-8.500000, -8.500000) translate(7.285714, 0.000000)">
|
|
33
|
+
</g>
|
|
34
|
+
</g>
|
|
35
|
+
</g>
|
|
36
|
+
<path id="椭圆形" class="st0" d="M8.5,11.5c1.7,0,3-1.4,3-3s-1.4-3-3-3s-3,1.4-3,3S6.8,11.5,8.5,11.5z" />
|
|
37
|
+
<rect id="矩形" x="7.3" class="st0" width="2.4" height="2.4" />
|
|
38
|
+
<rect id="矩形备份-2" x="7.3" y="14.6" class="st0" width="2.4" height="2.4" />
|
|
39
|
+
<polygon id="矩形_1_" class="st0" points="17,7.3 17,9.7 14.6,9.7 14.6,7.3 " />
|
|
40
|
+
<polygon id="矩形备份-2_1_" class="st0" points="2.4,7.3 2.4,9.7 0,9.7 0,7.3 " />
|
|
41
|
+
<polygon id="矩形_2_" class="st0" points="15.4,13.7 13.7,15.4 11.9,13.7 13.7,11.9 " />
|
|
42
|
+
<polygon id="矩形备份-2_2_" class="st0" points="5.1,3.3 3.3,5.1 1.6,3.3 3.3,1.6 " />
|
|
43
|
+
<polygon id="矩形_3_" class="st0" points="13.7,1.6 15.4,3.3 13.7,5.1 11.9,3.3 " />
|
|
44
|
+
<polygon id="矩形备份-2_3_" class="st0" points="3.3,11.9 5.1,13.7 3.3,15.4 1.6,13.7 " />
|
|
45
|
+
</g>
|
|
46
|
+
</g>
|
|
47
|
+
<rect x="0" class="st1" width="22" height="22" />
|
|
48
|
+
</svg>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<g clip-path="url(#clip0)">
|
|
3
|
+
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
4
|
+
d="M5.37754 16.9795L12.7498 9.43027C14.7163 7.41663 17.9428 7.37837 19.9564 9.34482C19.9852 9.37297 20.0137 9.40145 20.0418 9.43027L20.1221 9.51243C22.1049 11.5429 22.1049 14.7847 20.1221 16.8152L12.7498 24.3644C10.7834 26.378 7.55686 26.4163 5.54322 24.4498C5.5144 24.4217 5.48592 24.3932 5.45777 24.3644L5.37754 24.2822C3.39468 22.2518 3.39468 19.0099 5.37754 16.9795Z"
|
|
5
|
+
fill="#12D2AC" />
|
|
6
|
+
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
7
|
+
d="M20.0479 9.43034L27.3399 16.8974C29.3674 18.9735 29.3674 22.2883 27.3399 24.3644C25.3735 26.3781 22.147 26.4163 20.1333 24.4499C20.1045 24.4217 20.076 24.3933 20.0479 24.3644L12.7558 16.8974C10.7284 14.8213 10.7284 11.5065 12.7558 9.43034C14.7223 7.4167 17.9488 7.37844 19.9624 9.34489C19.9912 9.37304 20.0197 9.40152 20.0479 9.43034Z"
|
|
8
|
+
fill="#307AF2" />
|
|
9
|
+
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
10
|
+
d="M20.1321 9.52163L23.6851 13.1599L16.3931 20.627L9.10103 13.1599L12.6541 9.52163C14.6707 7.45664 17.9794 7.4174 20.0444 9.434C20.074 9.46286 20.1032 9.49207 20.1321 9.52163Z"
|
|
11
|
+
fill="#0057FE" />
|
|
12
|
+
</g>
|
|
13
|
+
<defs>
|
|
14
|
+
<clipPath id="clip0">
|
|
15
|
+
<rect width="26" height="19" fill="white" transform="translate(3.5 7)" />
|
|
16
|
+
</clipPath>
|
|
17
|
+
</defs>
|
|
18
|
+
</svg>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { Rspack } from "../src";
|
|
3
|
+
|
|
4
|
+
const context = path.resolve(__dirname, "../../../examples/react-with-sass");
|
|
5
|
+
|
|
6
|
+
const rspack = new Rspack({
|
|
7
|
+
entry: {
|
|
8
|
+
main: path.resolve(context, "./src/index.jsx")
|
|
9
|
+
},
|
|
10
|
+
context,
|
|
11
|
+
plugins: ["html"],
|
|
12
|
+
module: {
|
|
13
|
+
rules: [
|
|
14
|
+
{
|
|
15
|
+
test: "\\.s[ac]ss$",
|
|
16
|
+
uses: [{ builtinLoader: "sass-loader" }],
|
|
17
|
+
type: "css"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const stats = await rspack.build();
|
|
25
|
+
console.log(stats);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rspack/core",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"access": "public"
|
|
3
|
+
"main": "./dist/index.js",
|
|
4
|
+
"version": "0.0.2",
|
|
5
|
+
"bin": {
|
|
6
|
+
"rspack": "./bin.js"
|
|
8
7
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/node": "^18.6.3",
|
|
11
|
+
"tsm": "^2.2.2",
|
|
12
|
+
"typescript": "4.7.3"
|
|
11
13
|
},
|
|
12
|
-
"keywords": [],
|
|
13
|
-
"author": "",
|
|
14
|
-
"license": "ISC",
|
|
15
14
|
"dependencies": {
|
|
16
|
-
"
|
|
15
|
+
"@rspack/binding": "0.0.3",
|
|
16
|
+
"commander": "^9.4.0",
|
|
17
|
+
"@rspack/dev-server": "^0.0.2",
|
|
18
|
+
"@rspack/plugin-postcss": "^0.0.2"
|
|
19
|
+
},
|
|
20
|
+
"optionalDependencies": {
|
|
21
|
+
"@tmp-sass-embedded/darwin-arm64": "1.54.4",
|
|
22
|
+
"@tmp-sass-embedded/darwin-x64": "1.54.4",
|
|
23
|
+
"@tmp-sass-embedded/linux-arm64": "1.54.4",
|
|
24
|
+
"@tmp-sass-embedded/linux-ia32": "1.54.4",
|
|
25
|
+
"@tmp-sass-embedded/linux-x64": "1.54.4",
|
|
26
|
+
"@tmp-sass-embedded/win32-ia32": "1.54.4",
|
|
27
|
+
"@tmp-sass-embedded/win32-x64": "1.54.4"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "rm -rf dist/ && tsc -p tsconfig.json",
|
|
31
|
+
"dev": "tsc -p tsconfig.json -w",
|
|
32
|
+
"example": "node -r tsm ./example/basic.ts"
|
|
17
33
|
}
|
|
18
|
-
}
|
|
34
|
+
}
|
package/src/bin/index.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createServer } from "rspack-dev-server";
|
|
3
|
+
import { Rspack } from "..";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import { build } from "../build";
|
|
6
|
+
|
|
7
|
+
const program = new Command();
|
|
8
|
+
|
|
9
|
+
program
|
|
10
|
+
.option("--env", "env")
|
|
11
|
+
.command("build", {
|
|
12
|
+
isDefault: true
|
|
13
|
+
})
|
|
14
|
+
.description("Rspack build cli")
|
|
15
|
+
|
|
16
|
+
.argument("<config-file>", "rspack config file path")
|
|
17
|
+
.action(async configPath => {
|
|
18
|
+
const config = require(configPath);
|
|
19
|
+
const stats = await build(config);
|
|
20
|
+
console.log(stats);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.command("dev")
|
|
25
|
+
.description("Rspack build cli")
|
|
26
|
+
.argument("<config-file>", "rspack config file path")
|
|
27
|
+
.action(async configPath => {
|
|
28
|
+
const config = require(configPath);
|
|
29
|
+
const rspack = new Rspack(config);
|
|
30
|
+
const { options: { dev: { port = 8080 } = {} } = {} } = rspack;
|
|
31
|
+
await rspack.build();
|
|
32
|
+
const server = await createServer(rspack.options);
|
|
33
|
+
server.listen(port, () => console.log(`Server listening on port: ${port}`));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
program.parse();
|
package/src/build.ts
ADDED
package/src/config.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { RawOptions } from "@rspack/binding";
|
|
2
|
+
|
|
3
|
+
import type { ModuleRule } from ".";
|
|
4
|
+
import { createRawModuleRuleUses } from ".";
|
|
5
|
+
|
|
6
|
+
export type Plugin = {
|
|
7
|
+
name: string;
|
|
8
|
+
done?: () => void | Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export interface RspackOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Entry points of compilation.
|
|
14
|
+
*/
|
|
15
|
+
entry?: RawOptions["entry"];
|
|
16
|
+
/**
|
|
17
|
+
* An **absolute** path pointed the
|
|
18
|
+
*/
|
|
19
|
+
context?: RawOptions["context"];
|
|
20
|
+
/**
|
|
21
|
+
* An array of plugins
|
|
22
|
+
*/
|
|
23
|
+
plugins?: Plugin[];
|
|
24
|
+
/**
|
|
25
|
+
* dev server
|
|
26
|
+
*/
|
|
27
|
+
dev?: {
|
|
28
|
+
port?: Number;
|
|
29
|
+
static?: {
|
|
30
|
+
directory?: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Module configuration.
|
|
35
|
+
*/
|
|
36
|
+
module?: {
|
|
37
|
+
rules?: ModuleRule[];
|
|
38
|
+
parser?: RawOptions["module"]["parser"];
|
|
39
|
+
};
|
|
40
|
+
define?: RawOptions["define"];
|
|
41
|
+
target?: RawOptions["target"];
|
|
42
|
+
mode?: RawOptions["mode"];
|
|
43
|
+
external?: RawOptions["external"];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function User2Native(config: RspackOptions): RawOptions & {
|
|
47
|
+
plugins: Plugin[];
|
|
48
|
+
} {
|
|
49
|
+
return {
|
|
50
|
+
entry: config.entry ?? {},
|
|
51
|
+
context: config.context,
|
|
52
|
+
define: config.define,
|
|
53
|
+
target: config.target,
|
|
54
|
+
external: config.external,
|
|
55
|
+
plugins: config.plugins ?? [],
|
|
56
|
+
module: {
|
|
57
|
+
// TODO: support mutliple rules to support `Module Type`
|
|
58
|
+
rules: (config?.module?.rules ?? []).map(rule => {
|
|
59
|
+
return {
|
|
60
|
+
...rule,
|
|
61
|
+
uses: createRawModuleRuleUses(rule.uses || [])
|
|
62
|
+
};
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
export * from "./build";
|
|
2
|
+
|
|
3
|
+
import * as binding from "@rspack/binding";
|
|
4
|
+
import type {
|
|
5
|
+
ExternalObject,
|
|
6
|
+
RspackInternal,
|
|
7
|
+
RawModuleRuleUse,
|
|
8
|
+
RawModuleRule
|
|
9
|
+
} from "@rspack/binding";
|
|
10
|
+
|
|
11
|
+
import assert from "node:assert";
|
|
12
|
+
import * as Config from "./config";
|
|
13
|
+
import type { RspackOptions } from "./config";
|
|
14
|
+
|
|
15
|
+
interface ModuleRule {
|
|
16
|
+
test?: RawModuleRule["test"];
|
|
17
|
+
resource?: RawModuleRule["resource"];
|
|
18
|
+
resourceQuery?: RawModuleRule["resourceQuery"];
|
|
19
|
+
uses?: ModuleRuleUse[];
|
|
20
|
+
type?: RawModuleRule["type"];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type ModuleRuleUse =
|
|
24
|
+
| {
|
|
25
|
+
builtinLoader: BuiltinLoader;
|
|
26
|
+
options?: unknown;
|
|
27
|
+
}
|
|
28
|
+
| {
|
|
29
|
+
loader: JsLoader;
|
|
30
|
+
options?: unknown;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
interface JsLoader {
|
|
34
|
+
(this: LoaderContext, loaderContext: LoaderContext):
|
|
35
|
+
| Promise<LoaderResult | void>
|
|
36
|
+
| LoaderResult
|
|
37
|
+
| void;
|
|
38
|
+
displayName?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type BuiltinLoader = string;
|
|
42
|
+
|
|
43
|
+
interface LoaderThreadsafeContext {
|
|
44
|
+
id: number;
|
|
45
|
+
p: LoaderContextInternal;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface LoaderContextInternal {
|
|
49
|
+
// TODO: It's not a good way to do this, we should split the `source` into a separate type and avoid using `serde_json`, but it's a temporary solution.
|
|
50
|
+
source: number[];
|
|
51
|
+
resource: String;
|
|
52
|
+
resourcePath: String;
|
|
53
|
+
resourceQuery: String | null;
|
|
54
|
+
resourceFragment: String | null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface LoaderContext
|
|
58
|
+
extends Pick<
|
|
59
|
+
LoaderContextInternal,
|
|
60
|
+
"resource" | "resourcePath" | "resourceQuery" | "resourceFragment"
|
|
61
|
+
> {
|
|
62
|
+
source: {
|
|
63
|
+
getCode(): string;
|
|
64
|
+
getBuffer(): Buffer;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface LoaderResultInternal {
|
|
69
|
+
content: number[];
|
|
70
|
+
meta: number[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface LoaderResult {
|
|
74
|
+
content: Buffer | string;
|
|
75
|
+
meta: Buffer | string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface LoaderThreadsafeResult {
|
|
79
|
+
id: number;
|
|
80
|
+
p: LoaderResultInternal | null | undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const toBuffer = (bufLike: string | Buffer): Buffer => {
|
|
84
|
+
if (Buffer.isBuffer(bufLike)) {
|
|
85
|
+
return bufLike;
|
|
86
|
+
} else if (typeof bufLike === "string") {
|
|
87
|
+
return Buffer.from(bufLike);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw new Error("Buffer or string expected");
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function createRawModuleRuleUses(uses: ModuleRuleUse[]): RawModuleRuleUse[] {
|
|
94
|
+
return createRawModuleRuleUsesImpl([...uses].reverse());
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function createRawModuleRuleUsesImpl(
|
|
98
|
+
uses: ModuleRuleUse[]
|
|
99
|
+
): RawModuleRuleUse[] {
|
|
100
|
+
const index = uses.findIndex(use => "builtinLoader" in use);
|
|
101
|
+
if (index < 0) {
|
|
102
|
+
return [composeJsUse(uses)];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const before = uses.slice(0, index);
|
|
106
|
+
const after = uses.slice(index + 1);
|
|
107
|
+
return [
|
|
108
|
+
composeJsUse(before),
|
|
109
|
+
createNativeUse(uses[index]),
|
|
110
|
+
...createRawModuleRuleUsesImpl(after)
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function createNativeUse(use: ModuleRuleUse): RawModuleRuleUse {
|
|
115
|
+
assert("builtinLoader" in use);
|
|
116
|
+
|
|
117
|
+
if (use.builtinLoader === "sass-loader") {
|
|
118
|
+
(use.options ??= {} as any).__exePath = require.resolve(
|
|
119
|
+
`@tmp-sass-embedded/${process.platform}-${
|
|
120
|
+
process.arch
|
|
121
|
+
}/dart-sass-embedded/dart-sass-embedded${
|
|
122
|
+
process.platform === "win32" ? ".bat" : ""
|
|
123
|
+
}`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
builtinLoader: use.builtinLoader,
|
|
129
|
+
options: JSON.stringify(use.options)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function composeJsUse(uses: ModuleRuleUse[]): RawModuleRuleUse {
|
|
134
|
+
async function loader(err: any, data: Buffer): Promise<Buffer> {
|
|
135
|
+
if (err) {
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const loaderThreadsafeContext: LoaderThreadsafeContext = JSON.parse(
|
|
140
|
+
data.toString("utf-8")
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const { p: payload, id } = loaderThreadsafeContext;
|
|
144
|
+
|
|
145
|
+
const loaderContextInternal: LoaderContextInternal = {
|
|
146
|
+
source: payload.source,
|
|
147
|
+
resourcePath: payload.resourcePath,
|
|
148
|
+
resourceQuery: payload.resourceQuery,
|
|
149
|
+
resource: payload.resource,
|
|
150
|
+
resourceFragment: payload.resourceFragment
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
let sourceBuffer = Buffer.from(loaderContextInternal.source);
|
|
154
|
+
let meta = Buffer.from("");
|
|
155
|
+
// Loader is executed from right to left
|
|
156
|
+
for (const use of uses) {
|
|
157
|
+
assert("loader" in use);
|
|
158
|
+
const loaderContext = {
|
|
159
|
+
...loaderContextInternal,
|
|
160
|
+
source: {
|
|
161
|
+
getCode(): string {
|
|
162
|
+
return sourceBuffer.toString("utf-8");
|
|
163
|
+
},
|
|
164
|
+
getBuffer(): Buffer {
|
|
165
|
+
return sourceBuffer;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
getOptions() {
|
|
169
|
+
return use.options;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
let loaderResult: LoaderResult;
|
|
174
|
+
if (
|
|
175
|
+
(loaderResult = await Promise.resolve().then(() =>
|
|
176
|
+
use.loader.apply(loaderContext, [loaderContext])
|
|
177
|
+
))
|
|
178
|
+
) {
|
|
179
|
+
const content = loaderResult.content;
|
|
180
|
+
meta = meta.length > 0 ? meta : toBuffer(loaderResult.meta);
|
|
181
|
+
sourceBuffer = toBuffer(content);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const loaderResultPayload: LoaderResultInternal = {
|
|
186
|
+
content: [...sourceBuffer],
|
|
187
|
+
meta: [...meta]
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const loaderThreadsafeResult: LoaderThreadsafeResult = {
|
|
191
|
+
id: id,
|
|
192
|
+
p: loaderResultPayload
|
|
193
|
+
};
|
|
194
|
+
return Buffer.from(JSON.stringify(loaderThreadsafeResult), "utf-8");
|
|
195
|
+
}
|
|
196
|
+
loader.displayName = `NodeLoaderAdapter(${uses
|
|
197
|
+
.map(item => {
|
|
198
|
+
assert("loader" in item);
|
|
199
|
+
return item.loader.displayName || item.loader.name || "unknown-loader";
|
|
200
|
+
})
|
|
201
|
+
.join(" -> ")})`;
|
|
202
|
+
return {
|
|
203
|
+
loader
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
interface RspackThreadsafeContext<T> {
|
|
207
|
+
readonly id: number;
|
|
208
|
+
readonly inner: T;
|
|
209
|
+
}
|
|
210
|
+
interface RspackThreadsafeResult<T> {
|
|
211
|
+
readonly id: number;
|
|
212
|
+
readonly inner: T;
|
|
213
|
+
}
|
|
214
|
+
const createDummyResult = (id: number): string => {
|
|
215
|
+
const result: RspackThreadsafeResult<null> = {
|
|
216
|
+
id,
|
|
217
|
+
inner: null
|
|
218
|
+
};
|
|
219
|
+
return JSON.stringify(result);
|
|
220
|
+
};
|
|
221
|
+
class Rspack {
|
|
222
|
+
#instance: ExternalObject<RspackInternal>;
|
|
223
|
+
#plugins: RspackOptions["plugins"];
|
|
224
|
+
constructor(public options: RspackOptions) {
|
|
225
|
+
const nativeConfig = Config.User2Native(options);
|
|
226
|
+
this.#plugins = options.plugins ?? [];
|
|
227
|
+
|
|
228
|
+
this.#instance = binding.newRspack(nativeConfig, {
|
|
229
|
+
doneCallback: this.#done.bind(this)
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async #done(err: Error, value: string) {
|
|
233
|
+
const context: RspackThreadsafeContext<void> = JSON.parse(value);
|
|
234
|
+
for (const plugin of this.#plugins) {
|
|
235
|
+
await plugin.done?.();
|
|
236
|
+
}
|
|
237
|
+
return createDummyResult(context.id);
|
|
238
|
+
}
|
|
239
|
+
async build() {
|
|
240
|
+
const stats = await binding.build(this.#instance);
|
|
241
|
+
return stats;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async rebuild() {
|
|
245
|
+
const stats = await binding.rebuild(this.#instance);
|
|
246
|
+
return stats;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export { Rspack, createRawModuleRuleUses };
|
|
251
|
+
export type { ModuleRule };
|
|
252
|
+
export default Rspack;
|
|
File without changes
|
package/tsconfig.json
ADDED
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {}
|