Tag Archives: Javascript

TypeScript or Pure JavaScript?

I was really excited when I got to know that Microsoft had released a new language called TypeScript.

Type, which means better intellisense and type safety that serve the purpose of its existence — scalable.

Why is this important?

  1. Type safety.
    Hate bugs? There’s a joke we talk a lot, which is also a truth: “The weirder the bug is, the stupider mistake we might have made.” And the compiler would now worry about some of these things for us, like typo or forgetting to change a property after copying some code.
  2. Tooling.
    When a project grows, the API might become too complex for the developer himself to remember. Visual Studio provides great experience on JavaScript intellisense by actually running the code in background. But on the one hand, it would usually requires a special rewritten-version of intellisense file. On the other hand, it would become very slow when code lines add up. (I wrote a framework called VEJIS which picks up the powerful intellisense feature of Visual Studio, provides support for classes, interfaces, delegates, etc. But it’s a runtime framework and there’s no type safety. Checkout http://vilic.github.io/vejis/)
    TypeScript makes code navigation much easier and most of the time, we won’t even need to navigate because the information we need is there with intellisense.

Searching articles related to TypeScript would result in many that are comparing it to CoffeeScript and Dart. It’s really weird because some (maybe most) of these articles treats TypeScript the same sort of thing as CoffeeScript simply because both of them compile to JavaScript. And I have even seen an opinion saying: “If you want to build a big application I’d recommend going with CoffeeScript as you end up writing less code.”

WHAT? Maybe that buddy haven’t really met something big enough.

CoffeeScript won’t do things better for people like me, who have been writing JavaScript since day one. People like to talk about the “good part” when it comes to CoffeeScript, but… does it really take more effort for one person who starts with JavaScript to remember how to avoid the bad part than learning a syntactically brand new language?

And actually I have never given the “good or bad part” thing much credit.

So back to the topic, TypeScript or pure JavaScript? Ignoring things other than the languages themselves, I go with TypeScript without hesitate. Because it’s a superset of JavaScript, and it provides much more useful features for larger-scale applications. And, the key point, I write relatively large-scale web applications. However, to use TypeScript in productive environment, there would be more to think about.

  1. Poor IDE and editor plugin support.
    There have been several IDEs with TypeScript support integrated. Visual Studio, of course, would be one of them. But the experience coding using Visual Studio can’t even beat the experience on TypeScript Playground. This really bothers me a lot. No automatic-quote/bracket completion, no snippets, strange indent behavior, etc.
    I haven’t tried TypeScript in WebStorm, maybe it would have done better job. Also ReSharper for Visual Studio may improve the experience according to some comments I’ve seen.
    There are also some plugins for Sublime Text, but… you know.
  2. Poor NPM package and cross-project referencing support.
    Actually TypeScript is capable generating definition files so that it should have been friendly to these things. But the reality is not that awesome…
    I have proposed a convention on distributing TypeScript-written NPM package, and hoping it would make things better.

If finally you choose TypeScript, here’s some information and techniques that might help.

  1. Definitions of popular JavaScript libraries.
    I don’t have any crush on open source, but here open source does it right. So far most of the declarations I need for specific JavaScript libraries can be found in DefinitelyTyped, and it’s becoming of better quality and of larger covering.
    You may install the declarations though NuGet on Visual Studio, to make things work after installation, try to refresh the solution tree.
  2. Temporary “best” practice for cross-project referencing in Visual Studio.
    In project properties page TypeScript Build tab, check “Combine JavaScript output into file” (and specify a file name) and “Generate declaration files”.
    Create a “.d.ts” file in parent project and add the declaration file generated by sub project to it as a reference.
    Visual Studio would compile all “.ts” files included in the project into the JavaScript file specified, so make sure other test files are excluded from the project or you may want to create another project for samples and tests.
    When it comes to NPM packages, I haven’t figure out an acceptable way. But following that convention I mentioned earlier in this post, I may try to write an extension for Visual Studio which would pick up declaration files automatically, wrap it up with ambient module name and add the modified declaration file into the project that’s using that module. It would also be useful even if we are using these packages ourselves without publishing it to npmjs.org only. (BTW, symlink would save you hours if you didn’t know.)

I have now a symptom trying to make everything typed, it slows me down starting up coding a project, but speeds my lines up once the skeleton completes. Hope you enjoy writing in TypeScript if you need it.

(BTW it would be great if TypeScript add support for await/async based on Promise.)

Original link of this archive: http://vilic.info/blog/archives/1136
本文的原始链接: http://vilic.info/blog/archives/1136

关于 “动态” 模板的憧憬

大概是一年多以前还在一淘实习的时候, 萌生了这么个想法, 如果一个模板可以是基数据驱动的, 那能胜任的工作就从现在更多的格式化字符串和其他一些简单的东西变得更加复杂和强大. 当然因为是数据驱动的, 在写这样一个模板时, 也将体会到数据驱动带来的逻辑上的优势. 不过也是因为各种原因, 当时做完第一步的模板解析之后, 就没再继续了. 因为要做好, 略微困难, 而且不像原来做Prever什么的时候, 虽然代码总量大, 但可以分开成很多小块, 今天断开一点, 明天稍微回想下继续写就好.

除此之外, 另外一个数据驱动的小库, Drop(未更新), 倒是做了出来, 虽然还有诸多不完善, 到最后肯定也免不了被重写的命运… 但就实践来看, 这种方式的确是很实用的.

那回归可能会基于Drop(顺便Drop最近的版本是基于VEJIS的)之上的这个模板系统, 之前取名叫Sonne, 以后多半也是这个名字吧. 前些时候了解了下lisp语言, 才发现它和lisp之间还有一点点相似之处. 这里贴一段很久很久以前写的示例.

<!-- comments -->
{header
    <img src="xxx.jpg" />
    <h1>{title}</h1>
    <p><span>{tip}</span><span>{tip}</span>{description}</p>
}
{nav 
    <ul>
    {items[]
        <li>
        {#link {
            {@hash page}
            {@value home}
            {@inner {home}}
            {@class nav-link}
        }}
        </li>
    }
    </ul>
    {#if {
        {@if {#cookies loggedin}}
        {@then <a href="#logout">log out</a>}
        {@else <a href="#login">log in</a>}
    }}
}
{content
    <div>
    {#async {
        {@type html}
        {@url content.ashx?page={#hash { {@name page} {@default home} }}}
        {@loading
            loading...
        }
        {@loaded {data}}
    }}
    </div>
}
{sidebar
    <div>
    {#async {
        {@type json}
        {@url sidebar.ashx?page={#hash { {@name page} {@default home} }}}
        {@loaded
            {data
            <ul>
                {list[]
                <li>{text}</li>
                }
            </ul>
            }
        }
    }}
    </div>
}

还是大概能看出来吧? 大括号开始, 紧接一个字母的, 是闭包, 在里面可以直接书写文本内容. #号开头的则是组件(当然, 你可以定义自己的组件), 里面的@开头的是属性, 也可以理解成参数. 包括if都是以组件的形式存在的, 所以这种一般性让Sonne具有更强的扩展性. 好吧其实, 还有个原因是我实现起来会相对容易, 不用处理更多的特殊化的语法… :P

再以#async组件为例, 可以看到url属性对应的字符串中存在另一个组件, 所以实际上, 组件是有 “返回值” 的, 可以是字符串, 也可以是文档片段. 因为是数据驱动, 当数据发生变动的时候, #async组件所管理的文档片段也就随之变化了, 并且因为是组件, 也可以很容易地实现定时更新数据.

当时一直期望这东西能改变Web开发的某个分支, 其实现在也有这个想法, 但也不知道最后能不能做出来… 记得后来看到过某个库, 也有类似的功能, 但印象里并没有Sonne强大,,, 具体哪里没有… 忘记了…

Original link of this archive: http://vilic.info/blog/archives/889
本文的原始链接: http://vilic.info/blog/archives/889

TypeScript 小感

今天在一个Windows Phone的论坛看到微软出了个TypeScript, 瞬间想到高中时期自己构想的InviScript和Prever 2… 不过后来因为种种原因, InviScript只是停留在了构想上, 而Prever 2也在开发初期流产. 不过后来取代InviScript的, 则是VEJIS.

很高兴的是, 自己, 当然也一定是很多当时和我面临同样问题的人的设想, 最后被很好的实现. 其实Google也有一个叫Dart的语言, 不过与和InviScript的相似度赶TypeScript和InviScript的相似度就差太多了… 而且我个人也不喜欢Dart的语法, 感觉抛弃了很多JavaScript的精髓.

TypeScript和InviScript应该说都是JavaScript的超集, 并且相同的, 最终都会编译成JavaScript. 这也是我为什么取名为InviScript的原因. 意为INVIsible SCRIPT. 只在开发过程中存在.

不过同样高兴的是, 我选择了一个对于我个人而言, 更现实的实现, 即VEJIS. 虽然独立开发完InviScript也并非不可能, 但成本显然太过高昂…

VEJIS通过各种各样的函数, 从语法层面加强了JavaScript的功能, 提供了可以媲美甚至超过TypeScript的类/类型/模块工具, 当然因为VEJIS是运行时的脚本库, 代价就是一定的性能损耗. 这也限制了VEJIS的运用场景. 但就目前的实践经验来看, 在正确使用VEJIS的情况下, 这种影响是可以忽略不计的.

现在正在开发VEJIS 0.5, 重写了核心代码, 并提供了更多, 更具扩展性的功能. 甚至是delegate_, 虽然还没有决定是否会最终使用. 不论最终是中间语言形式的TypeScript更容易被接受, 还是运行时的VEJIS, 都一定程度反应了Web开发的趋势. 这点上, 我觉得Franky或许不会永远是对的. :P

Original link of this archive: http://vilic.info/blog/archives/885
本文的原始链接: http://vilic.info/blog/archives/885

正则表达式匹配JavaScript字符串字面量

第一次遇到这个问题, 是大概两年前写代码高亮, 从当时的解决方案到现在一共有三代, 嘎嘎. 觉得还是算越来越好的.

第一代:

//那个时候自己正则还不算很精通, 也没有(?:...)这种习惯, 是以寻找结束引号为入口写出的这个正则. 思路混乱, 也存在错误.
//比如像字面量 "abc\\\"", 则会匹配为 "abc\\\", 而正确的结果应该是 "abc\\\"".
var re = /('('|.*?([^\\]'|\\\\'))|"("|.*?([^\\]"|\\\\")))/g;

第二代:

//这个匹配其实和第一代思路基本相同, 也是寻找结束引号, 通过给\\添加*解决了第一代的bug.
var re = /(['"])(?:.*?[^\\](?:\\\\)*)?\1/g;

第三代:

//老实说第三代是昨天晚上出题的时候突然想出来的(后来又修改过), 支持多行字符串字面量, 思路也有了较大的转变, 从匹配结束引号变味了匹配中间内容.
var re = /(['"])(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*?\1/g

这里有一个正则里非常常用的技巧, 姑且称之为 “抢占”, 在诸如/a|./这样的正则里, 越靠前越先匹配, 通过 “抢占” 一些字符, 可以避开很多麻烦. 说起来有些抽象, 在上面这个例子里, /\\[\s\S]/就可以很自然地抢到 \” 这样的转义字符, 所以不必担心转义字符中的 ” 给匹配造成影响. 这是局部的 “抢占”, 还有更大范围的, 比如注释里的字符串或者字符串里的注释, 只要在同一个正则中, 把相关匹配都写入, 则一定是先遇到的优先. 如 /(注释正则)|(字符串正则)/g, 可以先通过这样的方式, 把内容匹配出来, 再进行进一步判断处理.

虽然可能对于多数人来说, 用处不大, 但万一呢? Best wishes~

Original link of this archive: http://vilic.info/blog/archives/848
本文的原始链接: http://vilic.info/blog/archives/848

Visual Studio 2012 for Web JavaScript自动完成体验

从Visual Studio 2005用到2010, 现在又用上了2012. 实际上之前就有体验过, 但并没有测试什么细节, 今天偶然想到, 对自己感兴趣的几个细节进行了测试, 感受是: It’s just AWESOME!

之前喜欢VS的JavaScript自动提示的原因, 是因为它会在某个环境执行你的代码, 并且用真实的结果给以智能提示, 如:

 

但VS 2010的时候, 类似的功能并不能体现到函数的实参上:

我一直很期待这个功能, 因为如果有它, 在更新自己VEJIS库的intellisense文件之后, 可以实现相当全面的自动提示. 结果, 它真的支持了!

但不仅仅是如此! 另外一个相当棒的功能就是支持异步, 比如异步加载脚本, 还有setTimeout. 先说可能大家不如我关心的setTimeout. 之后在介绍VEJIS的时候会提到前者.

除此之外, 智能提示还对数组的提示进行了优化, 会根据数组中之前出现的数据类型猜测之后出现的类型.

除了这些关于代码执行的提示, VS 2012对于代码注释的提示也有改进, 不过不是说让你写注释更方便, 而是让你写的注释被看得更方便. 并且支持多行, //和/**/都可以. 虽然之前也有<summary>等一些列的注释可以实现这样的功能, 但还是有点繁琐.

那接下来, 我就针对VEJIS谈谈对于VS 2012智能提示特性的进一步应用(这个时候在文件开头添加脚本引用了). 首先是动态加载.  在VEJIS里, require_函数用于动态加载一个脚本文件, 并且该文件会以<script>标签的形式添加到文档中. 例中动态加载的是我面向数据的一个基础库.

接下来是关于函数实参的, 像上面看到的那样, VS 2012可以根据函数被首次调用时传入的参数, 给实参加上提示, 但我们平时书写的时候, 多数时候是先写完函数再去调用. 当然, 在VEJIS下这种境况稍有不同, 因为VEJIS的函数支持重载, 也是需要指定类型的. 这样一来, 稍作修改, 就可以实现如下的功能.

同时, 因为之前说到的对于数组的提示支持, 让我还可以对VEJIS中的params类型进行处理.

又因为对于setTimeout的支持, VEJIS中类的提示也得到了加强, 虽然这个可能解释起来不是那么直观, 毕竟牵涉到其实现了.

强悍吧~ 话说如果是VEJIS老些的版本, 还支持with_, return_这些东西, 分别用于确定this和返回值的类型, 那配合上VS 2012, 就可以实现媲美强类型语言的自动提示了, 所以… 其实我已经动心开发下一个版本, 添加上这些支持. 囧. VS 2012除了这些运行时间的提示优化之外, 还增加了对很多常见对象的支持, 比如XMLHttpRequest.

顺便不得不提的是, Visual Studio 2012 for Web也有Express版, 也就意味着这么强大的工具是免费的! 各位前端同学们也加入VS阵营吧!

Original link of this archive: http://vilic.info/blog/archives/822
本文的原始链接: http://vilic.info/blog/archives/822