Open JdeH opened 6 years ago
Very interesting approach. :D
I was literally just trying to set Transcrypt up with React using create-react-app and decided that it was impossible without something like this, or a way to add es6 import/exports to the monolith itself, but outside of any IIFE.
This is very exciting!
This is fantastic. It seems to be the right approach. The universal module definition "standard" is essentially deprecated at this point.
For any projects that need to hit older browsers, it's a very common practice to transpile back to ES5. So I wouldn't worry about losing browser support because transpiling to earlier version and/or polyfills will fix that issue.
If anyone is interested, I eventually did get React working well (although without CRA for now). I have a repo with a POC here: https://github.com/metamarcdw/react-transcrypt
An update on progress and planning:
Transcrypt 3.7.0 will be the first version having its module mechanism fully based upon ES6 modules. The planning is to release it in the summer, shortly after the release of Python 3.7. If you want to know how it's moving forward, take a look at the modules branch. Note that this is unstable code. Not all commits result in working code, and significant changes may still take place. In general committing is messy in this branch, since currently I am the only one working on it and try to achieve as much development speed as possible.
One other improvement that comes with this, is that it won't require write privilege in the installation directory anymore. Everything generated, including the transpiled runtime, will be written in a subdir __target__
of the project dir.
Another improvement is that the main program can now also be a JavaScript-only module. JavaScript-only modules are taken into account into the minification process, including sourcemaps.
Each Transcrypt application will be compiled to a number of JS modules, at least the main module and the runtime module. Monoliths will not be supported anymore in 3.7, as this would greatly complicate code. It is however possible to package modules into a monolith using: https://rollupjs.org/guide/en .
The latter tool can also used (as a temporary solution) to make node.js applications with modules, as node.js currently doesn't fully support the ES6 modules spec. (it has no named imports and exports). If node.js will continue not supporting this, a more permanent solution will be to generate special purpose import and export code for node.js, but this is considered less desirable. After all, what do we have standards for.
Transcrypt 3.7 will require Python 3.7 or higher, and compile to ES6 or higher, although a postprocessor may be used to make the generated code run on ES5. Note that Transcrypt 3.6 will remain available for (further) development of existing applications.
Kind regards Jacques
Starting with JS 6 JavaScript has a decent module model (it's about time...).
In reaction to some issues I've been looking into using this to somehow implement Python modules. My conclusion is that it's feasible to merge the two.
As an example I've taken the following application from the current TS distro:
https://github.com/QQuick/Transcrypt/tree/master/transcrypt/development/manual_tests/units/animals
and manually converted the generated code to the code below. By using JS' native module mechanism it lacks a lot of overhead and complexity. Each Python/Transcrypt module translates to exactly one JS module. Modules aren't merged, there's no separate unit system needed. Modules can loaded separately and dynamically. The runtime is needed only once per page. Versioning of the runtime is simple. I believe this is the way to go.
Apart from simplicity and compactness it will lead to a completely seamless blending of the Transcrypt/Python and the JS world. TS modules will be first class citizens in the JS world and vice versa.
So in the future TS apps won't be monoliths anymore. They will be built up just like Python apps, from modules. To keep things simple (the main benefit of Python over JS) this mechanism, if it all works out as planned, will supersede monolithic Trancrypt apps as well as unit'ized apps. Some minor incompatibilities may result but they should be easily resolved. Note that the internals of compiled TS files will change, they will be simpler.
Also the sourcemap mechanism will need to be adapted. If that proves a problem, generating monoliths may still be allowed for debugging purposes. Currently the JS community hasn't laid an egg on module sourcemaps a.f.i.k.
This is not a very shortterm thing. Development on TS as is goes on. But at some point this transition very probably will be made. It should have minimal consequences for user code, as long as it doesn't depend upon TS' internal file structure. The .mod.js files will be more important, they will indeed by JS modules. And of course current and older versions of Transcrypt are planned to remain available for download.
To minimize disruption for developers, it may be a good idea to have this transition coincide with the transition to Python 3.7. Also that may be the right time to say goodbye to es5 mode (no problem in older browsers, since Google Closure already provides polyfills).
Some special attention will have to be paid to not creating a JS version of MS' wellknown DLL Hell. Sharing modules can create very hard versioning problems. This is something to be taken into account from the start. One solution would be to allow generation of an application container. An application container is a separate entity with all needed versions of all recursively imported libraries packed together. Packing may be denoted by using separate subdirs or by using unique prefixes.
Another point of attention is the fact the same import in different applications may refer to different modules (that are local to the app and happen to have the same name). This problem can probably best be solved in combination with the versioning problem.
animals.html
animals.mod.js
cats.mod.js
dogs.mod.js
animals_submodule.mod.js
cats_submodule.mod.js
dogs_submodule.mod.js
__transcrypt___runtime_3.6.101)).mod.js