Open pantharshit00 opened 4 years ago
I think we should track CSS parsing and JS parsing separately. Let's track CSS parsing here and I will create JS parsing in separate issue.
Update: #24
Sure but for now do you agree we should go with approach 3?
Yep sounds good to me
It will still give us control over the abell part. We will be able to add more syntax features in the future
I didn't get this point. We will be ASTing over CSS part right? how will it change anything for abell part?
Yes, we will parse the CSS part as well with stylis but not with our own implementation
No I meant. We will be parsing 'only' the CSS part right? and everything else will stay as it is
No, we will have to parse the html tree in order to add attributes.
oh yes makes sense
We will only have to add attribute to parent element right? how about doing that with RegExp and only doing AST of CSS?
That is possible but yeah we need html ast someday for sure.
I was thinking of doing this all over the weekend, I guess I can start with CSS and see our state.
ASTing html part will make abell more reliable in general
Yeah maybe we can add HTML AST in future. CSS AST should work for now. In my opinion, It will be easier to track if we go step-by-step instead a sudden major refactor now.
Makes sense, we can cut scope for now
Maybe a little out of context from the issue here. Just for fun I thought that this looks same as jsx with the extra {{}}. So I thought to treat the file as a js file parse the code generate the ast using babel and then use jsx-transform or whatever to create the required thing for static generation.
But unfortunately the jsx parser treated {{const a ='hello'}}
as an invalid syntax cause it is supposed to be an object. I thought there will be a plugin system for parser as well but the only way to write a plugin for @babel/parser
is to fork a version of it and modify it. I wrote it gives no error but it still keeps the extra { when generating ast. https://github.com/StTronn/Babell-Abell-parser source
So JSX parser may not work the best.
There are some syntax differences like, we use actual html attributes and not jsx attributes
We pass props to component by passing props={}
through components.
One of the major reasons I don't want to go for JSX yet is because we don't need all that additional transformation yet. We want to do minimal operations on the HTML as most of the part is going to be static.
I am working on one implementation where I am using htmlparser2
for tokenizing our HTML and creating the HTML right there and while doing that, execute the JS that comes in between.
Once I am done some experimentations I'll update it here
( I am going to do a thought dump here, I can also see us writing a tech blog about this. Basically I will start working after I other abell team members approves )
Right now we basically do string modifications to an abell file. We extract out the contents of
{{ }}
which are essentially regions of javascript inside of your html, which may or may no return a value. That is determined by the execution of that javascript in a V8 isolate provided by Node(https://nodejs.org/api/vm.html).This has worked pretty fine for now. But this approach makes it very hard to add features to abell especially features which require us to add additional metadata to the abell tree. Doing string replacements on a whole html tree is very error prone and it will be a unmaintainable mess for us. This also debars us from adding error messages to abell when a abell component is invalid. Right now it will just generate rubbish html.
For example, right now no one will stop you from doing this
Guess the output of the above template 😛. IMO it should be an error instead with a proper stack trace.
Now the solution here is what almost every compiler or template engine does. We will need to convert abell source code into a data structure which has all of the necessary information about the source code. This process is generally known as parsing. The DS should have enough information for us to implement a “printer” for that data structure which will convert it back to a source code.
Then what we can do is transform the data structure into our need. That process is far easier than relying on string transforms. At the end we can just print the result of transform. If we went with approach that I am going to suggest below, we should to perform the script execution before the printing step.
This data structure is typically called an Abstract Syntax Tree which represents the code in form of a tree data structure and it omits details like punctuations to make it “abstract”. For example, we don’t need to keep the
<
token in order to know it is a tag. That detail is abstracted out of parse tree. We will need to design an AST for abell which will enable to us all of the above mentioned things.Now we come to the real question, what it should look like, should we just do the current replacements and then just parse the html and css syntax using an existing parser? Is this even worth the effort? Will this make abell “strict”? Argh?!
Approach 1
Here is the first thought that came to my mind. Use
htmlparser2
+stylis
for the CSS. We do the replacements, then these tools can parse the data we pipe into them and do the transformations. This is a very good naive approach at first. Much less work and we gain.Pros
Cons
{{ }}
in the source tree. They are just replacements in the pre parsing step.Approach 2
Now the next approach that comes in the mind is going all custom. Doing all the parsing the from scratch. Implementing all lexing, parsing and printing steps from scratch. This will give us full control.
Pros
Cons
Approach 3
You know it’s coming. It’s always the hybrid approach. The reasoning in this approach is that since most of the abell syntax is baked into the html part, we can write a parser from scratch for that to have full control there. We can have stylis to parse the CSS for us. It will also give us additional features which stylis provides.
Props
&
referenceI will suggest we go with approach 3. That sounds most promising to me. If you all agree I can start working on it and I will writing a brief design proposal of the AST here.
Also, all this means almost a rewrite of abell-renderer 😅.
With this, abell will be like a superset of html with some additional features.