简介

有时间研究下开源库的源码,总是会有些收获的。注意到 Atom 插件编写时,可以直接使用 babel, coffeescript 或者 typescript。有些诧异,毕竟 Electron 中内置的 node 引擎,也一定不是完全兼容 es6,更不用说 coffeescript 和 typescript了。所以,必然在加载插件时,Atom 有某种自动转换的操作。刚好最近有一些类似的需求,需要批量以单个文件的方式转换一些其他语法的文件到 es5 兼容的js文件,于是就把 Atom 的转换机制拆分了出来,写成一个 cli。

他山之玉,不敢私藏。如果只是使用,请直接在npmjs上查找:smart-transform

特色定制

毋容置疑,最核心的地方是取自于 Atom 本身。之所以把这个逻辑单独剥离出来,主要是我很羡慕 Atom 插件编写时,各种语法随心使用的舒爽!要是自己项目,也能这么随意,岂不是爽歪歪!!!

为了独立于 Atom 使用,同时又具备一定的通用新,主要定制性体现在:

  • 将逻辑剥离成一个 cli 命令行工具,以后不管自己还是别人,拿来即用。不是每个前端,都很擅长 nodejs,所以我觉得,这还是能方便一些人的。
  • 通过配置文件,允许个性化定制。即,每个项目的输入和输出目录可以通过配置文件来自由配置。现在还不够灵活,只支持指定唯一一个输入文件夹和唯一一个输出文件夹,不过暂时够用了。
  • 引入 uglify-js 进行压缩和混淆。这一点,确实是项目本身的需要,我相信大部分人,都有这个需求吧?另外,之所以直接使用 uglify-js ,当然是因为我不想再额外配置 webpack 呀!!

扔一个 smart-transform.json 配置文件示例上来吧:

{
"in":"./src",
"out":"./lib",
"exclude":["./src/hi-ignore.js"],
"minify":true,
"minifyExclude":["./src/hi-ts.ts"]
}

源码解读

package.json

  "bin": {
"smart-transform": "index.js"
}

比较特殊的是 bin 字段。第一次写 cli 的童鞋,常常因为没有写这个字段,导致没有以全局命令的形式使用自己的工具库。

index.js

这是定制最多的一个文件。它实现的主要功能是,读取具体项目根目录的配置文件 smart-transform.json ,然后根据内部字段,来进行一些个性化的转换操作。

目前支持的操作有:

  • 将指定目录的 babeljs/coffeescript/typescript 转为 es5 兼容的js文件,并输出到另一个目录。
  • 忽略某些文件,不对其进行转换操作。
  • 转换时,可选支持同时进行压缩和混淆操作。压缩和混淆,目前使用的是 uglify-js

代码不长,但是本身有一些 node 相关的代码,所以我就还是贴出来,感兴趣的顺便瞅一眼:

#!/usr/bin/env node
'use strict'
var path = require("path")
var fs = require ('fs-plus')
var fse = require('fs-extra')
var os = require("os")
var {execSync} = require("child_process")
var UglifyJS = require("uglify-js") var argv = require('minimist')(process.argv.slice(2)) var project = argv.project
var configInfo = require(path.resolve(project,"./smart-transform.json")) var inDir = path.resolve(project,configInfo.in)
var outDir = path.resolve(project,configInfo.out)
var minify = configInfo.minify var excludeFiles = configInfo.exclude.map(function (filePath) {
return path.resolve(project,filePath)
}) var minifyExcludeFiles = configInfo.minifyExclude.map(
function (filePath) {
return path.resolve(project,filePath)
}
) fse.ensureDirSync(outDir) var inFiles = fs.listSync(inDir,[".js",".ts","coffee"]) for (var inFile of inFiles) {
if (excludeFiles.includes(inFile)) { // 不需要处理的,直接复制到输出目录
var outFile = path.resolve(project,outDir,path.basename(inFile))
fse.copySync(inFile,outFile)
continue
} var sourceCode = require("./compile-file")(inFile) if (minify && !minifyExcludeFiles.includes(inFile)) {
sourceCode = UglifyJS.minify(sourceCode).code
} var outFile = path.resolve(project,outDir,path.basename(inFile,path.extname(inFile)) + ".js")
fse.ensureFileSync(outFile)
fs.writeFileSync(outFile,sourceCode)
}

compile-file.js

相关预编译逻辑取自原Atom代码中的 src/compile-cache.js 类,主要区别是,禁用代码地图并禁用输出代码内的注释。考虑到项目本身的内部兼容性,并没有直接使用最新版的 Atom 源码演绎。如果自己有其他定制需求,可以直接看 Atom 源码。

这个文件比较出彩的地方是,它把各种类似的语法都使用 COMPILERS 的机制管理。一种语法对应一个 COMPILER。在某些特定情况下,如果你想解析或转换其他类型的文件,只需要修改这个类,新增一个 COMPILER 即可。

