Closed rubys closed 3 years ago
0.0.1 version of an npm module published. The following webpack loader can self load:
import Ruby2JS, from: '@ruby2js/ruby2js'
import path, from: 'path'
export default def loader(source)
file = path.relative(__dirname, self.resourcePath)
options = { **self.getOptions(), file: file }
begin
js = Ruby2JS.convert(source, options)
self.callback(nil, js.to_s, js.sourcemap)
rescue => error
message = error.message
message += "\n\n#{error.diagnostic}" if error.diagnostic
self.callback(Error.new(message))
end
end
@jaredcwhite Or, perhaps:
import Ruby2JS, from: '@ruby2js/ruby2js'
import path, from: 'path'
export default def loader(source)
file = path.relative(__dirname, self.resourcePath)
options = { **self.getOptions(), file: file }
begin
js = Ruby2JS.convert(source, options)
if options[:provide_source_maps] == false
return js.to_s
else
self.callback(nil, js.to_s, js.sourcemap)
end
rescue => error
message = error.message
message += "\n\n#{error.diagnostic}" if error.diagnostic
self.callback(Error.new(message))
end
end
That sounds great! I'm assuming the list of options/filters/etc. would be similar to the Snowpack loader? (seems like feature parity there makes sense)
Identical. The snowpack loader doesn't currently recognize a provide_source_maps
option, but that could be added. On the other hand, snowpack support for sourcemaps is experimental, and by default off. I'm not sure, but I think I read that snowpack rewrites some imports and that can make the sourcemap a bit off.
it does mean that one would configure the loader would be in the webpack.config.js
, so this wouldn't be a backwards compatible change. Arguably, that's where people who use webpack would expect to place their configuration?
I'm actually optimistic that this would be a big performance win. Ruby2JS takes a fraction of a second to load and then runs real fast. With the current design, Ruby2JS is spawned once per file. With the new design, it will only be loaded once. My initial measurements are that the initial Opal/JS load is slower than Ruby, but as I said, sub-second even on an i3. It is when you have a project with dozens, hundreds, or more source files that you will see a difference.
Seems cool. I might miss the niceness of the config .rb file but placing it directly within the webpack config makes the most sense, and I'm sure it'll be a lot faster with tons of files than spawning Ruby processes (although for me that hasn't been a major issue).
Challenge accepted. The following script will extract the options and format it as JSON. I just need to figure out where to put this script so that it runs automatically at startup whenever a rb2js.config.rb
file is present, and then merge the results with the options in the webpack config.
require_relative 'rb2js.config.rb'
require 'json'
puts({ filters: Ruby2JS::Filter::DEFAULTS.map {|mod|
method = mod.instance_method(mod.instance_methods.first)
File.basename(method.source_location.first, '.rb')
}, **Ruby2JS::Loader.options}.to_json)
Wowee…I wouldn't have even thought of that. Very nice!
I've now pushed a @ruby2js/ruby2js
to npm with support for taking options from either rb2js.config.rb
or a RUBY2JS_OPTIONS
environment variable.
I've also pushed a 2.0.0 version of @ruby2js/webpack-loader
that makes use of this.
Finally, I've published an example using this support: https://www.ruby2js.com/examples/rails/stimulus_webpacker
Please try it out, and let me know if there are any problems (either by reopening this issue or opening a new issue).
A byproduct of getting the demo to work with stimulus was the creation of a single source file that contains a JS implementation of ruby2js with a clean JS API. This source could be published to npm with both an ESM and CJS interface.
Examples of calling this API via node: nodetest. The ruby2js.com site also adds
Ruby2JS
as a property on thewindow
object, so it can be accessed directly via the console for experimentation.This would enable the webpack loader to be reduced to something like this: