Repository: parcel-bundler/parcel (js)

Issue:
[v2] posthtml-transform throws an unknown error when using posthtml-obfuscate
# 🐛 bug report

When I use posthtml-obfuscate to obfuscate email addresses with v2, I get this mysterious error:

```
@parcel/transformer-posthtml: Unexpected token u in JSON at position 0
```

## 🎛 Configuration (.babelrc, package.json, cli command)

this is what my .posthtmlrc file looks like:
```
{
  "plugins": {
    "posthtml-modules": {
      "root": "./src"
    },
    "posthtml-obfuscate": {}
  }
}
```

## 🤔 Expected Behavior

I'd expect the posthtml transformer to work without an error. This example (code provided below) works fine with parcel v1.

## 😯 Current Behavior

```
🚨 Build failed.
@parcel/transformer-posthtml: Unexpected token u in JSON at position 0
SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at Object.transform (node_modules/@parcel/transformer-posthtml/lib/PostHTMLTransformer.js:119:21)
```

## 💁 Possible Solution

Digging into PostHTMLTransformer.js, the error happens here:

```
    asset.setAST({
      type: 'posthtml',
      version: '0.4.1',
      program: JSON.parse(JSON.stringify(res.tree)) // posthtml adds functions to the AST that are not serializable

    });
```

My guess is that `res.tree` is undefined, but I'm unsure what would cause that

## 💻 Code Sample

.posthtmlrc
```
{
  "plugins": {
    "posthtml-obfuscate": {}
  }
}
```

index.html
```
<p>this is a test</p>
```

command:
`npx parcel build index.html`

## 🌍 Your Environment

<!--- Include as many relevant details about the environment you experienced the bug in -->

| Software         | Version(s) |
| ---------------- | ---------- |
| Parcel           | 2.0.0-beta.1
| Node             | v10.19.0
| npm/Yarn         | 6.14.2
| Operating System | macOS 10.15.5



Pull request description:
Fix and integration test for posthtml plugin loading
<!---
Thanks for filing a pull request 😄 ! Before you submit, please read the following:

Search open/closed issues before submitting since someone might have pushed the same thing before!
-->

# ↪️ Pull Request

<!---
Provide a general summary of the pull request here
Please look for any issues that this PR resolves and tag them in the PR.
-->

When loading posthtml plugins the convention is to call the function to get the actual plugin, this PR implements this as I don't think any posthtml plugin does not have this ability.

Fixes #4783 

## ✔️ PR Todo

- [x] Added/updated unit tests for this change
- [x] Filled out test instructions (In case there aren't any unit tests)
- [x] Included links to related issues/PRs


Patch:
diff --git a/packages/transformers/posthtml/src/loadPlugins.js b/packages/transformers/posthtml/src/loadPlugins.js
index 5051cb3f6..236240b64 100644
--- a/packages/transformers/posthtml/src/loadPlugins.js
+++ b/packages/transformers/posthtml/src/loadPlugins.js
@@ -55,15 +55,8 @@ async function loadPlugin(
   let plugin = await packageManager.require(pluginArg, relative, {
     autoinstall,
   });
-  plugin = plugin.default || plugin;
 
-  if (
-    options != null &&
-    typeof options === 'object' &&
-    Object.keys(options).length > 0
-  ) {
-    plugin = plugin(options);
-  }
+  plugin = plugin.default || plugin;
 
-  return plugin.default || plugin;
+  return plugin(options);
 }
diff --git a/yarn.lock b/yarn.lock
index 01d179529..5a09180ad 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10875,6 +10875,11 @@ posthtml-include@^1.1.0:
     posthtml "^0.12.0"
     posthtml-parser "^0.4.2"
 
+posthtml-obfuscate@^0.1.5:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/posthtml-obfuscate/-/posthtml-obfuscate-0.1.5.tgz#d65f6642c96349002d33a2208845b2f7517d0fc8"
+  integrity sha1-1l9mQsljSQAtM6IgiEWy91F9D8g=
+
 posthtml-parser@^0.3.0:
   version "0.3.3"
   resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.3.3.tgz#3fe986fca9f00c0f109d731ba590b192f26e776d"


Test patch:
diff --git a/packages/core/integration-tests/package.json b/packages/core/integration-tests/package.json
index ff2e9c240..b3d0f5cce 100644
--- a/packages/core/integration-tests/package.json
+++ b/packages/core/integration-tests/package.json
@@ -41,6 +41,7 @@
     "rimraf": "^2.6.1",
     "sinon": "^5.0.1",
     "tempy": "^0.3.0",
-    "ws": "^5.1.1"
+    "ws": "^5.1.1",
+    "posthtml-obfuscate": "^0.1.5"
   }
 }
diff --git a/packages/core/integration-tests/test/integration/posthtml-plugins/.posthtmlrc b/packages/core/integration-tests/test/integration/posthtml-plugins/.posthtmlrc
new file mode 100644
index 000000000..ce2ee4b87
--- /dev/null
+++ b/packages/core/integration-tests/test/integration/posthtml-plugins/.posthtmlrc
@@ -0,0 +1,5 @@
+{
+  "plugins": {
+    "posthtml-obfuscate": {}
+  }
+}
diff --git a/packages/core/integration-tests/test/integration/posthtml-plugins/index.html b/packages/core/integration-tests/test/integration/posthtml-plugins/index.html
new file mode 100644
index 000000000..8c04b351f
--- /dev/null
+++ b/packages/core/integration-tests/test/integration/posthtml-plugins/index.html
@@ -0,0 +1,3 @@
+<a href="mailto:sam@smith.com">
+	sam@smith.com
+</a>
diff --git a/packages/core/integration-tests/test/posthtml.js b/packages/core/integration-tests/test/posthtml.js
index 6f7a5334d..0d7c674bc 100644
--- a/packages/core/integration-tests/test/posthtml.js
+++ b/packages/core/integration-tests/test/posthtml.js
@@ -46,6 +46,30 @@ describe('posthtml', function() {
     ]);
   });
 
+  it('Should be able to process an html file with plugins without any params for plugin', async function() {
+    let b = await bundle(
+      path.join(__dirname, '/integration/posthtml-plugins/index.html'),
+    );
+
+    assertBundles(b, [
+      {
+        type: 'html',
+        assets: ['index.html'],
+      },
+    ]);
+
+    let html = await outputFS.readFile(
+      path.join(distDir, 'index.html'),
+      'utf-8',
+    );
+    assert(
+      html.includes(
+        '&#115;&#97;&#109;&#64;&#115;&#109;&#105;&#116;&#104;&#46;&#99;&#111;&#109;',
+      ),
+    );
+    assert(!html.includes('sam@smith.com'));
+  });
+
   it.skip('should add dependencies referenced by posthtml-include', async () => {
     const b = await bundle(
       path.join(__dirname, '/integration/posthtml-assets/index.html'),