@rspack/core 0.0.1 → 0.0.4
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 +31 -0
- package/README.md +1 -0
- package/bin.js +1 -0
- package/example/basic.ts +71 -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 +45 -13
- package/src/bin/index.ts +36 -0
- package/src/build.ts +8 -0
- package/src/config/builtins.ts +5 -0
- package/src/config/context.ts +3 -0
- package/src/config/define.ts +3 -0
- package/src/config/dev.ts +32 -0
- package/src/config/entry.ts +3 -0
- package/src/config/external.ts +3 -0
- package/src/config/index.ts +80 -0
- package/src/config/mode.ts +2 -0
- package/src/config/module.ts +240 -0
- package/src/config/output.ts +29 -0
- package/src/config/plugin.ts +6 -0
- package/src/config/resolve.ts +6 -0
- package/src/config/target.ts +28 -0
- package/src/index.ts +140 -0
- package/src/server/index.ts +0 -0
- package/tests/config.test.ts +40 -0
- package/tsconfig.json +14 -0
- package/index.js +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @rspack/core
|
|
2
|
+
|
|
3
|
+
## 0.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d466288: add process_assets hook
|
|
8
|
+
- Updated dependencies [d466288]
|
|
9
|
+
- @rspack/binding@0.0.5
|
|
10
|
+
- @rspack/dev-server@0.0.4
|
|
11
|
+
- @rspack/plugin-postcss@0.0.4
|
|
12
|
+
|
|
13
|
+
## 0.0.3
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 536f6f70: fix broken lib
|
|
18
|
+
- Updated dependencies [536f6f70]
|
|
19
|
+
- @rspack/binding@0.0.4
|
|
20
|
+
- @rspack/dev-server@0.0.3
|
|
21
|
+
- @rspack/plugin-postcss@0.0.3
|
|
22
|
+
|
|
23
|
+
## 0.0.2
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- bd57e818: first release
|
|
28
|
+
- Updated dependencies [bd57e818]
|
|
29
|
+
- @rspack/binding@0.0.2
|
|
30
|
+
- rspack-dev-server@0.0.2
|
|
31
|
+
- rspack-plugin-postcss@0.0.2
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# rspack
|
package/bin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require("./dist/bin/index");
|
package/example/basic.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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: [
|
|
11
|
+
{
|
|
12
|
+
name: "test",
|
|
13
|
+
apply(compiler) {
|
|
14
|
+
compiler.hooks.done.tap("done1", () => {
|
|
15
|
+
console.log("done1");
|
|
16
|
+
});
|
|
17
|
+
compiler.hooks.done.tap("done2", () => {
|
|
18
|
+
console.log("done2");
|
|
19
|
+
});
|
|
20
|
+
compiler.hooks.compilation.tap("compilation", compilation => {
|
|
21
|
+
compilation.hooks.processAssets.tapPromise(
|
|
22
|
+
"processAssets1",
|
|
23
|
+
async assets => {
|
|
24
|
+
for (const value of Object.values(assets)) {
|
|
25
|
+
console.log("value:", value.buffer(), value.source());
|
|
26
|
+
}
|
|
27
|
+
compilation.emitAsset("test.js", {
|
|
28
|
+
source: "hello world"
|
|
29
|
+
});
|
|
30
|
+
compilation.updateAsset("main.js", {
|
|
31
|
+
source: "hello main"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
module: {
|
|
40
|
+
rules: [
|
|
41
|
+
{
|
|
42
|
+
test: ".module.css$",
|
|
43
|
+
uses: [
|
|
44
|
+
{
|
|
45
|
+
loader: postcssLoader,
|
|
46
|
+
options: {
|
|
47
|
+
modules: true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// {
|
|
51
|
+
// loader: function testLoader(loaderContext) {
|
|
52
|
+
// // console.log(loaderContext);
|
|
53
|
+
// return {
|
|
54
|
+
// content: loaderContext.source.getBufFer(),
|
|
55
|
+
// meta: Buffer.from("something")
|
|
56
|
+
// };
|
|
57
|
+
// }
|
|
58
|
+
// }
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
async function main() {
|
|
66
|
+
const stats = await rspack.build();
|
|
67
|
+
console.log(stats);
|
|
68
|
+
// assert(stats.assets.length > 0)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
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,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rspack/core",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"publishConfig": {
|
|
7
|
-
"access": "public"
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"bin": {
|
|
5
|
+
"rspack": "./bin.js"
|
|
8
6
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
7
|
+
"main": "./lib/index.js",
|
|
8
|
+
"types": "./lib/index.d.ts",
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/node": "^18.6.3",
|
|
11
|
+
"tsm": "^2.2.2",
|
|
12
|
+
"ts-node": "10.9.1",
|
|
13
|
+
"typescript": "4.7.3",
|
|
14
|
+
"@types/ws": "8.5.3",
|
|
15
|
+
"@types/connect": "3.4.35",
|
|
16
|
+
"uvu": "0.5.6",
|
|
17
|
+
"@rspack/core": "0.0.4",
|
|
18
|
+
"@types/webpack-sources": "3.2.0"
|
|
11
19
|
},
|
|
12
|
-
"keywords": [],
|
|
13
|
-
"author": "",
|
|
14
|
-
"license": "ISC",
|
|
15
20
|
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
"@rspack/binding": "0.0.5",
|
|
22
|
+
"commander": "9.4.0",
|
|
23
|
+
"ws": "8.8.1",
|
|
24
|
+
"connect": "3.7.0",
|
|
25
|
+
"chokidar": "3.5.3",
|
|
26
|
+
"open": "8.4.0",
|
|
27
|
+
"clipanion": "3.2.0-rc.11",
|
|
28
|
+
"@rspack/dev-server": "^0.0.4",
|
|
29
|
+
"sirv": "2.0.2",
|
|
30
|
+
"@rspack/plugin-postcss": "^0.0.4",
|
|
31
|
+
"tapable": "2.2.1",
|
|
32
|
+
"webpack-sources": "3.2.3"
|
|
33
|
+
},
|
|
34
|
+
"optionalDependencies": {
|
|
35
|
+
"@tmp-sass-embedded/darwin-arm64": "1.54.4",
|
|
36
|
+
"@tmp-sass-embedded/darwin-x64": "1.54.4",
|
|
37
|
+
"@tmp-sass-embedded/linux-arm64": "1.54.4",
|
|
38
|
+
"@tmp-sass-embedded/linux-ia32": "1.54.4",
|
|
39
|
+
"@tmp-sass-embedded/linux-x64": "1.54.4",
|
|
40
|
+
"@tmp-sass-embedded/win32-ia32": "1.54.4",
|
|
41
|
+
"@tmp-sass-embedded/win32-x64": "1.54.4"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "rm -rf lib/ && tsc",
|
|
45
|
+
"dev": "tsc -w",
|
|
46
|
+
"example": "node -r ts-node/register ./example/basic.ts",
|
|
47
|
+
"test": "uvu -r tsm tests"
|
|
48
|
+
},
|
|
49
|
+
"readme": "# rspack\n"
|
|
50
|
+
}
|
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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
export interface Dev {
|
|
4
|
+
port?: number;
|
|
5
|
+
static?: {
|
|
6
|
+
directory?: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ResolvedDev {
|
|
11
|
+
port: number;
|
|
12
|
+
static: {
|
|
13
|
+
directory: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ResolveDevConfigContext {
|
|
18
|
+
context: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function resolveDevOptions(
|
|
22
|
+
devConfig: Dev = {},
|
|
23
|
+
context: ResolveDevConfigContext
|
|
24
|
+
): ResolvedDev {
|
|
25
|
+
return {
|
|
26
|
+
port: devConfig.port ?? 8080,
|
|
27
|
+
static: {
|
|
28
|
+
directory:
|
|
29
|
+
devConfig.static?.directory ?? path.resolve(context.context, "dist")
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Context, ResolvedContext } from "./context";
|
|
2
|
+
import type { Define, ResolvedDefine } from "./define";
|
|
3
|
+
import type { Dev, ResolvedDev } from "./dev";
|
|
4
|
+
import type { Entry, ResolvedEntry } from "./entry";
|
|
5
|
+
import type { External, ResolvedExternal } from "./external";
|
|
6
|
+
import type { Mode, ResolvedMode } from "./mode";
|
|
7
|
+
import type { Module, ResolvedModule } from "./module";
|
|
8
|
+
import type { Plugin } from "./plugin";
|
|
9
|
+
import type { ResolvedTarget, Target } from "./target";
|
|
10
|
+
import type { Output, ResolvedOutput } from "./output";
|
|
11
|
+
import { resolveTargetOptions } from "./target";
|
|
12
|
+
import { resolveOutputOptions } from "./output";
|
|
13
|
+
import { resolveDevOptions } from "./dev";
|
|
14
|
+
import { resolveModuleOptions } from "./module";
|
|
15
|
+
import { Builtins, ResolvedBuiltins } from "./builtins";
|
|
16
|
+
import { Resolve, ResolvedResolve } from "./resolve";
|
|
17
|
+
|
|
18
|
+
export type Asset = {
|
|
19
|
+
source: string;
|
|
20
|
+
};
|
|
21
|
+
export type Assets = Record<string, Asset>;
|
|
22
|
+
|
|
23
|
+
export interface RspackOptions {
|
|
24
|
+
entry?: Entry;
|
|
25
|
+
context?: Context;
|
|
26
|
+
plugins?: Plugin[];
|
|
27
|
+
dev?: Dev;
|
|
28
|
+
module?: Module;
|
|
29
|
+
define?: Define;
|
|
30
|
+
target?: Target;
|
|
31
|
+
mode?: Mode;
|
|
32
|
+
external?: External;
|
|
33
|
+
output?: Output;
|
|
34
|
+
builtins: Builtins;
|
|
35
|
+
resolve: Resolve;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ResolvedRspackOptions {
|
|
39
|
+
entry: ResolvedEntry;
|
|
40
|
+
context: ResolvedContext;
|
|
41
|
+
plugins: Plugin[];
|
|
42
|
+
dev: ResolvedDev;
|
|
43
|
+
module: ResolvedModule;
|
|
44
|
+
define: ResolvedDefine;
|
|
45
|
+
target: ResolvedTarget;
|
|
46
|
+
mode: ResolvedMode;
|
|
47
|
+
external: ResolvedExternal;
|
|
48
|
+
output: ResolvedOutput;
|
|
49
|
+
builtins: ResolvedBuiltins;
|
|
50
|
+
resolve: ResolvedResolve;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function resolveOptions(config: RspackOptions): ResolvedRspackOptions {
|
|
54
|
+
const context = config.context ?? process.cwd();
|
|
55
|
+
const mode = config.mode ?? "development";
|
|
56
|
+
const dev = resolveDevOptions(config.dev, { context });
|
|
57
|
+
const entry = config.entry ?? {};
|
|
58
|
+
const output = resolveOutputOptions(config.output);
|
|
59
|
+
const define = config.define ?? {};
|
|
60
|
+
const target = resolveTargetOptions(config.target);
|
|
61
|
+
const external = config.external ?? {};
|
|
62
|
+
const plugins = config.plugins ?? [];
|
|
63
|
+
const builtins = config.builtins ?? [];
|
|
64
|
+
const resolve = config.resolve ?? {};
|
|
65
|
+
const module = resolveModuleOptions(config.module);
|
|
66
|
+
return {
|
|
67
|
+
context,
|
|
68
|
+
mode,
|
|
69
|
+
dev,
|
|
70
|
+
entry,
|
|
71
|
+
output,
|
|
72
|
+
define,
|
|
73
|
+
target,
|
|
74
|
+
external,
|
|
75
|
+
plugins,
|
|
76
|
+
builtins,
|
|
77
|
+
module,
|
|
78
|
+
resolve
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import type { RawModuleRuleUse, RawModuleRule } from "@rspack/binding";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
|
|
4
|
+
export interface ModuleRule {
|
|
5
|
+
test?: RawModuleRule["test"];
|
|
6
|
+
resource?: RawModuleRule["resource"];
|
|
7
|
+
resourceQuery?: RawModuleRule["resourceQuery"];
|
|
8
|
+
uses?: ModuleRuleUse[];
|
|
9
|
+
type?: RawModuleRule["type"];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface Module {
|
|
13
|
+
rules?: ModuleRule[];
|
|
14
|
+
parser?: {
|
|
15
|
+
dataUrlCondition?: {
|
|
16
|
+
maxSize?: number;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ResolvedModuleRule {
|
|
22
|
+
test?: RawModuleRule["test"];
|
|
23
|
+
resource?: RawModuleRule["resource"];
|
|
24
|
+
resourceQuery?: RawModuleRule["resourceQuery"];
|
|
25
|
+
uses?: RawModuleRuleUse[];
|
|
26
|
+
type?: RawModuleRule["type"];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ResolvedModule {
|
|
30
|
+
rules: ResolvedModuleRule[];
|
|
31
|
+
parser?: {
|
|
32
|
+
dataUrlCondition: {
|
|
33
|
+
maxSize: number;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface LoaderContextInternal {
|
|
39
|
+
// 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.
|
|
40
|
+
source: number[];
|
|
41
|
+
resource: String;
|
|
42
|
+
resourcePath: String;
|
|
43
|
+
resourceQuery: String | null;
|
|
44
|
+
resourceFragment: String | null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface LoaderResult {
|
|
48
|
+
content: Buffer | string;
|
|
49
|
+
meta: Buffer | string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface LoaderThreadsafeResult {
|
|
53
|
+
id: number;
|
|
54
|
+
p: LoaderResultInternal | null | undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface LoaderResultInternal {
|
|
58
|
+
content: number[];
|
|
59
|
+
meta: number[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface LoaderContext
|
|
63
|
+
extends Pick<
|
|
64
|
+
LoaderContextInternal,
|
|
65
|
+
"resource" | "resourcePath" | "resourceQuery" | "resourceFragment"
|
|
66
|
+
> {
|
|
67
|
+
source: {
|
|
68
|
+
getCode(): string;
|
|
69
|
+
getBuffer(): Buffer;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const toBuffer = (bufLike: string | Buffer): Buffer => {
|
|
74
|
+
if (Buffer.isBuffer(bufLike)) {
|
|
75
|
+
return bufLike;
|
|
76
|
+
} else if (typeof bufLike === "string") {
|
|
77
|
+
return Buffer.from(bufLike);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
throw new Error("Buffer or string expected");
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
interface LoaderThreadsafeContext {
|
|
84
|
+
id: number;
|
|
85
|
+
p: LoaderContextInternal;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function composeJsUse(uses: ModuleRuleUse[]): RawModuleRuleUse | null {
|
|
89
|
+
if (!uses.length) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function loader(err: any, data: Buffer): Promise<Buffer> {
|
|
94
|
+
if (err) {
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const loaderThreadsafeContext: LoaderThreadsafeContext = JSON.parse(
|
|
99
|
+
data.toString("utf-8")
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const { p: payload, id } = loaderThreadsafeContext;
|
|
103
|
+
|
|
104
|
+
const loaderContextInternal: LoaderContextInternal = {
|
|
105
|
+
source: payload.source,
|
|
106
|
+
resourcePath: payload.resourcePath,
|
|
107
|
+
resourceQuery: payload.resourceQuery,
|
|
108
|
+
resource: payload.resource,
|
|
109
|
+
resourceFragment: payload.resourceFragment
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
let sourceBuffer = Buffer.from(loaderContextInternal.source);
|
|
113
|
+
let meta = Buffer.from("");
|
|
114
|
+
// Loader is executed from right to left
|
|
115
|
+
for (const use of uses) {
|
|
116
|
+
assert("loader" in use);
|
|
117
|
+
const loaderContext = {
|
|
118
|
+
...loaderContextInternal,
|
|
119
|
+
source: {
|
|
120
|
+
getCode(): string {
|
|
121
|
+
return sourceBuffer.toString("utf-8");
|
|
122
|
+
},
|
|
123
|
+
getBuffer(): Buffer {
|
|
124
|
+
return sourceBuffer;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
getOptions() {
|
|
128
|
+
return use.options;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
let loaderResult: LoaderResult;
|
|
133
|
+
if (
|
|
134
|
+
(loaderResult = await Promise.resolve().then(() =>
|
|
135
|
+
use.loader.apply(loaderContext, [loaderContext])
|
|
136
|
+
))
|
|
137
|
+
) {
|
|
138
|
+
const content = loaderResult.content;
|
|
139
|
+
meta = meta.length > 0 ? meta : toBuffer(loaderResult.meta);
|
|
140
|
+
sourceBuffer = toBuffer(content);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const loaderResultPayload: LoaderResultInternal = {
|
|
145
|
+
content: [...sourceBuffer],
|
|
146
|
+
meta: [...meta]
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const loaderThreadsafeResult: LoaderThreadsafeResult = {
|
|
150
|
+
id: id,
|
|
151
|
+
p: loaderResultPayload
|
|
152
|
+
};
|
|
153
|
+
return Buffer.from(JSON.stringify(loaderThreadsafeResult), "utf-8");
|
|
154
|
+
}
|
|
155
|
+
loader.displayName = `NodeLoaderAdapter(${uses
|
|
156
|
+
.map(item => {
|
|
157
|
+
assert("loader" in item);
|
|
158
|
+
return item.loader.displayName || item.loader.name || "unknown-loader";
|
|
159
|
+
})
|
|
160
|
+
.join(" -> ")})`;
|
|
161
|
+
return {
|
|
162
|
+
loader
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
interface JsLoader {
|
|
167
|
+
(this: LoaderContext, loaderContext: LoaderContext):
|
|
168
|
+
| Promise<LoaderResult | void>
|
|
169
|
+
| LoaderResult
|
|
170
|
+
| void;
|
|
171
|
+
displayName?: string;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
type BuiltinLoader = string;
|
|
175
|
+
|
|
176
|
+
type ModuleRuleUse =
|
|
177
|
+
| {
|
|
178
|
+
builtinLoader: BuiltinLoader;
|
|
179
|
+
options?: unknown;
|
|
180
|
+
}
|
|
181
|
+
| {
|
|
182
|
+
loader: JsLoader;
|
|
183
|
+
options?: unknown;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export function createRawModuleRuleUses(
|
|
187
|
+
uses: ModuleRuleUse[]
|
|
188
|
+
): RawModuleRuleUse[] {
|
|
189
|
+
return createRawModuleRuleUsesImpl([...uses].reverse());
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function createRawModuleRuleUsesImpl(
|
|
193
|
+
uses: ModuleRuleUse[]
|
|
194
|
+
): RawModuleRuleUse[] {
|
|
195
|
+
if (!uses.length) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const index = uses.findIndex(use => "builtinLoader" in use);
|
|
200
|
+
if (index < 0) {
|
|
201
|
+
return [composeJsUse(uses)];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const before = uses.slice(0, index);
|
|
205
|
+
const after = uses.slice(index + 1);
|
|
206
|
+
return [
|
|
207
|
+
composeJsUse(before),
|
|
208
|
+
createNativeUse(uses[index]),
|
|
209
|
+
...createRawModuleRuleUsesImpl(after)
|
|
210
|
+
].filter((item): item is RawModuleRuleUse => Boolean(item));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function createNativeUse(use: ModuleRuleUse): RawModuleRuleUse {
|
|
214
|
+
assert("builtinLoader" in use);
|
|
215
|
+
|
|
216
|
+
if (use.builtinLoader === "sass-loader") {
|
|
217
|
+
(use.options ??= {} as any).__exePath = require.resolve(
|
|
218
|
+
`@tmp-sass-embedded/${process.platform}-${
|
|
219
|
+
process.arch
|
|
220
|
+
}/dart-sass-embedded/dart-sass-embedded${
|
|
221
|
+
process.platform === "win32" ? ".bat" : ""
|
|
222
|
+
}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
builtinLoader: use.builtinLoader,
|
|
228
|
+
options: JSON.stringify(use.options)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function resolveModuleOptions(module: Module = {}): ResolvedModule {
|
|
233
|
+
const rules = (module.rules ?? []).map(rule => ({
|
|
234
|
+
...rule,
|
|
235
|
+
uses: createRawModuleRuleUses(rule.uses || [])
|
|
236
|
+
}));
|
|
237
|
+
return {
|
|
238
|
+
rules
|
|
239
|
+
};
|
|
240
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface Output {
|
|
2
|
+
path?: string;
|
|
3
|
+
publicPath?: string;
|
|
4
|
+
assetModuleFilename?: string;
|
|
5
|
+
filename?: string;
|
|
6
|
+
chunkFilename?: string;
|
|
7
|
+
uniqueName?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// TODO: fix it
|
|
11
|
+
export interface ResolvedOutput {
|
|
12
|
+
path?: string;
|
|
13
|
+
publicPath?: string;
|
|
14
|
+
assetModuleFilename?: string;
|
|
15
|
+
filename?: string;
|
|
16
|
+
chunkFilename?: string;
|
|
17
|
+
uniqueName?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolveOutputOptions(output: Output = {}): ResolvedOutput {
|
|
21
|
+
return {
|
|
22
|
+
path: output.path,
|
|
23
|
+
publicPath: output.publicPath,
|
|
24
|
+
chunkFilename: output.chunkFilename,
|
|
25
|
+
filename: output.publicPath,
|
|
26
|
+
assetModuleFilename: output.assetModuleFilename,
|
|
27
|
+
uniqueName: output.uniqueName
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type TargetItem =
|
|
2
|
+
| "web"
|
|
3
|
+
| "webworker"
|
|
4
|
+
| "browserslist"
|
|
5
|
+
| "es3"
|
|
6
|
+
| "es5"
|
|
7
|
+
| "es2015"
|
|
8
|
+
| "es2016"
|
|
9
|
+
| "es2017"
|
|
10
|
+
| "es2018"
|
|
11
|
+
| "es2019"
|
|
12
|
+
| "es2020"
|
|
13
|
+
| "es2021"
|
|
14
|
+
| "es2022";
|
|
15
|
+
|
|
16
|
+
export type Target = TargetItem | TargetItem[] | false;
|
|
17
|
+
export type ResolvedTarget = TargetItem[];
|
|
18
|
+
|
|
19
|
+
export function resolveTargetOptions(target: Target = "web"): ResolvedTarget {
|
|
20
|
+
if (!target) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(target)) {
|
|
24
|
+
return [target];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return target;
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export * from "./build";
|
|
2
|
+
import * as binding from "@rspack/binding";
|
|
3
|
+
import type { ExternalObject, RspackInternal } from "@rspack/binding";
|
|
4
|
+
import * as tapable from "tapable";
|
|
5
|
+
import {
|
|
6
|
+
RspackOptions,
|
|
7
|
+
ResolvedRspackOptions,
|
|
8
|
+
Assets,
|
|
9
|
+
Asset,
|
|
10
|
+
resolveOptions
|
|
11
|
+
} from "./config";
|
|
12
|
+
|
|
13
|
+
import { RawSource, Source } from "webpack-sources";
|
|
14
|
+
interface RspackThreadsafeContext<T> {
|
|
15
|
+
readonly id: number;
|
|
16
|
+
readonly inner: T;
|
|
17
|
+
}
|
|
18
|
+
interface RspackThreadsafeResult<T> {
|
|
19
|
+
readonly id: number;
|
|
20
|
+
readonly inner: T;
|
|
21
|
+
}
|
|
22
|
+
const createDummyResult = (id: number): string => {
|
|
23
|
+
const result: RspackThreadsafeResult<null> = {
|
|
24
|
+
id,
|
|
25
|
+
inner: null
|
|
26
|
+
};
|
|
27
|
+
return JSON.stringify(result);
|
|
28
|
+
};
|
|
29
|
+
type EmitAssetCallback = (options: { filename: string; asset: Asset }) => void;
|
|
30
|
+
class RspackCompilation {
|
|
31
|
+
#emitAssetCallback: EmitAssetCallback;
|
|
32
|
+
hooks: {
|
|
33
|
+
processAssets: tapable.AsyncSeriesHook<Record<string, Source>>;
|
|
34
|
+
};
|
|
35
|
+
constructor() {
|
|
36
|
+
this.hooks = {
|
|
37
|
+
processAssets: new tapable.AsyncSeriesHook<Record<string, Source>>([
|
|
38
|
+
"assets"
|
|
39
|
+
])
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* unsafe to call out of processAssets
|
|
44
|
+
* @param filename
|
|
45
|
+
* @param asset
|
|
46
|
+
*/
|
|
47
|
+
updateAsset(filename: string, asset: Asset) {
|
|
48
|
+
this.emitAsset(filename, asset);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* unsafe to call out of processAssets
|
|
52
|
+
* @param filename
|
|
53
|
+
* @param asset
|
|
54
|
+
*/
|
|
55
|
+
emitAsset(filename: string, asset: Asset) {
|
|
56
|
+
if (!this.#emitAssetCallback) {
|
|
57
|
+
throw new Error("can't call emitAsset outof processAssets hook for now");
|
|
58
|
+
}
|
|
59
|
+
this.#emitAssetCallback({
|
|
60
|
+
filename: filename,
|
|
61
|
+
asset
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async processAssets(err: Error, value: string, emitAsset: any) {
|
|
65
|
+
this.#emitAssetCallback = emitAsset;
|
|
66
|
+
if (err) {
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
const context: RspackThreadsafeContext<
|
|
70
|
+
Record<string, { source: string | Buffer }>
|
|
71
|
+
> = JSON.parse(value);
|
|
72
|
+
let content: Record<string, { source: string | Buffer }> =
|
|
73
|
+
context.inner ?? {};
|
|
74
|
+
let assets = {};
|
|
75
|
+
for (const [key, value] of Object.entries(content)) {
|
|
76
|
+
// webpack-sources's type definition is wrong, it actually could accept Buffer type
|
|
77
|
+
let source = value.source;
|
|
78
|
+
if (Array.isArray(value.source)) {
|
|
79
|
+
source = Buffer.from(value.source);
|
|
80
|
+
}
|
|
81
|
+
assets[key] = new RawSource(source as string);
|
|
82
|
+
}
|
|
83
|
+
await this.hooks.processAssets.promise(assets);
|
|
84
|
+
return createDummyResult(context.id);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class Rspack {
|
|
88
|
+
#plugins: RspackOptions["plugins"];
|
|
89
|
+
#instance: ExternalObject<RspackInternal>;
|
|
90
|
+
compilation: RspackCompilation;
|
|
91
|
+
hooks: {
|
|
92
|
+
done: tapable.AsyncSeriesHook<void>;
|
|
93
|
+
compilation: tapable.SyncHook<RspackCompilation>;
|
|
94
|
+
};
|
|
95
|
+
options: ResolvedRspackOptions;
|
|
96
|
+
constructor(options: RspackOptions) {
|
|
97
|
+
this.options = resolveOptions(options);
|
|
98
|
+
// @ts-ignored
|
|
99
|
+
this.#instance = binding.newRspack(this.options, {
|
|
100
|
+
doneCallback: this.#done.bind(this),
|
|
101
|
+
processAssetsCallback: this.#processAssets.bind(this)
|
|
102
|
+
});
|
|
103
|
+
this.hooks = {
|
|
104
|
+
done: new tapable.AsyncSeriesHook<void>(),
|
|
105
|
+
compilation: new tapable.SyncHook<RspackCompilation>(["compilation"])
|
|
106
|
+
};
|
|
107
|
+
this.#plugins = options.plugins ?? [];
|
|
108
|
+
for (const plugin of this.#plugins) {
|
|
109
|
+
plugin.apply(this);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async #done(err: Error, value: string) {
|
|
113
|
+
if (err) {
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
const context: RspackThreadsafeContext<void> = JSON.parse(value);
|
|
117
|
+
await this.hooks.done.promise();
|
|
118
|
+
return createDummyResult(context.id);
|
|
119
|
+
}
|
|
120
|
+
async #processAssets(err: Error, value: string, emitAsset: any) {
|
|
121
|
+
return this.compilation.processAssets(err, value, emitAsset);
|
|
122
|
+
}
|
|
123
|
+
#newCompilation() {
|
|
124
|
+
const compilation = new RspackCompilation();
|
|
125
|
+
this.compilation = compilation;
|
|
126
|
+
this.hooks.compilation.call(compilation);
|
|
127
|
+
return compilation;
|
|
128
|
+
}
|
|
129
|
+
async build() {
|
|
130
|
+
const compilation = this.#newCompilation();
|
|
131
|
+
const stats = await binding.build(this.#instance);
|
|
132
|
+
return stats;
|
|
133
|
+
}
|
|
134
|
+
async rebuild(changeFiles: string[]) {
|
|
135
|
+
const stats = await binding.rebuild(this.#instance, changeFiles);
|
|
136
|
+
return stats;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export { Rspack };
|
|
140
|
+
export default Rspack;
|
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { test } from "uvu";
|
|
2
|
+
import * as assert from "uvu/assert";
|
|
3
|
+
import { Rspack } from "@rspack/core";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
test("default config snapshot", () => {
|
|
7
|
+
const resolvedOptions = new Rspack({}).options;
|
|
8
|
+
|
|
9
|
+
assert.equal(resolvedOptions.context, process.cwd());
|
|
10
|
+
assert.equal(
|
|
11
|
+
resolvedOptions.dev.static.directory,
|
|
12
|
+
path.resolve(process.cwd(), "./dist")
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
// TypeScript will throw `The operand of a 'delete' operator must be optional`.
|
|
16
|
+
// But we remove these configurations with absolute paths.
|
|
17
|
+
// @ts-expect-error
|
|
18
|
+
delete resolvedOptions.context;
|
|
19
|
+
// @ts-expect-error
|
|
20
|
+
delete resolvedOptions.dev.static.directory;
|
|
21
|
+
|
|
22
|
+
assert.snapshot(
|
|
23
|
+
JSON.stringify(resolvedOptions),
|
|
24
|
+
JSON.stringify({
|
|
25
|
+
mode: "development",
|
|
26
|
+
dev: { port: 8080, static: {} },
|
|
27
|
+
entry: {},
|
|
28
|
+
output: {},
|
|
29
|
+
define: {},
|
|
30
|
+
target: ["web"],
|
|
31
|
+
external: {},
|
|
32
|
+
plugins: [],
|
|
33
|
+
builtins: [],
|
|
34
|
+
module: { rules: [] },
|
|
35
|
+
resolve: {}
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test.run();
|
package/tsconfig.json
ADDED
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {}
|