Skip to content

Commit a18cda4

Browse files
rjerueRichienb
andauthored
Allow selectively including polyfills (#30)
Co-authored-by: Richie Bendall <[email protected]>
1 parent 27be8de commit a18cda4

File tree

5 files changed

+86
-9
lines changed

5 files changed

+86
-9
lines changed

index.d.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { MergeExclusive } from "type-fest"
12
import { Compiler } from "webpack"
23

34
declare namespace NodePolyfillPlugin {
@@ -34,12 +35,21 @@ declare namespace NodePolyfillPlugin {
3435
| "vm"
3536
| "zlib"
3637

37-
export interface Options {
38+
interface IncludeOptions {
3839
/**
39-
By default, the modules that were polyfilled in Webpack 4 are mirrored over. However, if you don't want a module like console to be polyfilled you can specify alises to be skipped here.
40-
*/
40+
By default, the modules that were polyfilled in Webpack 4 are mirrored over. However, you can choose to only include certain aliases. For example, you can only have `console` polyfilled.
41+
*/
42+
includeAliases?: readonly Alias[]
43+
}
44+
45+
interface ExcludeOptions {
46+
/**
47+
By default, the modules that were polyfilled in Webpack 4 are mirrored over. However, if you don't want a module like `console` to be polyfilled you can specify alises to be skipped here.
48+
*/
4149
excludeAliases?: readonly Alias[]
4250
}
51+
52+
export type Options = MergeExclusive<IncludeOptions, ExcludeOptions>
4353
}
4454

4555
declare class NodePolyfillPlugin {

index.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,38 @@
22
const { ProvidePlugin } = require("webpack")
33
const filterObject = require("filter-obj")
44

5-
const excludeObjectKeys = (object, excludeKeys) => filterObject(object, key => !excludeKeys.includes(key))
5+
function createAliasFilter({ includeAliases, excludeAliases }) {
6+
if (includeAliases.length > 0) {
7+
return object => filterObject(object, key => includeAliases.includes(key))
8+
}
9+
10+
return object => filterObject(object, key => !excludeAliases.includes(key))
11+
}
612

713
module.exports = class NodePolyfillPlugin {
814
constructor(options = {}) {
915
this.options = {
1016
excludeAliases: [],
17+
includeAliases: [],
1118
...options
1219
}
20+
21+
if (this.options.includeAliases.length > 0 && this.options.excludeAliases.length > 0) {
22+
throw new Error("excludeAliases and includeAliases are mutually exclusive")
23+
}
1324
}
1425

1526
apply(compiler) {
16-
compiler.options.plugins.push(new ProvidePlugin(excludeObjectKeys({
27+
const filter = createAliasFilter(this.options)
28+
29+
compiler.options.plugins.push(new ProvidePlugin(filter({
1730
Buffer: [require.resolve("buffer/"), "Buffer"],
1831
console: require.resolve("console-browserify"),
1932
process: require.resolve("process/browser")
20-
}, this.options.excludeAliases)))
33+
})))
2134

2235
compiler.options.resolve.fallback = {
23-
...excludeObjectKeys({
36+
...filter({
2437
assert: require.resolve("assert/"),
2538
buffer: require.resolve("buffer/"),
2639
console: require.resolve("console-browserify"),
@@ -51,7 +64,7 @@ module.exports = class NodePolyfillPlugin {
5164
util: require.resolve("util/"),
5265
vm: require.resolve("vm-browserify"),
5366
zlib: require.resolve("browserify-zlib")
54-
}, this.options.excludeAliases),
67+
}),
5568
...compiler.options.resolve.fallback
5669
}
5770
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"string_decoder": "^1.3.0",
4646
"timers-browserify": "^2.0.12",
4747
"tty-browserify": "^0.0.1",
48+
"type-fest": "^2.13.1",
4849
"url": "^0.11.0",
4950
"util": "^0.12.4",
5051
"vm-browserify": "^1.1.2"

readme.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ module.exports = {
3535

3636
Type: `object`
3737

38+
`excludeAliases` and `includeAliases` are mutually exclusive.
39+
3840
#### excludeAliases
3941

4042
By default, the modules that were polyfilled in Webpack 4 are mirrored over. However, if you don't want a module like `console` to be polyfilled you can specify alises to be skipped here.
@@ -52,6 +54,23 @@ module.exports = {
5254
}
5355
```
5456

57+
#### includeAliases
58+
59+
Alternatively, you can choose to only include certain aliases. For example, you can only have `console` polyfilled.
60+
61+
```js
62+
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
63+
64+
module.exports = {
65+
// Other rules...
66+
plugins: [
67+
new NodePolyfillPlugin({
68+
includeAliases: ["console"]
69+
})
70+
]
71+
}
72+
```
73+
5574
## Aliases
5675

5776
### Globals

test.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const test = require("ava")
33
const webpack = require("p-webpack")
44
const NodePolyfillPlugin = require(".")
55

6-
test("main", async t => {
6+
test.serial("main", async t => {
77
await webpack({
88
entry: "./fixture",
99
output: {
@@ -22,4 +22,38 @@ test("main", async t => {
2222

2323
// https://github.com/browserify/console-browserify/blob/f7eefc7c908c29d2e94954e5c6c1098e8c1028b4/index.js#L63
2424
t.false(fs.readFileSync("./dist/main.js").toString().includes("No such label: "))
25+
26+
// https://github.com/feross/buffer/blob/master/index.js#L80
27+
t.true(fs.readFileSync("./dist/main.js").toString().includes("is invalid for option \"size\""))
28+
})
29+
30+
test.serial("includeAliases", async t => {
31+
await webpack({
32+
entry: "./fixture",
33+
output: {
34+
library: {
35+
type: "commonjs-module"
36+
}
37+
},
38+
plugins: [
39+
new NodePolyfillPlugin({
40+
includeAliases: ["console"]
41+
})
42+
]
43+
})
44+
45+
t.is(require("./dist/main.js"), "Hello World")
46+
47+
// https://github.com/browserify/console-browserify/blob/f7eefc7c908c29d2e94954e5c6c1098e8c1028b4/index.js#L63
48+
t.true(fs.readFileSync("./dist/main.js").toString().includes("No such label: "))
49+
50+
// https://github.com/feross/buffer/blob/master/index.js#L80
51+
t.false(fs.readFileSync("./dist/main.js").toString().includes("is invalid for option \"size\""))
52+
})
53+
54+
test("includeAliases and excludeAliases used at the same time", t => {
55+
t.throws(() => new NodePolyfillPlugin({
56+
includeAliases: ["console"],
57+
excludeAliases: ["crypto"]
58+
}), { instanceOf: Error })
2559
})

0 commit comments

Comments
 (0)