@crossbind/plugin-webpack 2.0.0-beta.62 → 2.0.0-beta.64

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.
Files changed (3) hide show
  1. package/README.md +20 -101
  2. package/index.js +29 -8
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -3,29 +3,28 @@
3
3
  A tool for seamless C++ integration with the Webpack bundler.
4
4
 
5
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" />
6
+ <img alt="NPM version" src="https://img.shields.io/npm/v/@crossbind/plugin-webpack/beta?style=for-the-badge" />
7
7
  </a>
8
8
  <a href="https://github.com/crossbind/crossbind/blob/main/LICENSE">
9
9
  <img alt="License" src="https://img.shields.io/github/license/crossbind/crossbind?style=for-the-badge" />
10
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" />
11
+ <a href="https://crossbind.dev/docs/guide/integrate-into-existing-project/webpack">
12
+ <img alt="Docs - Webpack" src="https://img.shields.io/badge/Docs_-_Webpack-20B2AA?style=for-the-badge" />
13
13
  </a>
14
14
 
15
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:
16
+ Install the plugin and its loader:
17
17
 
18
18
  ```sh
19
- npm install @crossbind/plugin-webpack @crossbind/plugin-webpack-loader --save-dev
19
+ npm install @crossbind/plugin-webpack@beta @crossbind/plugin-webpack-loader@beta --save-dev
20
20
  ```
21
21
 
22
22
  **Webpack**
23
- To enable the plugin, modify the `webpack.config.js` file as shown below.
23
+ Register the plugin, its loader rule and its dev server settings in `webpack.config.js`:
24
24
 
25
25
  ```diff
26
- + const CrossbindWebpackPlugin = require('@crossbind/plugin-webpack');
26
+ + const CrossbindWebpackPlugin = require('@crossbind/plugin-webpack').default;
27
27
  + const crossbindWebpackPlugin = new CrossbindWebpackPlugin();
28
- + const compiler = crossbindWebpackPlugin.getCompiler();
29
28
 
30
29
  module.exports = {
31
30
  //...
@@ -34,112 +33,32 @@ module.exports = {
34
33
  ],
35
34
  module: {
36
35
  rules: [
37
- + {
38
- + test: /\.h$/,
39
- + loader: '@crossbind/plugin-webpack-loader',
40
- + options: { compiler },
41
- + }
36
+ + crossbindWebpackPlugin.getRule(),
42
37
  ],
43
38
  },
39
+ + devServer: crossbindWebpackPlugin.getDevServerConfig(),
44
40
  };
45
41
  ```
46
42
 
47
43
  **Rspack**
48
- To enable the plugin, modify the `rspack.config.mjs` file as shown below.
44
+ The same plugin works in `rspack.config.mjs`:
49
45
 
50
46
  ```diff
51
47
  + import CrossbindWebpackPlugin from '@crossbind/plugin-webpack';
52
48
 
53
49
  + const crossbindWebpackPlugin = new CrossbindWebpackPlugin();
54
- + const compiler = crossbindWebpackPlugin.getCompiler();
55
50
 
56
51
  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
- + },
52
+ module: {
53
+ rules: [
54
+ + crossbindWebpackPlugin.getRule(),
55
+ ],
56
+ },
57
+ plugins: [
58
+ + crossbindWebpackPlugin,
59
+ ],
60
+ + devServer: crossbindWebpackPlugin.getDevServerConfig(),
94
61
  });
95
62
  ```
