Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow selectively including polyfills #30

Merged
merged 14 commits into from
Jun 24, 2022
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ declare namespace NodePolyfillPlugin {
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.
*/
excludeAliases?: readonly Alias[]
includeAliases?: readonly Alias[]
rjerue marked this conversation as resolved.
Show resolved Hide resolved
rjerue marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
23 changes: 14 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@
const { ProvidePlugin } = require("webpack")
const filterObject = require("filter-obj")

const excludeObjectKeys = (object, excludeKeys) => filterObject(object, key => !excludeKeys.includes(key))
const filterObjectKeys = (object, keys, isInclude) => filterObject(object, key => keys.includes(key) === isInclude)

module.exports = class NodePolyfillPlugin {
constructor(options = {}) {
this.options = {
excludeAliases: [],
...options
constructor({ excludeAliases = [], includeAliases = [] } = {}) {
rjerue marked this conversation as resolved.
Show resolved Hide resolved
if (includeAliases.length > 0 && excludeAliases.length > 0) {
throw new Error("Unable to use excludeAliases and includeAliases options!")
rjerue marked this conversation as resolved.
Show resolved Hide resolved
}

this.options = { excludeAliases, includeAliases }
}

apply(compiler) {
compiler.options.plugins.push(new ProvidePlugin(excludeObjectKeys({
const isInclude = this.options.includeAliases.length > 0
const keys = isInclude ? this.options.includeAliases : this.options.excludeAliases
const filterFunc = object => filterObjectKeys(object, keys, isInclude)
rjerue marked this conversation as resolved.
Show resolved Hide resolved

compiler.options.plugins.push(new ProvidePlugin(filterFunc({
Buffer: [require.resolve("buffer/"), "Buffer"],
console: require.resolve("console-browserify"),
process: require.resolve("process/browser")
}, this.options.excludeAliases)))
})))

compiler.options.resolve.fallback = {
...excludeObjectKeys({
...filterFunc({
assert: require.resolve("assert/"),
buffer: require.resolve("buffer/"),
console: require.resolve("console-browserify"),
Expand Down Expand Up @@ -51,7 +56,7 @@ module.exports = class NodePolyfillPlugin {
util: require.resolve("util/"),
vm: require.resolve("vm-browserify"),
zlib: require.resolve("browserify-zlib")
}, this.options.excludeAliases),
}),
...compiler.options.resolve.fallback
}
}
Expand Down
17 changes: 17 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ module.exports = {
}
```

#### includeAliases
rjerue marked this conversation as resolved.
Show resolved Hide resolved

Alternatively, you can chose to only include certain aliases. In this example, only `console` wil be polyfilled.
rjerue marked this conversation as resolved.
Show resolved Hide resolved

```js
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")

module.exports = {
// Other rules...
plugins: [
new NodePolyfillPlugin({
includeAliases: ["console"]
})
]
}
```

## Aliases

### Globals
Expand Down
36 changes: 35 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const test = require("ava")
const webpack = require("p-webpack")
const NodePolyfillPlugin = require(".")

test("main", async t => {
test.serial("main", async t => {
await webpack({
entry: "./fixture",
output: {
Expand All @@ -22,4 +22,38 @@ test("main", async t => {

// https://github.com/browserify/console-browserify/blob/f7eefc7c908c29d2e94954e5c6c1098e8c1028b4/index.js#L63
t.false(fs.readFileSync("./dist/main.js").toString().includes("No such label: "))

// https://github.com/feross/buffer/blob/master/index.js#L80
t.true(fs.readFileSync("./dist/main.js").toString().includes("is invalid for option \"size\""))
})

test.serial("Test Include", async t => {
rjerue marked this conversation as resolved.
Show resolved Hide resolved
await webpack({
entry: "./fixture",
output: {
library: {
type: "commonjs-module"
}
},
plugins: [
new NodePolyfillPlugin({
includeAliases: ["console"]
})
]
})

t.is(require("./dist/main.js"), "Hello World")

// https://github.com/browserify/console-browserify/blob/f7eefc7c908c29d2e94954e5c6c1098e8c1028b4/index.js#L63
t.true(fs.readFileSync("./dist/main.js").toString().includes("No such label: "))

// https://github.com/feross/buffer/blob/master/index.js#L80
t.false(fs.readFileSync("./dist/main.js").toString().includes("is invalid for option \"size\""))
})

test("Test Error", t => {
rjerue marked this conversation as resolved.
Show resolved Hide resolved
t.throws(() => new NodePolyfillPlugin({
includeAliases: ["console"],
excludeAliases: ["crypto"]
}), { instanceOf: Error })
})