marko-js / marko

A declarative, HTML-based language that makes building web apps fun
https://markojs.com/
MIT License
13.35k stars 643 forks source link

code-generator.js #1420

Closed sandro-pasquali closed 4 years ago

sandro-pasquali commented 4 years ago

Description

In this article there is a very interesting example of using a code-generator.js file (assuming the naming is relevant, given how Marko typically works). I cannot find more documentation on this feature, though creating a tag folder with code-generator.js in it (file cut/paste from that article) seems to get picked up (though I can't get it actually working).

https://medium.com/hackernoon/marko-vs-react-an-in-depth-look-767de0a5f9a6

Why

The article sold me on this powerful feature!

Is this something you're interested in working on?

Yes

gavinmcfarland commented 4 years ago

Interestingly I was trying to find information about the very same thing. I was only able to find a page that describes specifying what code generator to use.

https://markojs.com/docs/marko-json/

This is the markdown component being discussed in the article if it helps you any.

https://github.com/marko-js-samples/marko-webpack/tree/master/src/components/app-markdown

tigt commented 4 years ago

I believe this feature is part of the “compiler internals” that are currently undocumented, because they’re planning on changing majorly in the next version of Marko. So unfortunately, you more or less have to reverse-engineer it, and then expect it will break with Marko 5.

DylanPiercey commented 4 years ago

@tigt is right, code-generator's, transformer's and node-factory's are all run during compilation of the template. They are extremely powerful, but we consider them unstable and more/less private API's in some cases. In Marko 5 our compiler will be built on top of babel and these plugins will effectively become babel plugins (and we will actually document it 😄).


Also just to shed a little bit of light on the differences between the compiler stages:

  1. We parse the template using htmljs parser.
  2. Any migrate functions run (defined in marko.json). This is super early so that we can mostly work with the intact AST and marko migrate CLI only runs the compiler to this stage before printing back out.
  3. Any node-factory functions run (defined in marko.json). This is used to swap out AST nodes while parsing, eg an <if(x)> might become a JavaScript if statement AST.
  4. Any transformer functions run (defined in marko.json). This was primarily intended for user land preprocessing.
  5. Any code-generator functions run (defined in marko.json). These take the Marko AST, and convert it into a JavaScript only AST (eg: <macro> will be turned into a JavaScript function).
  6. Finally we take the AST after code-generator has run and print out the JavaScript.
sandro-pasquali commented 4 years ago

Thanks for the detailed info, all. When is 5 coming out?

Re: Babel. Y'know, one of the main reasons I choose Marko is because of its unique "no build step", filesystem aware, convention-driven, compile-on-first-access design. So I hope none of that goes away. You have, maybe unwittingly, delivered a superior design IMO. Great stuff!

Closing.