'use strict'
var path = require('path')
var fs = require('fs-plus') var COMPILERS = {
'.js': require('./babel'),
'.ts': require('./typescript'),
'.coffee': require('./coffee-script')
} function compileFileAtPath (filePath) {
const extension = path.extname(filePath)
const compiler = COMPILERS[extension] var sourceCode = fs.readFileSync(filePath, 'utf8') if (compiler.shouldCompile(sourceCode, filePath)) {
const compiledCode = compiler.compile(sourceCode, filePath)
return compiledCode
} return sourceCode
} module.exports = compileFileAtPath

babel.js coffee-script.js typescript.js

分别取自 Atom 源码中的 babel.js coffee-script.js typescript.js。有极小的修改,典型的 拿来主义 。有兴趣的,直接去看下源码,此处不做赘述。

注意

使用 bable 的js文件,开头应是以下几种的其中一种,否则无法被识别:

/** @babel */
"use babel"
'use babel'
/* @flow */

参考文章

【smart-transform】取自 Atom 的 babeljs/coffeescript/typescript 智能转 es5 库的更多相关文章

  1. 大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫

    大众点评评论数据抓取  反爬虫措施有css文字映射和字体库反爬虫 大众点评的反爬虫手段有那些: 封ip,封账号,字体库反爬虫,css文字映射,图形滑动验证码 这个图片是滑动验证码,访问频率高的话,会出 ...

  2. APICloud支持Atom编辑器,并建立开发工具核心库

    APICloud支持Atom编辑器开发工具 APICloud始终坚持多开发工具支持策略,开发者无论使用Sublime Text3.Eclipse还是Webstorm,都可以在APICloud平台中找到 ...

  3. 爬取百度贴吧前1000页内容(requests库面向对象思想实现)

    此程序以李毅吧为例子,以面向对象的设计思想实现爬取保存网页数据,暂时并未用到并发处理,以后有机会的话会加以改善 首先去百度贴吧分析贴吧地址栏中url后的参数,找到分页对应的参数pn,贴吧名字对应的参数 ...

  4. APICloud重磅支持Atom编辑器,并建立开发工具核心库

    APICloud技术再次升级,不仅支持Atom编辑器开发工具,并推出核心开发工具库,使开发者进行App开发更便捷高效. APICloud支持Atom编辑器开发工具 APICloud始终坚持多开发工具支 ...

  5. 用浏览器(支持WebSocket)和node-inspector 调试后端(CoffeeScript,Typescript)代码

    调试效果 配置 npm安装node-inspector: $ npm install -g node-inspector 配置gulp,gulp可以用 gulp-node-inspector 或 用g ...

  6. [TypeScript] Transform Existing Types Using Mapped Types in TypeScript

    Mapped types are a powerful and unique feature of TypeScript's type system. They allow you to create ...

  7. Webduino Smart 从入门到起飞

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 试用了一下,感觉这板子+WebduinoBlockly在线开发环境,下限低.上限也低,以后肯定要刷其他固件的.举个简单的例子,WB ...

  8. Tools - Atom编辑器

    Atom官网 Atom编辑器的常用插件 预览 document-outline:Show a heirarchical outline of a text document minimap:A pre ...

  9. Atom实用配置插件for C++

    autocomplete-clang  自动补全 autocomplete for C/C++/ObjC using clang autocomplete-python 自动补全 Python pac ...

随机推荐

  1. leetcode 697. Degree of an Array

    题目: Given a non-empty array of non-negative integers nums, the degree of this array is defined as th ...

  2. openwrt下 samba设置

    1. 增加用户: 可以手工直接修改 /etc/passwd, 增加一行: samba:x:102:100::/home/samba:#也可命令如下opkg updateopkg install sha ...

  3. java基础---字符串string

    1.字符创的概念 java字符串就是Unicode字符序列.例如,串“Java\u2122”由5个Unicode字符J.a.v.a和TM.java没有内置的字符串类型,而是在标准库Java类库中提供了 ...

  4. gevent的同步与异步

    from gevent import spawn,joinall,monkey;monkey.patch_all() import time def task(pid): time.sleep(0.5 ...

  5. C#通过OpenCL调用显卡GPU做高效并行运算

    GPU的并行运算能力远超CPU,有时候我们会需要用到超大数据并行运算,可以考虑用GPU实现,这是一篇C#调用GPU进行运算的入门教程. 1: 下载相关的库: https://sourceforge.n ...

  6. LeetCode 153. Find Minimum in Rotated Sorted Array (在旋转有序数组中找到最小值)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  7. OpenCV Image Watch 调试插件

    昨晚偶然发现vs2012的这个很神奇的插件,对于经常使用opencv的人来说,这个插件无疑是我们的调试神器.今天马上下载试用,感觉超级棒!~以后要想查看图像结果,不用再imshow了! Image W ...

  8. js中判断鼠标滚轮方向的方法

      前  言 LiuDaP 最近无聊,在做自己的个人站,其中用到了一个关于鼠标滚轮方向判断的方法,今天闲来无聊,就给大家介绍一下吧!!!! 在介绍鼠标事件案例前,让我们先稍微了解一下js中的event ...

  9. 2016-2017 ACM-ICPC, Asia Tsukuba Regional Contest D Hidden Anagrams

    题目链接:http://codeforces.com/gym/101158/attachments /* * @Author: lyucheng * @Date: 2017-10-21 12:20:0 ...

  10. Strategic Game

    Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...