-
Notifications
You must be signed in to change notification settings - Fork 797
Babel modules roadmap #73
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
Comments
Kind of curious about this myself. I've been looking into sprockets-es6 and I have no idea how to bridge the module declarations with my work. |
Also really interested. |
I'm also interested in this. |
Let's pretend I didn't understand half of the words you used in this issue. Also let's pretend that the original author of sprockets isn't here anymore and i'll likely have to work with whatever solution we decide to go with forwards. Let's be patient and go slowly. What's babel?
Okay. That seems like a thing we should want to support. What is a common js require? Looks like it's a way to import explicit functions from http://wiki.commonjs.org/wiki/Modules/1.1 What's a ES6 module declarations? Looks like it's a way of importing module like behavior http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples. We already have a babel processor. It looks like it currently supports es6
The test suite uses
It looks like sprockets gets its ES6 support directly from babel. How are commonJS requires implemented? Is it a different file extension & mime type or is it some other layer on top of es6? If it's a file extension then once the babel-transpiler supports commonjs then we can register that in the same way. There will probably be some plumbing needed in the processor itself. |
We would like to use CommonJS export/require with CoffeeScript. Currently we're getting the job done with the Browserify-Rails gem. It works, but is slow as heck, and the setup is complex. IMHO it would be a big improvement for Rails if CommonJS was incorporated directly into sprockets. I can't imagine building any JavaScript front-end these days without CommonJS - I believe it should be part of Sprockets. |
Babel does not implement common js requires itself. All it does it rewrite ES6 imports (i.e. |
Well that is the thing - Sprockets does not provide a loader, and it seems that this is something that pretty much anyone would expect in a modern setup. And that loader should work both with precompiled assets and expando assets. I know it is a tall order, but... |
Can you give me more info, what exactly is a "loader", this term has a sprockets specific context
Something that could help an implementer could be a PR with a failing test. Here's an example of an es6 test sprockets/test/test_environment.rb Lines 268 to 272 in 7b91316
You would need to add your own asset. |
@opal would benefit from a loader too, currently we monkeypatch I looked into that in the past and I suspect sprockets pipelines can be used for something like that. https://github.com/opal/opal-rails/blob/master/app/helpers/opal_helper.rb |
@SCheems a Loader would be a 3rd party JavaScript library responsible for polyfilling the Folks using sprockets 3 and the Rails.application.config.assets.configure do |env|
# If you are using Sprockets 4, use `Sprockets::BabelProcessor`
# instead of `Sprockets::ES6`.
es6amd = Sprockets::ES6.new('modules' => 'amd', 'moduleIds' => true)
# Replace the default transformer to transpile each `.es6` file with `define`
# and `require` from the AMD spec.
# Just be sure to add `almond.js` to the application and
# require it before requiring other assets on `application.js`
env.register_transformer 'text/ecmascript-6', 'application/javascript', es6amd
end Ideally, Sprockets could choose a module format by default (like Hope this helps to shed some light on some of the terms from the ES6 world here 😄 I'm using this setup on my current project and I believe that some other users of sprockets-es6 might have done a similar setup on their apps. |
related: #52 |
@lucasmazza Thanks so much. Exactly what I needed! However the syntax is thus: Rails.application.config.assets.configure do |env|
es6amd = Sprockets::BabelProcessor.new('modules' => 'amd', 'moduleIds' => true)
# Replace the default transformer to transpile each `.es6` file with `define`
# and `require` from the AMD spec.
# Just be sure to add `almond.js` to the application and
# require it before requiring other assets on `application.js`
env.register_transformer 'application/ecmascript-6', 'application/javascript', es6amd
end |
Any update here? Discourse seems to be using some vendored variant of ember-cli/loader.js to be able to transpile to amd modules. I really think Sprockets should provide something like this out of the box. Otherwise one will always have to install additional components to obtain a real ES2015 environment. |
While looking at maccman/sprockets-commonjs, I realized there are two more aspects that would need to be addressed:
|
@tf My first thought of preventing double requires would be to let sprockets be aware of the package.json convention, aka adding npm as a source for JavaScript dependencies. |
I'm not sure I agree. From my perspective, one of the main advantages of the asset pipeline comes from packaging up assets along with other Rails app components in gems and not having to deal with two package managers. If I was to use npm anyway, I do not see much value over switching to the js ecosystem completely and using webpack directly. |
Yeah, I think assets from other parts of Rails should definitely be accessible. But having to repackage every JS lib in a gem, or completely switching just to be able to use npm packages is also quite cumbersome. I was thinking more of a sprockets implemented For anyone interested, a lot of discussion has been held over at react-rails about the require() topic, and spawned a side project dedicated to including webpack (w/ React) into Rails. |
Would love to see node-style requires in sprockets proper. We're using browserify-rails right now and slowly moving our sprockets requires over to node style with |
Wondering if it makes sense to have a dependency on babel-transpliler give the maintainer is not upgrading it to the latest version of Babel (see babel/ruby-babel-transpiler#288). I haven't yet looked at this library, but it seems like it may be a promising alternative: https://github.com/fnando/babel-schmooze-sprockets |
I worked with @Liceth updating sprockets-commonjs to sprockets 4.x, the processor is this: https://github.com/Liceth/sprockets-commonjs/blob/sprockets-4/lib/sprockets/commonjs.rb, The modules can be used like this: /* foobar.module.es6 */
function foo() { return 'foo'; }
function bar() { return 'bar'; }
export { foo, bar }; /* main.es6 */
//= require foobar.module
import * as lib from 'foobar.module';
console.log(lib.foo());
console.log(lib.bar()); I think this can be an acceptable default solution for this since it works without requiring Node.js/NPM in the system like other alternatives. |
For anyone who ends up on this issue and wants to use something like the aforementioned babel-schmooze-sprockets but in an application on sprockets 3 (babel-schmooze-sprockets only works with the sprockets 4 beta), I'll mention the similar sprockets plugin I created: https://github.com/rmacklin/sprockets-bumble_d. It supports sprockets 3 and has some extra stuff geared specifically toward migrating large codebases to ES6 modules (since that was my use case at work) but it also works for general purpose babel transpilation. |
There been any more progress / documentation on this (or similar, e.g. where does TypeScript stand)? I looked at https://github.com/rmacklin/sprockets-bumble_d linked above, but seems, and if I understand correctly that wont tell sprockets the proper dependency order even between ES6 files, and similar for the other tools? Ive also looked at the CommonJS libs/loaders to make define/require work before, but honestly when I start getting hundreds of files, I like how Sprockets in development config can put them all as a series of separate As I understand from ES6 modules/imports, etc., dynamic loading is not supported there, so all the imports can be determined statically? So something like this should be possible and performant? // page/my_class.es6 (allow page/my_class.es6.erb as well for image_url etc.)
import * as lib from 'lib/bar'
...
export MyClass; Use bable (or any similar tool, maybe seperate gems) to get CommonJS ES5 (or even better, the exports and requires as a separate object/output). var lib = require('lib/bar');
...
module.exports = MyClass; Then convert this for Sprockets (unless its possible to directly tell sprockets the requires list in the API and skip the "//=" stuff) //= require foo/bar
(function() {
var lib = window.$modules.foo$bar;
...
window.$modules.page$my_class = MyClass;
})(); So in the HTML simply: <!--As before: devlepment-->
<script src="/assets/lib/bar.self-00112233.js?body=1"></script>
<script src="/assets/page/my_class.self-00112233.js?body=1"></script>
<!--As before: production / precompiled-->
<script src="https://cdn.my-asset-host.com/assets/application-00112233.js"></script> |
Have you tried setting this up with webpacker & rails 5.1 ? |
I'm pruning issues for Sprockets 4 release. We can still discuss here, but I want to keep the tracker as primarily actionable bugs. I'm going to close this for now. |
@schneems Looking at the es6 support section of https://github.com/rails/sprockets/blob/master/UPGRADING.md, does that mean es6 exports/imports don't work yet? When I try to import and export modules, it seems like it's attempting to require('the_module') and I don't see require defined anywhere. Is there a right way to do this? I guess this is happening because the babel-transpiler is just doing whatever it deems reasonable in this case. |
Currently Babel is switched to replace ES6 module declarations with CommonJS requires, whereas Sprockets does not provide a runtime to handle those requires.
Is there some roadmap as to how modules are going to be wired into Sprockets, or does it have to be handled by some module you have to BYO?
The text was updated successfully, but these errors were encountered: