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
Better handle inner modules #54
Comments
This probably will have an effect on how modules are translated |
Still thinking this through. I haven't come up with a plan yet, but I have thought about some options. One would be to check for inner modules, translate them into a function and export them with the outer module's export statement. The problem here is when aliasing, etc, it would currently break with the way they are translated into imports. Another would be to take the module and make it into it's own file. This would remove the issues laid out above. I would require some updates to the translation of modules, but nothing too bad. I'm not sold on either of those and would love any thoughts, feedback, or ideas. |
Ok, so I think I've come up with a plan for modules. Elixir modules don't really match up with ES6 modules as well as one would like. For instance, you could create a module inside of a function if you wanted to. So my proposal for updating modules is to do the following:
defmodule Hello do
@some_attr "hello"
defp private_function() do
end
def public_function() do
end
end Would turn into this const Hello = (function(){
const __MODULE__ = Atom("Hello")
const some_attr = "hello"
function private_function(){
return null;
}
function public_function(){
return null;
}
return { public_function: public_function }
})(); inner modules would work similar: defmodule Hello do
@some_attr "hello"
defmodule World do
end
defp private_function() do
end
def public_function() do
end
end Would turn into this const Hello = (function(){
const __MODULE__ = Atom("Hello")
const some_attr = "hello"
let World = (function(){
const __MODULE__ = Atom("World")
})();
function private_function(){
return null;
}
function public_function(){
return null;
}
return { public_function: public_function, World: World }
})(); An added benefit to this would be that one would no longer have to explicitly use aliases for modules. Aliases would just end up as const declarations to pointing to the specific module. For using other JS libraries, one could use them globally or a macro would be added specifically for importing js libraries. An added benefit of using the macro is that it helps keep Elixirscript as standard Elixir. The This may also help down the line with protocols as well. An added benefit is th |
Option 2 would be making them into classes. I just don't like ES6 classes that much (personal preference). |
What about dependencies and module loading? What happens with that stuff? |
They will either be reference by their full names are can be aliased. For example: defmodule Hello do
alias Another.Module.World
js_import JQuery
def something() do
Some.Other.Module.do_it()
World.do_it()
end
end would be translated to const Hello = (function(){
const __MODULE__ = Atom("Hello")
const World = Another.Module.World
import JQuery from 'jquery'
function something(){
Some.Other.Module.do_it();
World.do_it();
}
return { something: something }
})(); In this example, since the modules will be in the same scope, they can be accessed without having to import them in. This works more in line with Elixir. Also, you saw an example of what an alias would do. Lastly I added an example of how an ES6 module could be added. A macro (in the example The only issue for importing ES6 modules would be that import statements are hoisted to the top. That would mean that a module that imported an ES6 module could have that ES6 module used by another module here. That doesn't cause to much of a concern though.. |
@togakangaroo here is the link the the defmodule documentation for Elixir. Maybe it would give you some ideas as to how I could do this a better way. I like your idea of using something such as System.define, but not sure if it would work out well. |
So I ended up reverting back to making the modules into ES6 modules. I'm pulling out the inner modules and they are being placed into their own files. I'm also automatically creating an import statement for them in the modules containing them. The solution should resolve this issue. |
Testing out inner modules and realized there are some issues. The biggest being they export the default object as well creating more than one export default in a file. Same thing goes for the
__MODULE__
definition. Need a new way of handling the__MODULE__
translation, and probably need to put inner modules as a property on the outer object. There should only be one export default per file.The text was updated successfully, but these errors were encountered: