• 概要へ移動… +
    browser.coffee cake.coffee coffeescript.coffee command.coffee grammar.coffee helpers.coffee index.coffee lexer.coffee nodes.coffee optparse.coffee register.coffee repl.coffee rewriter.coffee scope.litcoffee sourcemap.litcoffee
  • index.coffee

  • §

    Node.js 実装

    CoffeeScript  = require './coffeescript'
    fs            = require 'fs'
    vm            = require 'vm'
    path          = require 'path'
    
    helpers       = CoffeeScript.helpers
    
    CoffeeScript.transpile = (js, options) ->
      try
        babel = require '@babel/core'
      catch
        try
          babel = require 'babel-core'
        catch
  • §

    このエラーは Node の専用です。CLI ユーザーは、Babel がインストールされていない場合、別なエラーを前に表示されます。

          throw new Error 'To use the transpile option, you must have the \'@babel/core\' module installed'
      babel.transform js, options
  • §

    compile メソッドは、CLI、Node、ブラウザーの API で共有されます。

    universalCompile = CoffeeScript.compile
  • §

    compile メソッドは、Node API に固有です。

    CoffeeScript.compile = (code, options) ->
  • §

    コンパイル時に、Babel の参照をコンパイラーに渡します。Node API の transpile オプションを利用できるようにするためです。このようにする必要があるのは、Webpack のようなツールが require('coffeescript') と記述して正しくビルドできるようにするためで、Babel を require しようとしてはなりません。

      if options?.transpile
        options.transpile.transpile = CoffeeScript.transpile
      universalCompile.call CoffeeScript, code, options
  • §

    一連の CoffeeScript (サーバー上) をコンパイルして実行します。ここで、__filename、__dirname、および相対的な require() を正しく設定します。

    CoffeeScript.run = (code, options = {}) ->
      mainModule = require.main
  • §

    ファイル名を設定します。

      mainModule.filename = process.argv[1] =
        if options.filename then fs.realpathSync(options.filename) else helpers.anonymousFileName()
  • §

    モジュールキャッシュをクリアします。

      mainModule.moduleCache and= {}
  • §

    node_modules 読み込みのパスを割り当てます

      dir = if options.filename?
        path.dirname fs.realpathSync options.filename
      else
        fs.realpathSync '.'
      mainModule.paths = require('module')._nodeModulePaths dir
  • §

    子インポートのコンパイルオプションを保存します。

      mainModule.options = options
    
      options.filename = mainModule.filename
      options.inlineMap = true
  • §

    コンパイルします。

      answer = CoffeeScript.compile code, options
      code = answer.js ? answer
    
      mainModule._compile code, mainModule.filename
  • §

    一連の CoffeeScript (Node.js ライクな環境) をコンパイルして評価します。CoffeeScript REPL は、入力を実行するためにこれを使用します。

    CoffeeScript.eval = (code, options = {}) ->
      return unless code = code.trim()
      createContext = vm.Script.createContext ? vm.createContext
    
      isContext = vm.isContext ? (ctx) ->
        options.sandbox instanceof createContext().constructor
    
      if createContext
        if options.sandbox?
          if isContext options.sandbox
            sandbox = options.sandbox
          else
            sandbox = createContext()
            sandbox[k] = v for own k, v of options.sandbox
          sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
        else
          sandbox = global
        sandbox.__filename = options.filename || 'eval'
        sandbox.__dirname  = path.dirname sandbox.__filename
  • §

    独自のモジュールまたは require を指定しない場合にのみ定義します。

        unless sandbox isnt global or sandbox.module or sandbox.require
          Module = require 'module'
          sandbox.module  = _module  = new Module(options.modulename || 'eval')
          sandbox.require = _require = (path) ->  Module._load path, _module, true
          _module.filename = sandbox.__filename
          for r in Object.getOwnPropertyNames require when r not in ['paths', 'arguments', 'caller']
            _require[r] = require[r]
  • §

    現在は、独自の REPL で Node が使用するものと同じハックを使用しています。

          _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
          _require.resolve = (request) -> Module._resolveFilename request, _module
      o = {}
      o[k] = v for own k, v of options
      o.bare = on # ensure return value
      js = CoffeeScript.compile code, o
      if sandbox is global
        vm.runInThisContext js
      else
        vm.runInContext js, sandbox
    
    CoffeeScript.register = -> require './register'
  • §

    暗黙的な require.extensions 登録に依存している場合、非推奨の警告とともにエラーをスローします。

    if require.extensions
      for ext in CoffeeScript.FILE_EXTENSIONS then do (ext) ->
        require.extensions[ext] ?= ->
          throw new Error """
          Use CoffeeScript.register() or require the coffeescript/register module to require #{ext} files.
          """
    
    CoffeeScript._compileRawFileContent = (raw, filename, options = {}) ->
  • §

    このファイルが Unicode バイトオーダーマークで始まる場合は、それを削除します。

      stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
    
      options = Object.assign {}, options,
        filename: filename
        literate: helpers.isLiterate filename
        sourceFiles: [filename]
    
      try
        answer = CoffeeScript.compile stripped, options
      catch err
  • §

    動的に読み込まれたファイルのファイル名とコードは、CoffeeScript.run でコンパイルされた元のファイルとは異なります。そのため、この情報をエラーに追加して、 później で適切に印刷できるようにしています。

        throw helpers.updateSyntaxError err, stripped, filename
    
      answer
    
    CoffeeScript._compileFile = (filename, options = {}) ->
      raw = fs.readFileSync filename, 'utf8'
    
      CoffeeScript._compileRawFileContent raw, filename, options
    
    module.exports = CoffeeScript
  • §

    Node の CommonJS パッケージから名前付きエクスポートを自動的に検出してすべて検出できるように、すべての名前付きエクスポートを明示的に定義します。これにより、パッケージ利用者は、import { compile } from 'coffeescript' のようにコードを記述できるようになります。これを行ってループまたは同様の処理に簡略化しないでください。module.exports.name の部分は、Node のアルゴリズムが名前を正常に検出するために不可欠です。

    module.exports.VERSION = CoffeeScript.VERSION
    module.exports.FILE_EXTENSIONS = CoffeeScript.FILE_EXTENSIONS
    module.exports.helpers = CoffeeScript.helpers
    module.exports.registerCompiled = CoffeeScript.registerCompiled
    module.exports.compile = CoffeeScript.compile
    module.exports.tokens = CoffeeScript.tokens
    module.exports.nodes = CoffeeScript.nodes
    module.exports.register = CoffeeScript.register
    module.exports.eval = CoffeeScript.eval
    module.exports.run = CoffeeScript.run
    module.exports.transpile = CoffeeScript.transpile
    module.exports.patchStackTrace = CoffeeScript.patchStackTrace
    module.exports._compileRawFileContent = CoffeeScript._compileRawFileContent
    module.exports._compileFile = CoffeeScript._compileFile