question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PostHTML Plugins: ast.walk is not a function

See original GitHub issue

🐛 bug report

I was using Parcel, PostHTML and several PostHTML plugins to create my documents. However the build fails on certain conditions.

🎛 Configuration (.babelrc, package.json, cli command)

Here is my .posthtmlrc:

{
  "plugins": {
    "posthtml-include-md": true,
  }
}

test.html (plugins above do not have any effect on this HTML since this doesn’t include any markdown paragraphs):

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<div class="baz">foobar</div>
	</body>
</html>

CLI Command: $ parcel test.html

🤔 Expected Behavior

$ parcel test.html
Server running at http://localhost:1234 
✨  Built in 6ms.

😯 Current Behavior

$ parcel test.html
Server running at http://localhost:1234 
🚨  /path/to/my/document/test.html: ast.walk is not a function
    at HTMLAsset.collectDependencies (/path/to/parcel/packages/core/parcel-bundler/src/assets/HTMLAsset.js:138:9)
    at HTMLAsset.getDependencies (/path/to/parcel/packages/core/parcel-bundler/src/Asset.js:81:18)

💁 Possible Solution

Following the stack trace and the source code, I figured out that the problem came from where Parcel loaded plugins. ast in the error log above was not an object that expresses AST but was a expoted function that returns an actual plugin function (that takes a tree as an argument). As PostHTML process() function didn’t have type checks, it simply returned an actual plugin function which clearly didn’t have a walk property.

I made a small modification to /packages/core/parcel-bundler/src/utils/loadPlugins.js then the build succeeded. I removed a length check for options so that plugin functions were always executed even with empty options.

async function loadPlugin(plugin, relative, options) {
 ...
   if (typeof options !== 'object') {
      options = {};
    }
   
    if (Object.keys(options).length > 0) { // removed this 
      plugin = plugin(options);
    }
...

Giving the plugin options (like {"a":"b"} instead of true) in .posthtmlrc also made the build successful.

In addition, README.md of posthtml/posthtml also shows that we have to call the exported functions (require('...')()) of the plugin before calling process(ast, options) since they are functions that return functions.

posthtml(
  [
    require('posthtml-to-svg-tags')(),
    require('posthtml-extend-attrs')({
      attrsTree: {
        '.wow' : {
          id: 'wow_id',
          fill: '#4A83B4',
          'fill-rule': 'evenodd',
          'font-family': 'Verdana'
        }
      }
    })
  ])
  .process(html/*, options */)
  .then((result) =>  console.log(result.html))

As the changes I made to loadPlugins.js might cause problems of other transformers such as PostCSS, I tried to modifying parcel-bundler/src/transforms/posthtml.js instead but I wasn’t able to figure out how to pass the plugins’ options to them. For Parcel v2 this should be straightforward thanks to the non-shared loadPlugins.js.

🔦 Context

💻 Code Sample

🌍 Your Environment

Software Version(s)
Parcel 1.12.3
Node v11.13.0
npm/Yarn 1.16.0 (yarn)
Operating System Arch Linux (kernel: 5.0.5-arch1-1)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
mischniccommented, Jun 23, 2019

Using this configuration seems to work (without any modifications to parcel itself):

{
  "plugins": {
    "posthtml-include-md": {},
  }
}

But true should still work…

0reactions
danielrobcommented, May 30, 2020
  "devDependencies": {
    "parcel-bundler": "^1.12.4",
    "posthtml-include": "^1.4.3"
{
  "plugins": {
    "posthtml-include": true
  }
}

Same problem here… specifying {} fixed the problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

posthtml/posthtml - Gitter
2) It does work out of the box, you can either use the helper or write a recursive function to do the walk...
Read more >
Top 5 posthtml-parser Code Examples - Snyk
To help you get started, we've selected a few posthtml-parser examples, based on popular ways it is used in public projects. Secure your...
Read more >
parcel build error: plugin is not a function - Stack Overflow
Building a Rails 6/Vue 2 app and converting to parcel from webpack(er), so Parcel 2 is not an option for me. (Demanding people...
Read more >
Reshape NPM | npm.io
When all plugins have finished, reshape transforms the AST into a JavaScript function which, when called, will produce a string of HTML.
Read more >
postcss-loader | webpack - JS.ORG
Then add the plugin to your webpack config. ... the plugin postcss-preset-env is used, which is not installed by default. ... Using function...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found