Skip to content

Added support for VueJS Single File Components w/ example #11

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

Merged
merged 3 commits into from
Feb 8, 2018

Conversation

thomasantony
Copy link
Contributor

When the input file is .vue, the loader creates a temporary .py file for passing to Transcrypt and then deletes it afterwards. There's probably better ways of doing this (maybe an __python__ folder?). I also couldn't make a Python script work as the webpack entry point. Suggestions are welcome.

Other changes:

  • Moved the original example to examples/hello and created new example under examples/vue-demo
  • Updated README with info about VueJS

@martim00
Copy link
Owner

Yeah, man, it's a very good contribution indeed. Thanks for that! We really need an example of vue.js integration. But I'm afraid that this could not be the best solution for that. I don't know, we are a python loader so we handle python files. If we relax this constraint I think we could get too much complexity to handle in the loader (imagine if we need to manage JSX files or typescript files). I don't know, I think we need to do one thing well, which is transpile python to javascript.

But also, I could be wrong. Please, let me know what do you think.

@icarito have made another proposal to handle python in .vue files in this thread:
#8

Maybe we can evolve that. What do you think?

@thomasantony
Copy link
Contributor Author

Well, I thought this belonged here because it is still compiling only the Python part while leaving the rest of it alone. vue-loader basically calls a webpack loader for processing any <script> tag it cannot handle. For example, <script lang="coffee"> would be handled by a coffeescript transpiler. It only sends the script text to this loader and nothing else.

I initially thought py-loader would work out of the box for this purpose since it is a webpack loader. I made the changes to address the fact that Transcrypt is adamant about requiring a .py file as input rather than allowing stdin. So I merely write the text passed in by vue-loader to a temporary file and then calls Transcrypt.

I think @icarito's example shows that this functionality already works out-of-the-box when using a streaming compiler (unlike Transcrypt). This is more of a Transcrypt (and possibly jiphy)-specific tweak.

@icarito
Copy link
Contributor

icarito commented Feb 1, 2018

Hi @thomasantony - seems like a nice addition. Perhaps the saving of source to temporary file can be done only optionally? I appreciate that this makes it possible to use non-streaming compiler with embedded python in html scripts. I did try to get Transcrypt to accept stdin once: TranscryptOrg/Transcrypt#137

@icarito
Copy link
Contributor

icarito commented Feb 1, 2018

The problem with import is that Transcrypt wants to do its own thing, but require is a hacky way around it.
I have made the following pull requests to Javascripthon:

With these I am able to write components like this:

<script lang="py?compiler=pj">

    from vue import Vue
    from vue__codemirror__lite import VueCodeMirror

    Vue.use(VueCodeMirror)

    class Component:

        def __init__(self):
            self['data'] = lambda: { 'code': '2' }
            self['computed'] = { 'data': lambda: 2 }

    __all__ = Component()

</script>

@icarito
Copy link
Contributor

icarito commented Feb 1, 2018

If you have a .py test in webpack. does this trigger a build because of the new .py file ? in that case maybe look into a cache mechanism to avoid compiling the same source many times. I saw such a mechanism at https://github.com/Beg-in/javascripthon-loader/blob/master/index.js

@icarito icarito mentioned this pull request Feb 1, 2018
@icarito
Copy link
Contributor

icarito commented Feb 1, 2018

Also possibly leave a note here posva/vim-vue#97 so soon we'll have a fully integrated solution if we use Vim ;-)

@icarito
Copy link
Contributor

icarito commented Feb 2, 2018

Actually @martim00 I think this is the only way to work around the fact that many py->js compilers don't handle a stream and we want to be able to transpile python embedded in html files.
I woud like it if .vue was not a special case. I have done the same with .tag for riotjs, and there are likely other useful extensions.
Also looking over my concern to trigger webpack with the spurious .py file, having read again how it works, it should not happen.

@icarito
Copy link
Contributor

icarito commented Feb 2, 2018

You guys are probably interested in this I just pushed! https://github.com/nuxt-community/python-module

@thomasantony
Copy link
Contributor Author

@icarito It's like you read my mind! I am currently working on rewriting my personal website using Nuxt.js . This looks good!

@martim00
Copy link
Owner

martim00 commented Feb 3, 2018

Guys, sorry for the delay.

