@crossbind/plugin-webpack 2.0.0-beta.50
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/AGENTS.md +89 -0
- package/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/index.js +176 -0
- package/package.json +26 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# AGENTS.md — @crossbind/plugin-webpack
|
|
2
|
+
|
|
3
|
+
> Webpack **and Rspack** integration plugin. Same package serves both — Rspack reuses the Webpack plugin contract.
|
|
4
|
+
|
|
5
|
+
## What lives here
|
|
6
|
+
|
|
7
|
+
- `index.js` — exports `class CrossbindWebpackPlugin`. Single class, no separate kernel.
|
|
8
|
+
- Sibling package `@crossbind/plugin-webpack-loader` ships the loader for `.h` files; `getRule()` references it by name.
|
|
9
|
+
|
|
10
|
+
## Class API surface
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
new CrossbindWebpackPlugin()
|
|
14
|
+
↓
|
|
15
|
+
.apply(compiler) ← webpack standard plugin hook
|
|
16
|
+
.getRule() ← module.rules entry for .h
|
|
17
|
+
.getDevServerConfig() ← devServer block w/ COOP+COEP + middleware
|
|
18
|
+
.getLoaderOptions() ← escape hatch: crossbind state passed to other rules
|
|
19
|
+
.setDevServerMiddleware(...) ← internal, called by getDevServerConfig
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
User config consumes all four; see `docs/playbooks/integration/webpack-rspack.md` for the canonical wiring.
|
|
23
|
+
|
|
24
|
+
## Hooks the plugin registers
|
|
25
|
+
|
|
26
|
+
| webpack hook | What it does |
|
|
27
|
+
|--------------|--------------|
|
|
28
|
+
| `compiler.hooks.done` | After every compilation: re-run `createLib + createXCFramework + buildWasm` (mtime-aware via `isSourceNewer`) |
|
|
29
|
+
| `compiler.hooks.afterCompile` | Adds `state.config.paths.native` to `compilation.contextDependencies` so webpack watch picks up `.cpp`/`.h` edits |
|
|
30
|
+
|
|
31
|
+
## DevServer middleware
|
|
32
|
+
|
|
33
|
+
`getDevServerConfig()` returns:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
{
|
|
37
|
+
watchFiles: state.config.paths.native,
|
|
38
|
+
hot: true,
|
|
39
|
+
liveReload: true,
|
|
40
|
+
headers: {
|
|
41
|
+
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
42
|
+
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
43
|
+
},
|
|
44
|
+
setupMiddlewares: (middlewares, devServer) => { ... }
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The middleware adds `/crossbind.js` and `/crossbind.wasm` routes that pipe the freshly built artifacts. Both routes also re-emit COOP/COEP per-response (belt-and-suspenders for caching layers that strip top-level headers).
|
|
49
|
+
|
|
50
|
+
## Rspack compatibility
|
|
51
|
+
|
|
52
|
+
Rspack copies webpack's plugin / loader shape. The plugin works without modification. The Rspack-specific wrinkle: `getRule()` returns a plain object that Rspack's TypeScript-strict config types may complain about — cast to `RspackOptions['module']['rules'][number]` if needed.
|
|
53
|
+
|
|
54
|
+
## Common pitfalls
|
|
55
|
+
|
|
56
|
+
- **Forgetting `getRule()` while passing the plugin instance.** The `.h` loader rule and the plugin instance are independent registrations; both are required.
|
|
57
|
+
- **Wrapping the plugin's `getDevServerConfig()` and dropping `headers`.** Always spread: `{ ...cppDev, ...custom, headers: { ...cppDev.headers, ...custom.headers } }`.
|
|
58
|
+
- **Trying to inject `getRule()` into `plugins:` array** instead of `module.rules:`. They are distinct.
|
|
59
|
+
- **Babel/SWC running on `.h` first.** Loader chain order matters; `getRule()` test is `/\.h$/` so other rules with broader tests can swallow it. Make sure no rule for `/\.[jt]sx?$/` accidentally matches `.h` (none do by default).
|
|
60
|
+
- **Adding `console.log` for debugging.** Route through `crossbind` exports — `state.config` carries the logger if you need it. Plugin output should be quiet by default.
|
|
61
|
+
|
|
62
|
+
## Validation
|
|
63
|
+
|
|
64
|
+
Strict gate:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm run ci:linux:build && pnpm run e2e:dev && pnpm run e2e:prod
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Smoke samples:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm --filter=@crossbind/example-web-react-rspack run build
|
|
74
|
+
pnpm --filter=@crossbind/e2e-web-rspack run build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If you touch the dev-server middleware, also test:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pnpm --filter=@crossbind/example-web-react-rspack exec rspack serve
|
|
81
|
+
# verify in browser: COOP/COEP headers present, /crossbind.wasm 200
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Reference
|
|
85
|
+
|
|
86
|
+
- Loader package: `plugins/webpack-loader/`
|
|
87
|
+
- Integration recipe: `docs/playbooks/integration/webpack-rspack.md`
|
|
88
|
+
- Next.js variant (no devServer): `docs/playbooks/integration/nextjs.md`
|
|
89
|
+
- Canonical samples: `examples/web-react-rspack`, `e2e/web-rspack`
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @crossbind/plugin-webpack
|
|
2
|
+
|
|
3
|
+
## 2.0.0-beta.50
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- A cargo dependency no longer has to be built by hand before the app. The dependency step this
|
|
8
|
+
plugin already awaits builds one whose target is missing, and refuses to link one it could not
|
|
9
|
+
build — on wasm that case used to pass silently and leave a module that died at init.
|
|
10
|
+
|
|
11
|
+
## 1.0.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- crossbind@1.0.4
|
|
17
|
+
|
|
18
|
+
## 1.0.0
|
|
19
|
+
|
|
20
|
+
### Major Changes
|
|
21
|
+
|
|
22
|
+
- 🚀 first stable release
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- crossbind@1.0.0
|
|
28
|
+
|
|
29
|
+
## 1.0.0-beta.10
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- chore: add initial version of CHANGELOGS files
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
- crossbind@1.0.0-beta.33
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Buğra Sarı and crossbind contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# @crossbind/plugin-webpack
|
|
2
|
+
**crossbind Webpack plugin**
|
|
3
|
+
A tool for seamless C++ integration with the Webpack bundler.
|
|
4
|
+
|
|
5
|
+
<a href="https://www.npmjs.com/package/@crossbind/plugin-webpack">
|
|
6
|
+
<img alt="NPM version" src="https://img.shields.io/npm/v/@crossbind/plugin-webpack?style=for-the-badge" />
|
|
7
|
+
</a>
|
|
8
|
+
<a href="https://github.com/crossbind/crossbind/blob/main/LICENSE">
|
|
9
|
+
<img alt="License" src="https://img.shields.io/github/license/crossbind/crossbind?style=for-the-badge" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://crossbind.js.org/docs/guide/integrate-into-existing-project/webpack">
|
|
12
|
+
<img alt="Docs - React Native" src="https://img.shields.io/badge/Docs_-_Webpack-20B2AA?style=for-the-badge" />
|
|
13
|
+
</a>
|
|
14
|
+
|
|
15
|
+
## Integration
|
|
16
|
+
To integrate crossbind into your project using Webpack as a bundler, you can utilize the @crossbind/plugin-webpack plugin. Start by installing these package with the following command:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @crossbind/plugin-webpack @crossbind/plugin-webpack-loader --save-dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Webpack**
|
|
23
|
+
To enable the plugin, modify the `webpack.config.js` file as shown below.
|
|
24
|
+
|
|
25
|
+
```diff
|
|
26
|
+
+ const CrossbindWebpackPlugin = require('@crossbind/plugin-webpack');
|
|
27
|
+
+ const crossbindWebpackPlugin = new CrossbindWebpackPlugin();
|
|
28
|
+
+ const compiler = crossbindWebpackPlugin.getCompiler();
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
//...
|
|
32
|
+
plugins: [
|
|
33
|
+
+ crossbindWebpackPlugin,
|
|
34
|
+
],
|
|
35
|
+
module: {
|
|
36
|
+
rules: [
|
|
37
|
+
+ {
|
|
38
|
+
+ test: /\.h$/,
|
|
39
|
+
+ loader: '@crossbind/plugin-webpack-loader',
|
|
40
|
+
+ options: { compiler },
|
|
41
|
+
+ }
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Rspack**
|
|
48
|
+
To enable the plugin, modify the `rspack.config.mjs` file as shown below.
|
|
49
|
+
|
|
50
|
+
```diff
|
|
51
|
+
+ import CrossbindWebpackPlugin from '@crossbind/plugin-webpack';
|
|
52
|
+
|
|
53
|
+
+ const crossbindWebpackPlugin = new CrossbindWebpackPlugin();
|
|
54
|
+
+ const compiler = crossbindWebpackPlugin.getCompiler();
|
|
55
|
+
|
|
56
|
+
export default defineConfig({
|
|
57
|
+
module: {
|
|
58
|
+
rules: [
|
|
59
|
+
+ {
|
|
60
|
+
+ test: /\.h$/,
|
|
61
|
+
+ loader: '@crossbind/plugin-webpack-loader',
|
|
62
|
+
+ options: { compiler },
|
|
63
|
+
+ }
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
plugins: [
|
|
67
|
+
+ crossbindWebpackPlugin,
|
|
68
|
+
].filter(Boolean),
|
|
69
|
+
+ devServer: {
|
|
70
|
+
+ watchFiles: compiler.config.paths.native,
|
|
71
|
+
+ setupMiddlewares: (middlewares, devServer) => {
|
|
72
|
+
+ if (!devServer) {
|
|
73
|
+
+ throw new Error('@rspack/dev-server is not defined');
|
|
74
|
+
+ }
|
|
75
|
+
+
|
|
76
|
+
+ middlewares.unshift({
|
|
77
|
+
+ name: '/crossbind.js',
|
|
78
|
+
+ path: '/crossbind.js',
|
|
79
|
+
+ middleware: (req, res) => {
|
|
80
|
+
+ res.sendFile(`${compiler.config.paths.temp}/${compiler.config.general.name}.browser.js`);
|
|
81
|
+
+ },
|
|
82
|
+
+ });
|
|
83
|
+
+ middlewares.unshift({
|
|
84
|
+
+ name: '/crossbind.wasm',
|
|
85
|
+
+ path: '/crossbind.wasm',
|
|
86
|
+
+ middleware: (req, res) => {
|
|
87
|
+
+ res.send(fs.readFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`));
|
|
88
|
+
+ },
|
|
89
|
+
+ });
|
|
90
|
+
+
|
|
91
|
+
+ return middlewares;
|
|
92
|
+
+ },
|
|
93
|
+
+ },
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Craco**
|
|
98
|
+
To enable the plugin, create the `craco.config.js` file as shown below.
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
const fs = require('fs');
|
|
102
|
+
|
|
103
|
+
module.exports = async function () {
|
|
104
|
+
const { default: CrossbindWebpackPlugin } = await import('@crossbind/plugin-webpack');
|
|
105
|
+
const crossbindWebpackPlugin = new CrossbindWebpackPlugin();
|
|
106
|
+
const compiler = crossbindWebpackPlugin.getCompiler();
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
webpack: {
|
|
110
|
+
plugins: {
|
|
111
|
+
add: [crossbindWebpackPlugin],
|
|
112
|
+
},
|
|
113
|
+
configure: (config) => {
|
|
114
|
+
config.module.rules[1].oneOf = [
|
|
115
|
+
{
|
|
116
|
+
test: /\.h$/,
|
|
117
|
+
loader: '@crossbind/plugin-webpack-loader',
|
|
118
|
+
options: { compiler },
|
|
119
|
+
},
|
|
120
|
+
...config.module.rules[1].oneOf,
|
|
121
|
+
];
|
|
122
|
+
return config;
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
devServer: (devServerConfig) => {
|
|
126
|
+
devServerConfig.watchFiles = compiler.config.paths.native;
|
|
127
|
+
devServerConfig.onBeforeSetupMiddleware = (devServer) => {
|
|
128
|
+
if (!devServer) {
|
|
129
|
+
throw new Error('webpack-dev-server is not defined');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
devServer.app.get('/crossbind.js', function (req, res) {
|
|
133
|
+
res.sendFile(`${compiler.config.paths.temp}/${compiler.config.general.name}.browser.js`);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
devServer.app.get('/crossbind.wasm', function (req, res) {
|
|
137
|
+
res.send(fs.readFileSync(`${compiler.config.paths.temp}/${compiler.config.general.name}.wasm`));
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return devServerConfig;
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
```
|
package/index.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import {
|
|
5
|
+
state, createLib, buildWasm, createBridgeFile, getData, getCrossbindScript, getRustJsScript, getDependFilePath, buildDependencies, getTargetParams, getFilteredBuildTargets, isSourceNewer,
|
|
6
|
+
} from 'crossbind';
|
|
7
|
+
|
|
8
|
+
const targetParams = getTargetParams({ platform: ['wasm'], arch: ['wasm32'], runtime: ['st'], runtimeEnv: ['browser'] }, true);
|
|
9
|
+
let buildTargetRelease = getFilteredBuildTargets(targetParams, { buildType: 'release' })?.[0];
|
|
10
|
+
let buildTargetDebug = getFilteredBuildTargets(targetParams, { buildType: 'debug' })?.[0];
|
|
11
|
+
|
|
12
|
+
if (!buildTargetRelease && !buildTargetDebug) {
|
|
13
|
+
throw new Error('No build targets found');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!buildTargetDebug) {
|
|
17
|
+
buildTargetDebug = buildTargetRelease;
|
|
18
|
+
} else if (!buildTargetRelease) {
|
|
19
|
+
buildTargetRelease = buildTargetDebug;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default class CrossbindWebpackPlugin {
|
|
23
|
+
static defaultOptions = {};
|
|
24
|
+
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.options = { ...CrossbindWebpackPlugin.defaultOptions, ...options };
|
|
27
|
+
this.bridges = [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
apply(compiler) {
|
|
31
|
+
const pluginName = this.constructor.name;
|
|
32
|
+
compiler.options.resolve = compiler.options.resolve || {};
|
|
33
|
+
compiler.options.resolve.alias = compiler.options.resolve.alias || {};
|
|
34
|
+
// `cargo:` imports use the node:/npm: convention for a non-npm store; webpack's resolver
|
|
35
|
+
// has no such scheme, so the request is rewritten to the generated marker .rs (which the
|
|
36
|
+
// loader then turns into the crate-import bridge). Works on rspack via its compat layer.
|
|
37
|
+
new compiler.webpack.NormalModuleReplacementPlugin(/^cargo:/, (resource) => {
|
|
38
|
+
const marker = getDependFilePath(resource.request, buildTargetRelease);
|
|
39
|
+
if (marker) resource.request = marker;
|
|
40
|
+
}).apply(compiler);
|
|
41
|
+
// Rust packages ship no JS entry at all (their package.json is just a name), so node
|
|
42
|
+
// resolution can never find them. Each known cargo-type dependency gets an exact-match
|
|
43
|
+
// alias onto its crate root; the loader's .rs branch turns that into the proxy module.
|
|
44
|
+
for (const dep of state.config.allDependencies ?? []) {
|
|
45
|
+
if (dep.export?.type !== 'cargo' || !dep.package?.name) continue;
|
|
46
|
+
const libRs = path.resolve(dep.paths.project, dep.export.crate ?? 'crate', 'src/lib.rs');
|
|
47
|
+
if (fs.existsSync(libRs) && !(`${dep.package.name}$` in compiler.options.resolve.alias)) {
|
|
48
|
+
compiler.options.resolve.alias[`${dep.package.name}$`] = libRs;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// tapPromise (not tap) so webpack awaits the native C++/wasm build and a build
|
|
52
|
+
// failure surfaces as a compilation error instead of an unhandled rejection.
|
|
53
|
+
compiler.hooks.done.tapPromise(pluginName, this.onDone.bind(this));
|
|
54
|
+
compiler.hooks.afterCompile.tapAsync(pluginName, this.afterCompile.bind(this));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
afterCompile(compilation, callback) {
|
|
58
|
+
state.config.paths.native.map((file) => compilation.contextDependencies.add(file));
|
|
59
|
+
callback();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async onDone({ compilation }) {
|
|
63
|
+
const isDev = compilation.options.mode === 'development';
|
|
64
|
+
const buildTarget = isDev ? buildTargetDebug : buildTargetRelease;
|
|
65
|
+
await buildDependencies({ targetParams: { ...targetParams, buildType: [buildTarget.buildType] } });
|
|
66
|
+
const force = isSourceNewer(buildTarget);
|
|
67
|
+
const sourceBuilt = createLib(buildTarget, 'Source', { force, buildSource: true });
|
|
68
|
+
// Bridge cache is keyed on the nativeGlob fingerprint: a changed bridge
|
|
69
|
+
// set rebuilds the lib even without source changes, and a rebuilt lib
|
|
70
|
+
// must force the final link too.
|
|
71
|
+
const bridgeBuilt = createLib(buildTarget, 'Bridge', { force, buildSource: false, nativeGlob: [`${state.config.paths.cli}/assets/cpp-runtime/commonBridges.cpp`, ...this.bridges] });
|
|
72
|
+
await buildWasm(buildTarget, { force: force || Boolean(sourceBuilt) || Boolean(bridgeBuilt) });
|
|
73
|
+
if (!isDev) {
|
|
74
|
+
const output = state.config.paths.output === state.config.paths.build ? compilation.options.output.path : state.config.paths.output;
|
|
75
|
+
// On a first-ever build the output dir may not exist yet when this
|
|
76
|
+
// hook runs; copyFileSync reports that as ENOENT too.
|
|
77
|
+
fs.mkdirSync(output, { recursive: true });
|
|
78
|
+
fs.copyFileSync(`${state.config.paths.build}/${buildTarget.jsName}`, `${output}/crossbind.js`);
|
|
79
|
+
fs.copyFileSync(`${state.config.paths.build}/${buildTarget.wasmName}`, `${output}/crossbind.wasm`);
|
|
80
|
+
|
|
81
|
+
const dataFilePath = `${state.config.paths.build}/${buildTarget.dataTxtName}`;
|
|
82
|
+
if (fs.existsSync(dataFilePath)) {
|
|
83
|
+
fs.copyFileSync(dataFilePath, `${output}/crossbind.data.txt`);
|
|
84
|
+
}
|
|
85
|
+
/* const workerFilePath = `${state.config.paths.build}/${state.config.general.name}.js`;
|
|
86
|
+
if (fs.existsSync(workerFilePath)) {
|
|
87
|
+
fs.copyFileSync(workerFilePath, `${output}/cpp.worker.js`);
|
|
88
|
+
} */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getLoaderOptions() {
|
|
93
|
+
return {
|
|
94
|
+
bridges: this.bridges,
|
|
95
|
+
createBridgeFile,
|
|
96
|
+
getData,
|
|
97
|
+
state,
|
|
98
|
+
getCrossbindScript,
|
|
99
|
+
getRustJsScript,
|
|
100
|
+
getTargetParams,
|
|
101
|
+
getFilteredBuildTargets
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
getRule() {
|
|
106
|
+
return {
|
|
107
|
+
// `rs` rides the same rule: the loader branches on the extension.
|
|
108
|
+
test: new RegExp(`\\.(${[...state.config.ext.header, 'rs'].join('|')})$`),
|
|
109
|
+
loader: '@crossbind/plugin-webpack-loader',
|
|
110
|
+
options: { ...this.getLoaderOptions() },
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
setDevServerMiddleware(middlewares, devServer) {
|
|
115
|
+
if (!devServer) {
|
|
116
|
+
throw new Error('devServer is not defined');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
middlewares.unshift({
|
|
120
|
+
name: '/crossbind.js',
|
|
121
|
+
path: '/crossbind.js',
|
|
122
|
+
middleware: (req, res) => {
|
|
123
|
+
const filePath = `${state.config.paths.build}/${buildTargetDebug.jsName}`;
|
|
124
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
125
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
126
|
+
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
127
|
+
fs.createReadStream(filePath).pipe(res);
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
middlewares.unshift({
|
|
132
|
+
name: '/crossbind.wasm',
|
|
133
|
+
path: '/crossbind.wasm',
|
|
134
|
+
middleware: (req, res) => {
|
|
135
|
+
const filePath = `${state.config.paths.build}/${buildTargetDebug.wasmName}`;
|
|
136
|
+
res.setHeader('Content-Type', 'application/wasm');
|
|
137
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
138
|
+
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
139
|
+
fs.createReadStream(filePath).pipe(res);
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
middlewares.unshift({
|
|
144
|
+
name: '/crossbind.data.txt',
|
|
145
|
+
path: '/crossbind.data.txt',
|
|
146
|
+
middleware: (req, res) => {
|
|
147
|
+
const filePath = `${state.config.paths.build}/${buildTargetDebug.dataTxtName}`;
|
|
148
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
149
|
+
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
150
|
+
if (!fs.existsSync(filePath)) {
|
|
151
|
+
res.statusCode = 404;
|
|
152
|
+
res.end();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
fs.createReadStream(filePath).pipe(res);
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return middlewares;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
getDevServerConfig() {
|
|
163
|
+
return {
|
|
164
|
+
watchFiles: state.config.paths.native,
|
|
165
|
+
hot: true,
|
|
166
|
+
liveReload: true,
|
|
167
|
+
headers: {
|
|
168
|
+
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
169
|
+
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
170
|
+
},
|
|
171
|
+
setupMiddlewares: (middlewares, devServer) => {
|
|
172
|
+
return this.setDevServerMiddleware(middlewares, devServer);
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crossbind/plugin-webpack",
|
|
3
|
+
"version": "2.0.0-beta.50",
|
|
4
|
+
"description": "crossbind Webpack plugin: A tool for seamless C++ integration with the Webpack bundler.",
|
|
5
|
+
"homepage": "https://github.com/crossbind/crossbind/tree/main/plugins/webpack#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/crossbind/crossbind.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "index.js",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"crossbind": "^2.0.0-beta.50",
|
|
15
|
+
"@crossbind/core-embind-rust": "^2.0.0-beta.50"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"webpack": ">=5.109.2"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"crossbind-plugin",
|
|
22
|
+
"webpack",
|
|
23
|
+
"bind",
|
|
24
|
+
"c++"
|
|
25
|
+
]
|
|
26
|
+
}
|