96
63
 
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
- ```
64
+ `getRule()` sends header and Rust imports to the loader, and `getDevServerConfig()` serves the build with the COOP/COEP headers a multithreaded build needs. To keep a `devServer` of your own, spread `getDevServerConfig()` into it.
package/index.js CHANGED
@@ -3,6 +3,7 @@ import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import {
5
5
  state, createLib, buildWasm, createBridgeFile, getData, getCrossbindScript, getRustJsScript, getDependFilePath, buildDependencies, getTargetParams, getFilteredBuildTargets, isSourceNewer,
6
+ appSourceFiles,
6
7
  } from 'crossbind';
7
8
 
8
9
  const targetParams = getTargetParams({ platform: ['wasm'], arch: ['wasm32'], runtime: ['st'], runtimeEnv: ['browser'] }, true);
@@ -19,6 +20,8 @@ if (!buildTargetDebug) {
19
20
  buildTargetRelease = buildTargetDebug;
20
21
  }
21
22
 
23
+ const buildTargetFor = (mode) => (mode === 'development' ? buildTargetDebug : buildTargetRelease);
24
+
22
25
  export default class CrossbindWebpackPlugin {
23
26
  static defaultOptions = {};
24
27
 
@@ -54,6 +57,12 @@ export default class CrossbindWebpackPlugin {
54
57
  compiler.options.resolve.alias[`${dep.package.name}$`] = libRs;
55
58
  }
56
59
  }
60
+ // Before any loader runs: a header's bridge reads the include roots of every dependency, conan's staged
61
+ // packages included, and a cargo dependency built for another target only is there but lacks this one
62
+ // until the build makes it.
63
+ const buildDeps = () => buildDependencies({ targetParams: { ...targetParams, buildType: [buildTargetFor(compiler.options.mode).buildType] } });
64
+ compiler.hooks.beforeRun.tapPromise(pluginName, buildDeps);
65
+ compiler.hooks.watchRun.tapPromise(pluginName, buildDeps);
57
66
  // tapPromise (not tap) so webpack awaits the native C++/wasm build and a build
58
67
  // failure surfaces as a compilation error instead of an unhandled rejection.
59
68
  compiler.hooks.done.tapPromise(pluginName, this.onDone.bind(this));
@@ -67,8 +76,7 @@ export default class CrossbindWebpackPlugin {
67
76
 
68
77
  async onDone({ compilation }) {
69
78
  const isDev = compilation.options.mode === 'development';
70
- const buildTarget = isDev ? buildTargetDebug : buildTargetRelease;
71
- await buildDependencies({ targetParams: { ...targetParams, buildType: [buildTarget.buildType] } });
79
+ const buildTarget = buildTargetFor(compilation.options.mode);
72
80
  const force = isSourceNewer(buildTarget);
73
81
  const sourceBuilt = createLib(buildTarget, 'Source', { force, buildSource: true });
74
82
  // Bridge cache is keyed on the nativeGlob fingerprint: a changed bridge
@@ -98,6 +106,7 @@ export default class CrossbindWebpackPlugin {
98
106
  getLoaderOptions() {
99
107
  return {
100
108
  bridges: this.bridges,
109
+ appSourceFiles,
101
110
  createBridgeFile,
102
111
  getData,
103
112
  state,
@@ -122,10 +131,16 @@ export default class CrossbindWebpackPlugin {
122
131
  throw new Error('devServer is not defined');
123
132
  }
124
133
 
134
+ // The boot code asks under webpack's public path, which need not be the root.
135
+ const asksFor = (req, name) => req.url.split('?')[0].endsWith(`/${name}`);
136
+
125
137
  middlewares.unshift({
126
138
  name: '/crossbind.js',
127
- path: '/crossbind.js',
128
- middleware: (req, res) => {
139
+ middleware: (req, res, next) => {
140
+ if (!asksFor(req, 'crossbind.js')) {
141
+ next();
142
+ return;
143
+ }
129
144
  const filePath = `${state.config.paths.build}/${buildTargetDebug.jsName}`;
130
145
  res.setHeader('Content-Type', 'application/javascript');
131
146
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@@ -136,8 +151,11 @@ export default class CrossbindWebpackPlugin {
136
151
 
137
152
  middlewares.unshift({
138
153
  name: '/crossbind.wasm',
139
- path: '/crossbind.wasm',
140
- middleware: (req, res) => {
154
+ middleware: (req, res, next) => {
155
+ if (!asksFor(req, 'crossbind.wasm')) {
156
+ next();
157
+ return;
158
+ }
141
159
  const filePath = `${state.config.paths.build}/${buildTargetDebug.wasmName}`;
142
160
  res.setHeader('Content-Type', 'application/wasm');
143
161
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@@ -148,8 +166,11 @@ export default class CrossbindWebpackPlugin {
148
166
 
149
167
  middlewares.unshift({
150
168
  name: '/crossbind.data.txt',
151
- path: '/crossbind.data.txt',
152
- middleware: (req, res) => {
169
+ middleware: (req, res, next) => {
170
+ if (!asksFor(req, 'crossbind.data.txt')) {
171
+ next();
172
+ return;
173
+ }
153
174
  const filePath = `${state.config.paths.build}/${buildTargetDebug.dataTxtName}`;
154
175
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
155
176
  res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossbind/plugin-webpack",
3
- "version": "2.0.0-beta.62",
3
+ "version": "2.0.0-beta.64",
4
4
  "description": "crossbind Webpack plugin: A tool for seamless C++ integration with the Webpack bundler.",
5
5
  "homepage": "https://github.com/crossbind/crossbind/tree/main/plugins/webpack#readme",
6
6
  "repository": {
@@ -11,8 +11,8 @@
11
11
  "type": "module",
12
12
  "main": "index.js",
13
13
  "dependencies": {
14
- "crossbind": "^2.0.0-beta.62",
15
- "@crossbind/core-embind-rust": "^2.0.0-beta.62"
14
+ "crossbind": "^2.0.0-beta.64",
15
+ "@crossbind/core-embind-rust": "^2.0.0-beta.64"
16
16
  },
17
17
  "peerDependencies": {
18
18
  "webpack": ">=5.0.0"