Fix #4725: apply transpile option to require’d .coffee files (#4728)

* Fix #4725: apply transpile option to require’d .coffee files

* Use the current module’s options if it has any, before going searching up the tree

* Don’t mutate passed-in options object
This commit is contained in:
Geoffrey Booth 2017-10-04 17:49:59 -07:00 committed by GitHub
parent 694e69d872
commit a2037e799f
6 changed files with 47 additions and 18 deletions

View File

@ -53,6 +53,8 @@
// Assign paths for node_modules loading
dir = options.filename != null ? path.dirname(fs.realpathSync(options.filename)) : fs.realpathSync('.');
mainModule.paths = require('module')._nodeModulePaths(dir);
// Save the options for compiling child imports.
mainModule.options = options;
// Compile.
if (!helpers.isCoffee(mainModule.filename) || require.extensions) {
answer = CoffeeScript.compile(code, options);
@ -147,19 +149,19 @@
}
}
CoffeeScript._compileFile = function(filename, sourceMap = false, inlineMap = false) {
CoffeeScript._compileFile = function(filename, options = {}) {
var answer, err, raw, stripped;
raw = fs.readFileSync(filename, 'utf8');
// Strip the Unicode byte order mark, if this file begins with one.
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
options = Object.assign({}, options, {
filename: filename,
literate: helpers.isLiterate(filename),
sourceFiles: [filename],
inlineMap: true // Always generate a source map, so that stack traces line up.
});
try {
answer = CoffeeScript.compile(stripped, {
filename,
sourceMap,
inlineMap,
sourceFiles: [filename],
literate: helpers.isLiterate(filename)
});
answer = CoffeeScript.compile(stripped, options);
} catch (error) {
err = error;
// As the filename and code of a dynamically loaded file will be different

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 2.0.1
(function() {
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, i, len, loadFile, path, ref;
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;
CoffeeScript = require('./');
@ -12,8 +12,9 @@
// Load and run a CoffeeScript file for Node, stripping any `BOM`s.
loadFile = function(module, filename) {
var answer;
answer = CoffeeScript._compileFile(filename, false, true);
var answer, options;
options = module.options || getRootModule(module).options;
answer = CoffeeScript._compileFile(filename, options);
return module._compile(answer, filename);
};
@ -72,4 +73,13 @@
};
}
// Utility function to find the `options` object attached to the topmost module.
getRootModule = function(module) {
if (module.parent) {
return getRootModule(module.parent);
} else {
return module;
}
};
}).call(this);

View File

@ -46,6 +46,9 @@ CoffeeScript.run = (code, options = {}) ->
fs.realpathSync '.'
mainModule.paths = require('module')._nodeModulePaths dir
# Save the options for compiling child imports.
mainModule.options = options
# Compile.
if not helpers.isCoffee(mainModule.filename) or require.extensions
answer = CoffeeScript.compile code, options
@ -104,17 +107,19 @@ if require.extensions
Use CoffeeScript.register() or require the coffeescript/register module to require #{ext} files.
"""
CoffeeScript._compileFile = (filename, sourceMap = no, inlineMap = no) ->
CoffeeScript._compileFile = (filename, options = {}) ->
raw = fs.readFileSync filename, 'utf8'
# Strip the Unicode byte order mark, if this file begins with one.
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]
inlineMap: yes # Always generate a source map, so that stack traces line up.
try
answer = CoffeeScript.compile stripped, {
filename, sourceMap, inlineMap
sourceFiles: [filename]
literate: helpers.isLiterate filename
}
answer = CoffeeScript.compile stripped, options
catch err
# As the filename and code of a dynamically loaded file will be different
# from the original file compiled with CoffeeScript.run, add that

View File

@ -5,7 +5,8 @@ path = require 'path'
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
loadFile = (module, filename) ->
answer = CoffeeScript._compileFile filename, no, yes
options = module.options or getRootModule(module).options
answer = CoffeeScript._compileFile filename, options
module._compile answer, filename
# If the installed version of Node supports `require.extensions`, register
@ -48,3 +49,7 @@ if child_process
args = [path].concat args
path = binary
fork path, args, options
# Utility function to find the `options` object attached to the topmost module.
getRootModule = (module) ->
if module.parent then getRootModule module.parent else module

View File

@ -166,3 +166,7 @@ test "using transpile from the Node API requires an object", ->
CoffeeScript.compile '', transpile: yes
catch exception
eq exception.message, 'The transpile option must be given an object with options to pass to Babel'
test "transpile option applies to imported .coffee files", ->
return if global.testingBrowser
doesNotThrow -> transpile 'run', "import { getSep } from './test/importing/transpile_import'\ngetSep()"

View File

@ -0,0 +1,3 @@
import path from 'path'
export getSep = -> path.sep