mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 09:42:07 +08:00
Transpile ES6 even without node, just using rubyracer
This commit is contained in:
parent
dddb2e19fc
commit
c3ccc3e309
|
@ -32,6 +32,7 @@ module Discourse
|
|||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
||||
require 'discourse'
|
||||
require 'es6_module_transpiler/rails'
|
||||
require 'js_locale_helper'
|
||||
|
||||
# mocha hates us, active_support/testing/mochaing.rb line 2 is requiring the wrong
|
||||
|
|
39
lib/es6_module_transpiler/rails.rb
Normal file
39
lib/es6_module_transpiler/rails.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
require 'es6_module_transpiler/rails/version'
|
||||
require 'es6_module_transpiler/tilt'
|
||||
require 'es6_module_transpiler/sprockets'
|
||||
|
||||
module ES6ModuleTranspiler
|
||||
def self.compile_to
|
||||
@compile_to || :amd
|
||||
end
|
||||
|
||||
def self.compile_to=(target)
|
||||
@compile_to = target
|
||||
end
|
||||
|
||||
def self.prefix_patterns
|
||||
@prefix_patterns ||= []
|
||||
end
|
||||
|
||||
def self.add_prefix_pattern(pattern, prefix)
|
||||
prefix_patterns << [pattern, prefix]
|
||||
end
|
||||
|
||||
def self.lookup_prefix(path)
|
||||
_, prefix = prefix_patterns.detect {|pattern, prefix| pattern =~ path }
|
||||
|
||||
prefix
|
||||
end
|
||||
|
||||
def self.transform=(transform)
|
||||
@transform = transform
|
||||
end
|
||||
|
||||
def self.transform
|
||||
@transform
|
||||
end
|
||||
|
||||
def self.compiler_options
|
||||
@compiler_options ||= {}
|
||||
end
|
||||
end
|
5
lib/es6_module_transpiler/rails/version.rb
Normal file
5
lib/es6_module_transpiler/rails/version.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
module ES6ModuleTranspiler
|
||||
module Rails
|
||||
VERSION = '0.4.0'
|
||||
end
|
||||
end
|
3
lib/es6_module_transpiler/sprockets.rb
Normal file
3
lib/es6_module_transpiler/sprockets.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'sprockets'
|
||||
|
||||
Sprockets.register_engine '.es6', Tilt::ES6ModuleTranspilerTemplate
|
7195
lib/es6_module_transpiler/support/es6-module-transpiler.js
Normal file
7195
lib/es6_module_transpiler/support/es6-module-transpiler.js
Normal file
File diff suppressed because one or more lines are too long
22
lib/es6_module_transpiler/support/es6_node_runner.js
Normal file
22
lib/es6_module_transpiler/support/es6_node_runner.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
(function(program, execJS) { execJS(program) })(function(module, exports, console) {
|
||||
#{source}
|
||||
}, function(program) {
|
||||
var output, print = function(string) {
|
||||
process.stdout.write('' + string);
|
||||
};
|
||||
try {
|
||||
result = program();
|
||||
if (typeof result == 'undefined' && result !== null) {
|
||||
print('["ok"]');
|
||||
} else {
|
||||
try {
|
||||
print(JSON.stringify(['ok', result]));
|
||||
} catch (err) {
|
||||
print('["err"]');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
print(JSON.stringify(['err', '' + err]));
|
||||
}
|
||||
});
|
||||
|
4
lib/es6_module_transpiler/tilt.rb
Normal file
4
lib/es6_module_transpiler/tilt.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
require 'tilt'
|
||||
require 'es6_module_transpiler/tilt/es6_module_transpiler_template'
|
||||
|
||||
Tilt.register Tilt::ES6ModuleTranspilerTemplate, 'es6'
|
109
lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb
Normal file
109
lib/es6_module_transpiler/tilt/es6_module_transpiler_template.rb
Normal file
|
@ -0,0 +1,109 @@
|
|||
require 'execjs'
|
||||
|
||||
module Tilt
|
||||
class ES6ModuleTranspilerTemplate < Tilt::Template
|
||||
self.default_mime_type = 'application/javascript'
|
||||
|
||||
@mutex = Mutex.new
|
||||
@ctx_init = Mutex.new
|
||||
|
||||
def prepare
|
||||
# intentionally left empty
|
||||
# Tilt requires this method to be defined
|
||||
end
|
||||
|
||||
def self.create_new_context
|
||||
ctx = V8::Context.new(timeout: 5000)
|
||||
ctx.eval("module = {}; exports = {};");
|
||||
ctx.load("#{Rails.root}/lib/es6_module_transpiler/support/es6-module-transpiler.js")
|
||||
ctx
|
||||
end
|
||||
|
||||
def self.v8
|
||||
return @ctx if @ctx
|
||||
|
||||
# ensure we only init one of these
|
||||
@ctx_init.synchronize do
|
||||
return @ctx if @ctx
|
||||
@ctx = create_new_context
|
||||
end
|
||||
|
||||
@ctx
|
||||
end
|
||||
|
||||
class JavaScriptError < StandardError
|
||||
attr_accessor :message, :backtrace
|
||||
|
||||
def initialize(message, backtrace)
|
||||
@message = message
|
||||
@backtrace = backtrace
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.protect
|
||||
rval = nil
|
||||
@mutex.synchronize do
|
||||
begin
|
||||
rval = yield
|
||||
# This may seem a bit odd, but we don't want to leak out
|
||||
# objects that require locks on the v8 vm, to get a backtrace
|
||||
# you need a lock, if this happens in the wrong spot you can
|
||||
# deadlock a process
|
||||
rescue V8::Error => e
|
||||
raise JavaScriptError.new(e.message, e.backtrace)
|
||||
end
|
||||
end
|
||||
rval
|
||||
end
|
||||
|
||||
def evaluate(scope, locals, &block)
|
||||
return @output if @output
|
||||
|
||||
klass = self.class
|
||||
klass.protect do
|
||||
@output = klass.v8.eval(generate_source(scope))
|
||||
end
|
||||
@output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def transpiler_path
|
||||
File.expand_path('../../support/es6-module-transpiler.js', __FILE__)
|
||||
end
|
||||
|
||||
def generate_source(scope)
|
||||
"new module.exports.Compiler(#{::JSON.generate(data, quirks_mode: true)}, '#{module_name(scope.root_path, scope.logical_path)}', #{compiler_options}).#{compiler_method}()"
|
||||
end
|
||||
|
||||
def module_name(root_path, logical_path)
|
||||
path = ''
|
||||
if prefix = ES6ModuleTranspiler.lookup_prefix(File.join(root_path, logical_path))
|
||||
path = File.join(prefix, logical_path)
|
||||
else
|
||||
path = logical_path
|
||||
end
|
||||
|
||||
if ES6ModuleTranspiler.transform
|
||||
path = ES6ModuleTranspiler.transform.call(path)
|
||||
end
|
||||
|
||||
path
|
||||
end
|
||||
|
||||
def compiler_method
|
||||
type = {
|
||||
amd: 'AMD',
|
||||
cjs: 'CJS',
|
||||
globals: 'Globals'
|
||||
}[ES6ModuleTranspiler.compile_to.to_sym]
|
||||
|
||||
"to#{type}"
|
||||
end
|
||||
|
||||
def compiler_options
|
||||
::JSON.generate(ES6ModuleTranspiler.compiler_options, quirks_mode: true)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user