Class: Condenser::JstTransformer

Inherits:
NodeProcessor show all
Defined in:
lib/condenser/transformers/jst_transformer.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from NodeProcessor

#binary, #exec_runtime, #exec_runtime_error, #exec_syntax_error, node_modules_path, #node_modules_path, setup

Class Method Details

.call(environment, input) ⇒ Object



3
4
5
# File 'lib/condenser/transformers/jst_transformer.rb', line 3

def self.call(environment, input)
  new.call(environment, input)
end

Instance Method Details

#call(environment, input) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/condenser/transformers/jst_transformer.rb', line 7

def call(environment, input)
  opts = {
    filename:         input[:filename],
    moduleId:         input[:filename].sub(/(\..+)+/, ''),
    cwd:              '/assets/',
    filenameRelative: input[:filename],
    sourceFileName:   input[:filename],
    ast:              false,
    compact:          false,
    plugins:          []
  }

  result = exec_runtime("    const babel = require(\"\#{File.expand_path('../../processors/node_modules', __FILE__)}/@babel/core\");\n    const source = \#{JSON.generate(input[:source])};\n    const options = \#{JSON.generate(opts).gsub(/\"@?babel[\\/-][^\"]+\"/) { |m| \"require(\#{m})\"}};\n\n    function globalVar(scope, name) {\n      if (name in scope.globals) {\n        return true;\n      } else if (scope.parent === null) {\n        return false;\n      } else {\n        return globalVar(scope.parent, name);\n      }\n    }\n\n    options['plugins'].unshift(function({ types: t }) {\n      return {\n        visitor: {\n          Identifier(path, state) {\n            if ( path.parent.type == 'MemberExpression' && path.parent.object != path.node) {\n              return;\n            }\n            if ( path.parent.type == 'ImportSpecifier' || path.parent.type == 'ImportDefaultSpecifier' || path.parent.type =='FunctionDeclaration') {\n              return;\n            }\n\n            if (\n              path.node.name !== 'document' &&\n              path.node.name !== 'window' &&\n              !(path.node.name in global) &&\n              globalVar(path.scope, path.node.name)\n            ) {\n              path.replaceWith(\n                t.memberExpression(t.identifier(\"locals\"), path.node)\n              );\n            }\n          }\n        }\n      };\n    });\n\n    try {\n      const result = babel.transform(source, options);\n      console.log(JSON.stringify(result));\n    } catch(e) {\n      console.log(JSON.stringify({'error': [e.name, e.message, e.stack]}));\n      process.exit(0);\n    }\n  JS\n\n  if result['error']\n    if result['error'][0] == 'SyntaxError'\n      raise exec_syntax_error(result['error'][1], \"/assets/\#{input[:filename]}\")\n    else\n      raise exec_runtime_error(result['error'][0] + ': ' + result['error'][1])\n    end\n  else\n    input[:source] = result['code']\n  end\n  \n  environment.preprocessors['application/javascript'].each do |processor|\n    processor_klass = (processor.is_a?(Class) ? processor : processor.class)\n    input[:processors] << processor_klass.name\n    environment.load_processors(processor_klass)\n    processor.call(environment, input)\n  end\nend\n")