Skip to content

Commit b32ab40

Browse files
authored
fix(NODE-4211): Do not require crypto in browser builds (#500)
1 parent 210fc11 commit b32ab40

File tree

4 files changed

+74
-34
lines changed

4 files changed

+74
-34
lines changed

package-lock.json

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@rollup/plugin-commonjs": "^15.0.0",
4444
"@rollup/plugin-json": "^4.1.0",
4545
"@rollup/plugin-node-resolve": "^9.0.0",
46+
"@rollup/plugin-replace": "^4.0.0",
4647
"@rollup/plugin-typescript": "^6.0.0",
4748
"@typescript-eslint/eslint-plugin": "^3.10.1",
4849
"@typescript-eslint/parser": "^3.10.1",

rollup.config.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
55
import { babel } from '@rollup/plugin-babel';
66
import typescript from '@rollup/plugin-typescript';
77
import nodeGlobals from 'rollup-plugin-node-globals';
8+
import replace from '@rollup/plugin-replace';
89

910
const tsConfig = {
1011
allowJs: false,
@@ -33,18 +34,26 @@ const tsConfig = {
3334
};
3435
const input = 'src/bson.ts';
3536

36-
const plugins = [
37-
typescript(tsConfig),
38-
nodeResolve({ preferBuiltins: false }),
39-
nodeBuiltins(),
40-
nodeGlobals(),
41-
commonjs({ extensions: ['.js', '.ts'] }),
42-
babel({
43-
babelHelpers: 'external',
44-
plugins: ['@babel/plugin-external-helpers'],
45-
presets: [['@babel/env', { modules: false }]]
46-
})
47-
];
37+
const plugins = (options = { browser: false }) => {
38+
return [
39+
typescript(tsConfig),
40+
nodeResolve({ preferBuiltins: false }),
41+
nodeBuiltins(),
42+
nodeGlobals(),
43+
replace({
44+
preventAssignment: true,
45+
values: {
46+
'process.browser': options.browser
47+
}
48+
}),
49+
commonjs({ extensions: ['.js', '.ts'] }),
50+
babel({
51+
babelHelpers: 'external',
52+
plugins: ['@babel/plugin-external-helpers'],
53+
presets: [['@babel/env', { modules: false }]]
54+
})
55+
];
56+
};
4857

4958
const external = Object.keys(pkg.dependencies || {});
5059

@@ -60,7 +69,7 @@ module.exports = [
6069
exports: 'named',
6170
sourcemap: true
6271
},
63-
plugins,
72+
plugins: plugins(),
6473
external
6574
},
6675
{
@@ -88,6 +97,6 @@ module.exports = [
8897
sourcemap: true
8998
}
9099
],
91-
plugins
100+
plugins: plugins({ browser: true })
92101
}
93102
];

src/parser/utils.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,38 @@ declare let require: Function;
3434
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3535
declare let global: any;
3636
declare const self: unknown;
37+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
38+
declare let process: any; // Used by @rollup/plugin-replace
3739

3840
const detectRandomBytes = (): RandomBytesFunction => {
39-
if (typeof window !== 'undefined') {
40-
// browser crypto implementation(s)
41-
const target = window.crypto || window.msCrypto; // allow for IE11
42-
if (target && target.getRandomValues) {
43-
return size => target.getRandomValues(Buffer.alloc(size));
41+
if (process.browser) {
42+
if (typeof window !== 'undefined') {
43+
// browser crypto implementation(s)
44+
const target = window.crypto || window.msCrypto; // allow for IE11
45+
if (target && target.getRandomValues) {
46+
return size => target.getRandomValues(Buffer.alloc(size));
47+
}
4448
}
45-
}
4649

47-
if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
48-
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
49-
return size => global.crypto.getRandomValues(Buffer.alloc(size));
50-
}
50+
if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
51+
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
52+
return size => global.crypto.getRandomValues(Buffer.alloc(size));
53+
}
5154

52-
let requiredRandomBytes: RandomBytesFunction | null | undefined;
53-
try {
54-
// eslint-disable-next-line @typescript-eslint/no-var-requires
55-
requiredRandomBytes = require('crypto').randomBytes;
56-
} catch (e) {
57-
// keep the fallback
58-
}
55+
return insecureRandomBytes;
56+
} else {
57+
let requiredRandomBytes: RandomBytesFunction | null | undefined;
58+
try {
59+
// eslint-disable-next-line @typescript-eslint/no-var-requires
60+
requiredRandomBytes = require('crypto').randomBytes;
61+
} catch (e) {
62+
// keep the fallback
63+
}
5964

60-
// NOTE: in transpiled cases the above require might return null/undefined
65+
// NOTE: in transpiled cases the above require might return null/undefined
6166

62-
return requiredRandomBytes || insecureRandomBytes;
67+
return requiredRandomBytes || insecureRandomBytes;
68+
}
6369
};
6470

6571
export const randomBytes = detectRandomBytes();

0 commit comments

Comments
 (0)