【smart-transform】取自 Atom 的 babeljs/coffeescript/typescript 智能转 es5 库
简介
有时间研究下开源库的源码,总是会有些收获的。注意到 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 库的更多相关文章
- 大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫
大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫 大众点评的反爬虫手段有那些: 封ip,封账号,字体库反爬虫,css文字映射,图形滑动验证码 这个图片是滑动验证码,访问频率高的话,会出 ...
- APICloud支持Atom编辑器,并建立开发工具核心库
APICloud支持Atom编辑器开发工具 APICloud始终坚持多开发工具支持策略,开发者无论使用Sublime Text3.Eclipse还是Webstorm,都可以在APICloud平台中找到 ...
- 爬取百度贴吧前1000页内容(requests库面向对象思想实现)
此程序以李毅吧为例子,以面向对象的设计思想实现爬取保存网页数据,暂时并未用到并发处理,以后有机会的话会加以改善 首先去百度贴吧分析贴吧地址栏中url后的参数,找到分页对应的参数pn,贴吧名字对应的参数 ...
- APICloud重磅支持Atom编辑器,并建立开发工具核心库
APICloud技术再次升级,不仅支持Atom编辑器开发工具,并推出核心开发工具库,使开发者进行App开发更便捷高效. APICloud支持Atom编辑器开发工具 APICloud始终坚持多开发工具支 ...
- 用浏览器(支持WebSocket)和node-inspector 调试后端(CoffeeScript,Typescript)代码
调试效果 配置 npm安装node-inspector: $ npm install -g node-inspector 配置gulp,gulp可以用 gulp-node-inspector 或 用g ...
- [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 ...
- Webduino Smart 从入门到起飞
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 试用了一下,感觉这板子+WebduinoBlockly在线开发环境,下限低.上限也低,以后肯定要刷其他固件的.举个简单的例子,WB ...
- Tools - Atom编辑器
Atom官网 Atom编辑器的常用插件 预览 document-outline:Show a heirarchical outline of a text document minimap:A pre ...
- Atom实用配置插件for C++
autocomplete-clang 自动补全 autocomplete for C/C++/ObjC using clang autocomplete-python 自动补全 Python pac ...
随机推荐
- WebService的简单运用添加删除
WebService是一种跨编程语言和跨操作系统平台的远程调用技术,简单来说就是将数据存储到项目的文件夹下 .NET中基于DOM核心类 XmlDocument 表示一个XML文档 XmlNode表示X ...
- JAVA中HashMap和Hashtable区别
Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合框架面试题中最常被考的问题,所以在参加任何Java面试之前,都不要忘了准备这一题. 我们先看2个类的定义 public ...
- 使用脚本监控windows服务的方法
以下脚本可监控某一个windows服务,发现其停止就立即重启之. @echo off rem 定义循环间隔时间和监测的服务: set secs=60 set srvname="NetWin ...
- OOAD-设计模式(二)之GRASP模式与GOF设计模式概述
一.GRASP模式(通用责任分配软件模式)概述 1.1.理解责任 1)什么是责任 责任是类间的一种合约或义务,也可以理解成一个业务功能,包括行为.数据.对象的创建等 知道责任——表示知道什么 行为责任 ...
- 基于webuploader.js的单图片上传封装
HTML代码 <div class="manageImgUp">点击图片上传</div> <div class="manageImgUpLc ...
- Vue 国际化 vue-i18n 用法详解
vue-i18n 仓库地址:https://github.com/kazupon/vue-i18n 兼容性: 支持 Vue.js 2.x 以上版本 安装方法:(此处只演示 npm) npm insta ...
- vi 编辑器笔记
摘要: vi从安装到使用 vi从菜鸟到高手 0. vim - Vi IMproved, a programmers text editor 分为 VI和VIM,现在流行的发行版里面VI=VIM 是一个 ...
- ASP.NET Core中间件实现分布式 Session
1. ASP.NET Core中间件详解 1.1. 中间件原理 1.1.1. 什么是中间件 1.1.2. 中间件执行过程 1.1.3. 中间件的配置 1.2. 依赖注入中间件 1.3. Cookies ...
- Android 开发笔记___基本适配器的使用__BaseAdapter
之前用到过ArryAdapter适用于纯文本的列表数据,SimpleAdapter适用于带图标的列表数据,但在实际应用中常常有更复杂的列表,比如同一项中存在多个控件,这时候用前面的两个会比较复杂,而且 ...
- Android 开发笔记___spinner__适配器基础_arrayadapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...