-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CS2] Add webpack support #4501
Changes from 4 commits
78ae25e
6cde4b5
665eba1
ca93686
882ff5c
eb8ef8e
45cbdd7
c8df38f
ffac681
def9e25
298bb21
6ab07aa
4bea2c0
e68a622
e776d78
62a9315
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,14 +51,8 @@ run = (args, callback) -> | |
buildParser = -> | ||
helpers.extend global, require 'util' | ||
require 'jison' | ||
parser = require('./lib/coffee-script/grammar').parser.generate() | ||
# Patch Jison’s output, until https://github.com/zaach/jison/pull/339 is accepted, | ||
# to ensure that require('fs') is only called where it exists. | ||
parser = parser.replace "var source = require('fs')", """ | ||
var source = ''; | ||
var fs = require('fs'); | ||
if (typeof fs !== 'undefined' && fs !== null) | ||
source = fs""" | ||
# We don't need moduleMain, since the parser is unlikely to be run standalone | ||
parser = require('./lib/coffee-script/grammar').parser.generate(moduleMain: ->) | ||
fs.writeFileSync 'lib/coffee-script/parser.js', parser | ||
|
||
buildExceptParser = (callback) -> | ||
|
@@ -135,7 +129,7 @@ task 'build:browser', 'merge the built scripts into a single file for use in a b | |
var CoffeeScript = function() { | ||
function require(path){ return require[path]; } | ||
#{code} | ||
return require['./coffee-script']; | ||
return require['./browser']; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain this? Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for logic consistency. Since |
||
}(); | ||
|
||
if (typeof define === 'function' && define.amd) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
{ | ||
"name": "coffee-script", | ||
"main": [ | ||
"lib/coffee-script/coffee-script.js" | ||
"lib/coffee-script/browser.js" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine. I’ve used Bower, it’s only for frontend (browser-based) JavaScript. |
||
], | ||
"description": "Unfancy JavaScript", | ||
"keywords": [ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
# `text/coffeescript` script tags, source maps via data-URLs, and so on. | ||
|
||
CoffeeScript = require './coffee-script' | ||
CoffeeScript.require = require | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for catching this. |
||
compile = CoffeeScript.compile | ||
|
||
# Use standard JavaScript `eval` to eval code. | ||
|
@@ -18,6 +17,10 @@ CoffeeScript.run = (code, options = {}) -> | |
options.shiftLine = on | ||
Function(compile code, options)() | ||
|
||
CoffeeScript.register = -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it seems like the strategy here is to declare this dummy method, and then in the Node version this gets overridden with the real method? This is confusing, to say the least. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is confusing because Because coffee's browser test is not actually ran in a browser. It runs in node environment and the first call in the That's why I set it to a NOP implementation to pass the test for now. I could configure a test script that actually runs in browser with one of the methods mentioned above. But I think that should be a separate PR/issue for discussion since it requires adding more devDependencies. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On a separate note, I also think |
||
|
||
module.exports = CoffeeScript | ||
|
||
# If we're not in a browser environment, we're finished with the public API. | ||
return unless window? | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,6 @@ | |
# contains the main entry functions for tokenizing, parsing, and compiling | ||
# source CoffeeScript into JavaScript. | ||
|
||
fs = require 'fs' | ||
vm = require 'vm' | ||
path = require 'path' | ||
{Lexer} = require './lexer' | ||
{parser} = require './parser' | ||
helpers = require './helpers' | ||
|
@@ -156,101 +153,13 @@ exports.nodes = withPrettyErrors (source, options) -> | |
else | ||
parser.parse source | ||
|
||
# Compile and execute a string of CoffeeScript (on the server), correctly | ||
# setting `__filename`, `__dirname`, and relative `require()`. | ||
exports.run = (code, options = {}) -> | ||
mainModule = require.main | ||
# Compile and execute a string of CoffeeScript | ||
exports.run = (code, options = {}) -> throw new Error 'Not implemented' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why export this if it just throws an error? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is that |
||
|
||
# Set the filename. | ||
mainModule.filename = process.argv[1] = | ||
if options.filename then fs.realpathSync(options.filename) else '<anonymous>' | ||
# Compile and evaluate a string of CoffeeScript | ||
exports.eval = (code, options = {}) -> throw new Error 'Not implemented' | ||
|
||
# Clear the module cache. | ||
mainModule.moduleCache and= {} | ||
|
||
# Assign paths for node_modules loading | ||
dir = if options.filename? | ||
path.dirname fs.realpathSync options.filename | ||
else | ||
fs.realpathSync '.' | ||
mainModule.paths = require('module')._nodeModulePaths dir | ||
|
||
# Compile. | ||
if not helpers.isCoffee(mainModule.filename) or require.extensions | ||
answer = compile code, options | ||
code = answer.js ? answer | ||
|
||
mainModule._compile code, mainModule.filename | ||
|
||
# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment). | ||
# The CoffeeScript REPL uses this to run the input. | ||
exports.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 | ||
# define module/require only if they chose not to specify their own | ||
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] | ||
# use the same hack node currently uses for their own REPL | ||
_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 = compile code, o | ||
if sandbox is global | ||
vm.runInThisContext js | ||
else | ||
vm.runInContext js, sandbox | ||
|
||
exports.register = -> require './register' | ||
|
||
# Throw error with deprecation warning when depending upon implicit `require.extensions` registration | ||
if require.extensions | ||
for ext in @FILE_EXTENSIONS then do (ext) -> | ||
require.extensions[ext] ?= -> | ||
throw new Error """ | ||
Use CoffeeScript.register() or require the coffee-script/register module to require #{ext} files. | ||
""" | ||
|
||
exports._compileFile = (filename, sourceMap = no, inlineMap = no) -> | ||
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 | ||
|
||
try | ||
answer = compile stripped, { | ||
filename, sourceMap, inlineMap | ||
sourceFiles: [filename] | ||
literate: helpers.isLiterate filename | ||
} | ||
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 | ||
# information to error so it can be pretty-printed later. | ||
throw helpers.updateSyntaxError err, stripped, filename | ||
|
||
answer | ||
exports.register = -> throw new Error 'Not implemented' | ||
|
||
# Instantiate a Lexer for our use here. | ||
lexer = new Lexer | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,106 @@ | ||
# Loader for CoffeeScript as a Node.js library. | ||
exports[key] = val for key, val of require './coffee-script' | ||
# Node.js Implementation | ||
CoffeeScript = require './coffee-script' | ||
fs = require 'fs' | ||
vm = require 'vm' | ||
path = require 'path' | ||
|
||
helpers = CoffeeScript.helpers | ||
compile = CoffeeScript.compile | ||
|
||
# Compile and execute a string of CoffeeScript (on the server), correctly | ||
# setting `__filename`, `__dirname`, and relative `require()`. | ||
CoffeeScript.run = (code, options = {}) -> | ||
mainModule = require.main | ||
|
||
# Set the filename. | ||
mainModule.filename = process.argv[1] = | ||
if options.filename then fs.realpathSync(options.filename) else '<anonymous>' | ||
|
||
# Clear the module cache. | ||
mainModule.moduleCache and= {} | ||
|
||
# Assign paths for node_modules loading | ||
dir = if options.filename? | ||
path.dirname fs.realpathSync options.filename | ||
else | ||
fs.realpathSync '.' | ||
mainModule.paths = require('module')._nodeModulePaths dir | ||
|
||
# Compile. | ||
if not helpers.isCoffee(mainModule.filename) or require.extensions | ||
answer = compile code, options | ||
code = answer.js ? answer | ||
|
||
mainModule._compile code, mainModule.filename | ||
|
||
# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment). | ||
# The CoffeeScript REPL uses this to run the input. | ||
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 | ||
# define module/require only if they chose not to specify their own | ||
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] | ||
# use the same hack node currently uses for their own REPL | ||
_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 = compile code, o | ||
if sandbox is global | ||
vm.runInThisContext js | ||
else | ||
vm.runInContext js, sandbox | ||
|
||
CoffeeScript.register = -> require './register' | ||
|
||
# Throw error with deprecation warning when depending upon implicit `require.extensions` registration | ||
if require.extensions | ||
for ext in CoffeeScript.FILE_EXTENSIONS then do (ext) -> | ||
require.extensions[ext] ?= -> | ||
throw new Error """ | ||
Use CoffeeScript.register() or require the coffee-script/register module to require #{ext} files. | ||
""" | ||
|
||
CoffeeScript._compileFile = (filename, sourceMap = no, inlineMap = no) -> | ||
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 | ||
|
||
try | ||
answer = compile stripped, { | ||
filename, sourceMap, inlineMap | ||
sourceFiles: [filename] | ||
literate: helpers.isLiterate filename | ||
} | ||
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 | ||
# information to error so it can be pretty-printed later. | ||
throw helpers.updateSyntaxError err, stripped, filename | ||
|
||
answer | ||
|
||
module.exports = CoffeeScript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is brilliant. Thanks for solving this better than my hack.