@thomasantony You are right. I finally understood the problem and as @icarito have said it is the problem with compilers not accepting the input source as streams. Because Transcrypt only accepts python files and we are receiving a .vue file from vue-loader you had to save in a temporary file. I don't think it is a problem if we manage it well, like removing the tmp files, etc. In fact in the beginning I think we were doing that.

Also, I think that saving to a temporary file will be needed to implement any pre-processing feature like the one we are planning to do for managing js import stuffs (#2). So maybe we can assume that we'll always create that tmp file and even remove the restriction to be a .py file (as @icarito said, that way we can handle inline python scripts inside html for example).

Having said that, would you mind to fix some minor issues with the code style? Then we can move forward and merge. If you don't have the time please say, then I can merge and do it for myself.

@thomasantony
Copy link
Contributor Author

What all changes are required? So far I have gathered that we want the temporary file thing to be a generic feature rather than specifically for .vue files. Should I just make it so that it does it every time?

Also, should we have a centralized location for the temporary files?

@martim00
Copy link
Owner

martim00 commented Feb 3, 2018

Yes, I think it we can assume that because of two things:

  1. We'll need to pre-process things before sending to compilers.
  2. To handle python scripts embedded in another extensions (html, vue, etc).

For the centralized location it will be nice. But if you want to keep as it is today, then we can do later.

@fzzylogic
Copy link

fzzylogic commented Feb 3, 2018

Transcrypt has an option for streams now using the xtrans pragma. Haven't used it myself, but it's been used by others. Hope that helps. Edit: Actually, think i got the wrong end of the stick here, sorry. xtrans is for calling external transpilers using pipes, from within the code that transcrypt itself is transpiling.

@martim00
Copy link
Owner

martim00 commented Feb 8, 2018

@thomasantony I'm going to merge this to be able to use it with an experiment I'm doing. If you have any additional modification please create another pull request. It will be welcome!

Thanks for your contribution!

@martim00 martim00 merged commit 86dec89 into martim00:master Feb 8, 2018
@icarito
Copy link
Contributor

icarito commented Feb 22, 2018

Hi @thomasantony and others interested in Vue components with Python, i've made https://github.com/nuxt-community/python-module and I would like your input on how to produce the object syntax vue requires.

Please check TranscryptOrg/Transcrypt#287 for a discussion of the syntax and the current problems for doing this with Transcrypt (it works with Javascripthon/pj).

If we can do some processing or syntactic sugar, I think we can do better than this syntax (avoid repetition and boilerplate)

@icarito
Copy link
Contributor

icarito commented Feb 22, 2018

I guess the main issue is the lack of a good lambda in Python (multi-line), and in this particular case Transcrypt adds unneeded methods to the object that confuse vue-meta (part of Nuxt).

@martim00
Copy link
Owner

That's very impressive!

About the syntax I'm afraid that javascript anonymous function vs python lambda differences are really bad. One solution would be using something like https://github.com/atsepkov/RapydScript, but is not totally python. They allow you to create a python multiline lambda like this:

factorial = def(n):
	if n == 0:
		return 1
	return n * factorial(n-1) 

Other solution would be using a more pythonic frontend framework, like @thomasantony 's flybywire -> https://github.com/thomasantony/flybywire

I will install python-module and play a little to see if I can have any idea.

@icarito
Copy link
Contributor

icarito commented Feb 24, 2018 via email

@martim00
Copy link
Owner

https://github.com/somosazucar/Jappy -> That's pretty cool! I have the same interest on this kind of initiative (teach programming to kids). I read your blog, very important projects you are doing in Peru. Congrats!

Feedback about python-module: I really liked the workflow Nuxt.js can afford (never use in a real project though). With Python the things can get even better =). I really do not think the python alternative to vuejs 'methods' is bad (defining the method separated). In some cases it could even be more clear. Have you tried implementing decorators for that?

Also, the middleware thing, is it possible to implement in python?

I didn't know about coconut-lang. Really cool!

@martim00
Copy link
Owner

I tested middleware with python. It worked, pretty cool!

@icarito
Copy link
Contributor

icarito commented Feb 27, 2018

Agreed Javascripthon is good for using. But I don't like repeating myself (I mean listing methods at the constructor). A decorator would be cool, but I'm not sure where to implement it. https://github.com/vuejs/vue-class-component is the official way to use classes, it adds some syntax enhancements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants