Skip to content

Commit 18d6b9a

Browse files
authored
build(node-runtime-worker-thread, compass-shell): Do not inline worker-runtime modules (#588)
* fix(node-runtime-worker-thread): Do not polyfill node built-ins; Externalize optional mongodb deps * fix(node-runtime-worker-thread): Do not inline worker and child process proxy during the build * build(compass-shell): Make node-runtime-worker-thread a peer dependency This allows us to avoid inlining source of node-runtime-worker-thread when used in compass, but has a small downside of manually installing runtime in compass main repo * chore(node-runtime-worker-thread): Remove unused loader * chore(compas-shell): Clean-up unused leftovers in deps * build(compass-shell): Move node-runtime back to direct dependencies and explicitly exclude it for all builds
1 parent 4f1e18f commit 18d6b9a

File tree

6 files changed

+56
-135
lines changed

6 files changed

+56
-135
lines changed

packages/compass-shell/config/webpack.base.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,11 @@ module.exports = {
128128
exclude: /(node_modules)/
129129
}
130130
]
131+
},
132+
externals: {
133+
// Runtime implementation depends on worker file existing near the library
134+
// main import and for that reason it needs to stay external to the
135+
// compass-shell
136+
'@mongosh/node-runtime-worker-thread': 'commonjs2 @mongosh/node-runtime-worker-thread',
131137
}
132138
};

packages/compass-shell/config/webpack.dev.config.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { spawn } = require('child_process');
77
const baseWebpackConfig = require('./webpack.base.config');
88
const project = require('./project');
99

10+
/** @type import('webpack').Configuration */
1011
const config = {
1112
mode: 'development',
1213
target: 'electron-renderer',
@@ -76,6 +77,21 @@ const config = {
7677
.on('close', () => process.exit(0))
7778
.on('error', spawnError => console.error(spawnError)); // eslint-disable-line no-console
7879
}
80+
},
81+
resolve: {
82+
// Without this alias, in dev mode symlinked browser-repl breaks the code
83+
// by having two reacts loadeded on the page
84+
alias: {
85+
'react': require.resolve('react'),
86+
'react-dom': require.resolve('@hot-loader/react-dom'),
87+
}
88+
},
89+
externals: {
90+
// "Optional" mongodb dependencies that should stay out of the build in dev
91+
// mode
92+
'mongodb-client-encryption': 'commonjs2 mongodb-client-encryption',
93+
kerberos: 'commonjs2 kerberos',
94+
snappy: 'commonjs2 snappy'
7995
}
8096
};
8197

packages/node-runtime-worker-thread/loaders/inline-entry-loader.js

Lines changed: 0 additions & 119 deletions
This file was deleted.

packages/node-runtime-worker-thread/src/child-process-proxy.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@
1313
*
1414
* @see {@link https://github.com/nodejs/node/pull/36344}
1515
*/
16-
1716
import { once } from 'events';
1817
import { SHARE_ENV, Worker } from 'worker_threads';
18+
import fs from 'fs';
19+
import path from 'path';
1920
import { exposeAll, createCaller } from './rpc';
2021

21-
/**
22-
* The source has to be inlined to allow the runtime to be bundled in a single
23-
* file when used by compass shell
24-
*/
25-
import workerRuntimeSrc from 'inline-entry-loader!./worker-runtime';
22+
// eslint-disable-next-line no-sync
23+
const workerRuntimeSrc = fs.readFileSync(
24+
path.resolve(
25+
process.env.NODE_RUNTIME_WORKER_THREAD_PARENT_DIRNAME || __dirname,
26+
'worker-runtime.js'
27+
),
28+
'utf-8'
29+
);
2630

2731
const workerProcess = new Worker(workerRuntimeSrc, {
2832
eval: true,

packages/node-runtime-worker-thread/src/index.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import { ChildProcess, SpawnOptionsWithoutStdio } from 'child_process';
55
import { MongoClientOptions } from '@mongosh/service-provider-core';
66
import { Runtime, RuntimeEvaluationListener, RuntimeEvaluationResult } from '@mongosh/browser-runtime-core';
7+
import { promises as fs } from 'fs';
8+
import path from 'path';
79
import spawnChildFromSource, { kill } from './spawn-child-from-source';
810
import { Caller, createCaller } from './rpc';
911
import { ChildProcessEvaluationListener } from './child-process-evaluation-listener';
1012
import type { WorkerRuntime as WorkerThreadWorkerRuntime } from './worker-runtime';
11-
import childProcessProxySrc from 'inline-entry-loader!./child-process-proxy';
1213
import { deserializeEvaluationResult } from './serializer';
1314

1415
type ChildProcessRuntime = Caller<WorkerThreadWorkerRuntime>;
@@ -43,11 +44,22 @@ class WorkerRuntime implements Runtime {
4344
private async initWorker() {
4445
const { uri, driverOptions, cliOptions, spawnOptions } = this.initOptions;
4546

46-
this.childProcess = await spawnChildFromSource(
47-
childProcessProxySrc,
48-
spawnOptions
47+
const childProcessProxySrc = await fs.readFile(
48+
path.resolve(__dirname, 'child-process-proxy.js'),
49+
'utf-8'
4950
);
5051

52+
this.childProcess = await spawnChildFromSource(childProcessProxySrc, {
53+
...spawnOptions,
54+
env: {
55+
// Proxy child process and worker_threads worker are inlined and as such
56+
// they are not aware of the dirname (which child process will need to
57+
// read worker source)
58+
NODE_RUNTIME_WORKER_THREAD_PARENT_DIRNAME: __dirname,
59+
...spawnOptions.env
60+
}
61+
});
62+
5163
this.childProcessRuntime = createCaller(
5264
['init', 'evaluate', 'getCompletions', 'setEvaluationListener'],
5365
this.childProcess

packages/node-runtime-worker-thread/webpack.config.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ const TerserPlugin = require('terser-webpack-plugin');
55
const config = {
66
target: 'node',
77

8-
devtool: false,
9-
108
output: {
119
path: path.resolve(__dirname, 'dist'),
1210
filename: '[name].js',
@@ -27,10 +25,6 @@ const config = {
2725
extensions: ['.ts', '.js']
2826
},
2927

30-
resolveLoader: {
31-
modules: ['node_modules', path.resolve(__dirname, 'loaders')]
32-
},
33-
3428
optimization: {
3529
minimizer: [
3630
new TerserPlugin({
@@ -40,6 +34,14 @@ const config = {
4034
}
4135
})
4236
]
37+
},
38+
39+
node: false,
40+
41+
externals: {
42+
'mongodb-client-encryption': 'commonjs2 mongodb-client-encryption',
43+
kerberos: 'commonjs2 kerberos',
44+
snappy: 'commonjs2 snappy'
4345
}
4446
};
4547

0 commit comments

Comments
 (0)