CoffeeScript 2.7 入门指南这门编译为 JavaScript 的小语言及其安装、编译与使用原理【免费下载链接】coffeescriptUnfancy JavaScript项目地址: https://gitcode.com/gh_mirrors/co/coffeescriptCoffeeScript 是一门编译为 JavaScript 的小语言本指南以 documentation/sections/introduction.md 为骨架带你理解其不过是 JavaScriptIts just JavaScript的设计哲学掌握本地/全局安装、命令行执行与编译、语言速览并结合 src/coffeescript.coffee 与 src/index.coffee 源码深入其词法分析→语法分析→代码生成的编译管线以及 Node.js API 与浏览器端的完整使用方式。CoffeeScript 是什么一门编译进 JavaScript 的小语言官方定位见 introduction.md非常精炼CoffeeScript is a little language that compiles into JavaScript——它是一门小语言最终产物是 JavaScript。这一表述背后有两层含义语言足够小语法刻意精简去掉 JavaScript 中繁琐的样板样板代码只保留表达力最强的核心结构编译是唯一运行方式CoffeeScript 源码从不被解释器直接执行而是先被完整编译成等价的 JavaScript再由 JavaScript 引擎运行。在该语言的自我描述中JavaScript 被比喻为外表粗糙awkward Java-esque patina内里有一颗华丽的心gorgeous heart。CoffeeScript 的使命就是把 JavaScript 中真正优雅的部分用一种更简单的方式暴露出来——去掉样板、简化语法但不改变底层语义。Its just JavaScript黄金法则与三大承诺CoffeeScript 的黄金法则是Its just JavaScript不过是 JavaScript。围绕这条法则官方文档给出了三项可以直接验证的承诺一对一编译无运行时解释CoffeeScript 代码逐条编译为等价的 JavaScript运行时不存在任何解释器层。这也意味着不需要引入庞大的运行时库——编译产物就是纯 JS。与现有 JavaScript 生态完全互通你可以从 CoffeeScript 中无缝使用任何已有的 JavaScript 库反之亦然。因为编译产物就是普通 JS模块边界、函数调用、对象传递都不存在语言隔离。输出可读、美观且性能不逊手写 JS编译输出经过 pretty-print 格式化可读性良好由于几乎是一对一的机械转换生成代码的运行速度倾向于与等价的手写 JavaScript 一样快或更快。这一点与许多运行时转译语言有本质区别——没有运行时开销性能损耗只可能来自代码生成的质量而一对一转换保证了这一点。从源码看这种无运行时设计贯彻得很彻底src/coffeescript.coffee 的编译器产出的就是纯文本 JavaScriptjs fragment.code产物中不注入任何框架代码唯一可选的依赖是--transpile时借用的 Babel但那属于可选的旧语法适配层而非语言自身的运行时。环境要求与安装本地安装与全局安装CoffeeScript 的命令行版本以 Node.js 工具的形式发布详见 documentation/sections/installation.md当前仓库的 package.json 声明了当前版本2.7.0运行环境node: 6Node 6 及以上命令行入口bin下提供coffee与cake两个命令安装前请确保已安装 Node.js建议使用最新的稳定版本。安装有两种方式对应两种使用场景方式一本地安装推荐用于具体项目npm install --save-dev coffeescript在项目目录内执行。这样 CoffeeScript 的版本会作为该项目的开发依赖被记录不同项目可以锁定不同版本互不干扰。方式二全局安装便于随处执行.coffee文件npm install --global coffeescript这会全局提供coffee和cake两个命令。一个值得注意的版本解析细节coffee与cake命令会先在当前目录查找本地安装的 CoffeeScript找到就用本地的找不到才用全局的。因此全局与本地可以共存不同版本项目内执行命令时以本地版本为准。关于--transpile的额外依赖如果计划使用--transpile选项参见 documentation/sections/transpilation.md还需要额外安装babel/core——全局安装的 CoffeeScript 对应全局安装 Babel本地安装的对应本地安装 Babel。快速开始执行脚本与编译脚本安装完成后即可通过coffee命令使用见 README.md。直接执行一个 CoffeeScript 脚本coffee /path/to/script.coffee把 CoffeeScript 编译为 JavaScript 文件coffee -c /path/to/script.coffee-ccompile会把.coffee源码编译为同名的.js文件编译产物即纯 JavaScript可直接被 Node.js 或浏览器加载。从源码看编译入口对以下文件扩展名生效src/coffeescript.coffeeexports.FILE_EXTENSIONS FILE_EXTENSIONS [.coffee, .litcoffee, .coffee.md]其中.litcoffee与.coffee.md是文学化 CoffeeScriptLiterate CoffeeScript的文件形式说明编译器对文档型源码同样原生支持。语言速览用一段示例看懂核心语法要快速理解小语言到底长什么样最直接的素材是官方示例 documentation/examples/overview.coffee。它用十几行代码覆盖了 CoffeeScript 的主要语法面# Assignment: number 42 opposite true # Conditions: number -42 if opposite # Functions: square (x) - x * x # Arrays: list [1, 2, 3, 4, 5] # Objects: math root: Math.sqrt square: square cube: (x) - x * square x # Splats: race (winner, runners...) - print winner, runners # Existence: alert I knew it! if elvis? # Array comprehensions: cubes (math.cube num for num in list)对照 documentation/sections/language.md 的语法基础说明可以提炼出这套语法的几个支柱用缩进代替花括号函数、if、switch、try/catch 等代码块一律用缩进界定不再需要{ }。用换行代替分号表达式以换行结尾即终止无需;同一行内塞多个表达式时仍可用分号分隔。省略调用括号传参调用时无需括号隐式调用会向后延伸到行尾或块表达式末尾。例如console.log sys.inspect object会编译为console.log(sys.inspect(object));。后置条件与后置循环number -42 if opposite、math.cube num for num in list这类把条件/循环后置的写法让代码读起来更接近自然语言。-定义函数、...表示 splats可变参数、?表示存在性判断elvis?检查变量是否已定义且非 null/undefined。示例中cubes (math.cube num for num in list)是数组推导式编译后等价于一段循环 push 的 JavaScript——这正是编译为等价 JS的直观体现。编译原理从源码看词法、语法与代码生成一对一编译、无运行时并非口号src/coffeescript.coffee 中的compile函数完整呈现了编译管线tokens lexer.tokenize code, options # ... nodes parser.parse tokens # ... fragments nodes.compileToFragments options # ... js fragment.code整个流程分为四步词法分析Lexerlexer.tokenize把源码字符串切成 token 流。期间还会收集源码中所有IDENTIFIERtoken 作为referencedVars让编译器生成临时变量时避开用户已有的名字避免命名冲突。语法分析Parserparser.parse基于 Jison 生成的文法src/grammar.coffee把 token 流规约为 AST。解析时会检测IMPORT/EXPORT语句——一旦出现自动强制bare模式见下文因为模块语法本身就需要顶层作用域。代码生成Nodesnodes.compileToFragments把 AST 编译为一系列代码片段fragments每个片段携带原始源码的位置信息locationData。拼接输出把片段按顺序拼接成最终 JS 字符串并同步计算行列偏移为生成 source map 做准备见 src/sourcemap.litcoffee。语法错误的报错也做得相当细致parser.yy.parseError会针对意外的缩进意外的标识符非预期的输入结尾等场景生成专门的错误信息并带上精确的位置。Node.js APIcompile、run、eval 与 register除命令行外CoffeeScript 还提供完整的 Node.js API详见 documentation/sections/nodejs_usage.md 与 src/index.coffee。注册扩展名直接requireCoffeeScript 文件require coffeescript/register App require ./app # .coffee 扩展名可省略register让 Node 的模块加载器认识.coffee等扩展名之后require ./app.coffee与require ./app均可工作。编译字符串CoffeeScript require coffeescript eval CoffeeScript.compile console.log Mmmmm, I could really go for some #{Math.pi}compile(code, options)的核心选项与 CLI 选项一一对应选项类型作用sourceMapboolean为 true 时生成 source map返回值从字符串变为{js, v3SourceMap, sourceMap}对象inlineMapboolean为 true 时把 source map 以 base64 编码字符串内联到输出底部注释中filenamestring用于 source map 的文件名可含相对或绝对路径bareboolean为 true 时不输出顶层函数安全包装IIFEheaderboolean为 true 时在输出顶部加入Generated by CoffeeScript头注释transpileobject传入要交给 Babel 的选项对象见 documentation/sections/transpilation.mdastboolean为 true 时返回输入源码的抽象语法树AST执行与求值CoffeeScript.run(code, options)编译并执行一段 CoffeeScript会正确设置__filename、__dirname与相对require()的解析路径src/index.coffee。CoffeeScript.eval(code, options)在类似 Node 的沙箱环境中编译求值CoffeeScript 自带 REPLsrc/repl.coffee即基于此实现。值得一提的是transpile的实现细节Node API 会向编译器注入对 Babel 的引用options.transpile.transpile CoffeeScript.transpile这样像 Webpack 这样的构建工具require(coffeescript)时不会被强制要求安装 Babel见 src/index.coffee。在浏览器中运行与深入学习路径CoffeeScript 的核心编译器不依赖 Node可以在任意 JavaScript 环境中运行documentation/sections/installation.md。仓库为此提供两份浏览器专用构建lib/coffeescript-browser-compiler-modern/coffeescript.js面向现代浏览器lib/coffeescript-browser-compiler-legacy/coffeescript.js面向旧式浏览器。package.json 中通过module与browser字段分别指向这两份构建方便打包工具按环境自动选择。进一步学习可以沿以下仓库资源展开完整语言参考documentation/sections/language.md交互式在线体验与站点示例documentation/site/编译器源码词法 src/lexer.coffee、文法 src/grammar.coffee、AST 节点 src/nodes.coffee、source map src/sourcemap.litcoffee大量可运行的语法示例documentation/examples/。小结CoffeeScript 的立身之本可以浓缩为三句话它是编译为 JavaScript 的小语言它的黄金法则是Its just JavaScript即一对一编译、无运行时、生态互通它的安装与使用都极其轻量npm install后用coffee执行或编译。从本仓库源码可以确认这条无运行时、纯编译的路线贯彻到了编译器每一层——从 lexer 到 parser 再到代码片段拼接最终产出的始终是干净、可读、可直接运行的 JavaScript。【免费下载链接】coffeescriptUnfancy JavaScript项目地址: https://gitcode.com/gh_mirrors/co/coffeescript创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考