module Sprockets::Babel

Constants

VERSION

Public Class Methods

context() click to toggle source
# File lib/sprockets/babel.rb, line 94
def self.context
  @context ||= begin
    ctx = V8::Context.new
    ctx.eval('var self = this; ' + File.read(::Babel::Transpiler.script_path))
    ctx['console'] = Console.new
    ctx
  end
end
transform(code, options = {}) click to toggle source
# File lib/sprockets/babel.rb, line 81
def self.transform(code, options = {})
  modules = options[:modules] || 'inline'
  babel_transform = context[:babel][:transform]
  result = babel_transform.call(code, options.merge(
    'ast' => false,
    'modules' => modules == 'inline' ? 'amd' : modules
  ))
  if modules == 'inline'
    result['code'] = transform_inline(result['code'], options)
  end
  result
end

Private Class Methods

resolve_relative_module_id(source_module_id, target_module_id) click to toggle source
# File lib/sprockets/babel.rb, line 165
def self.resolve_relative_module_id(source_module_id, target_module_id)
  target_path_parts = target_module_id.split(/\//)
  basename = target_path_parts.pop
  return target_module_id if target_path_parts.length == 0
  return target_module_id if target_path_parts[0] != '.' && target_path_parts[0] != '..'
  target_path_parts.shift if target_path_parts[0] == '.'

  source_path_parts = source_module_id.split(/\//)
  source_path_parts.pop # ignore filename part
  while target_path_parts.length > 0 && target_path_parts[0] == '..'
    target_path_parts.shift
    source_path_parts.pop if source_path_parts.length > 0
  end
  parts = source_path_parts.concat(target_path_parts)
  if parts.length == 0
    return basename
  end
  parts.join('/') + '/' + basename
end
transform_inline(code, options) click to toggle source
# File lib/sprockets/babel.rb, line 105
    def self.transform_inline(code, options)
      module_var = '$__' + ERB::Util.url_encode(options[:moduleId].gsub(/^\.\//, ''))
        .gsub(/%|-/, '') + '__'
      prefix = <<-JS
        (function(global) {
          var exports = {};
          global.#{module_var} = exports;

          var define = function(moduleId, importIds, body) {
            var resolveRelativeModuleId = function(targetId) {
              var targetParts = targetId.split(/\\//),
                basename = targetParts.pop();
              if ((targetParts.length == 0) || (targetParts[0] != '.' && targetParts[0] != '..')) {
                return targetId;
              }
              if (targetParts[0] == '.') {
                targetParts.shift();
              }

              var fromParts = moduleId.split(/\\//);
              fromParts.pop();
              while (targetParts.length > 0 && targetParts[0] == '..') {
                targetParts.shift();
                if (fromParts.length > 0) {
                  fromParts.pop();
                }
              }
              var parts = fromParts.concat(targetParts);
              return (parts.length == 0) ? basename : parts.join('/') + '/' + basename;
            };

            importIds.shift();
            var imports = [exports],
              module = {exports: null};
            for (var i = 0; i < importIds.length; i++) {
              if (importIds[i] == 'module') {
                imports.push(module);
                continue;
              }

              var importId = resolveRelativeModuleId(importIds[i]),
                variable = '$__' + encodeURIComponent(importId.replace(/^\\.\\//, ''))
                  .replace(/%|-/, '') + '__';
              imports.push(global[variable]);
            }
            body.apply(global, imports);
            if (module.exports != null) {
              global.#{module_var} = module.exports;
            }
          };
      JS

      # code transpiled by babel is inserted here

      suffix = <<-JS
        })(this);
      JS
      prefix + "\n" + code + "\n" + suffix
    end