当 AMD 遇上 FIS

2015-01-02  来源:本站原创  分类:产品  人气:10 

前言

也许说AMD不知道这是啥,但说requirejs就都懂了。没错AMD就是一种模块定义的接口(API),用来定义模块间依赖以及自身暴露什么内容的一种规范。而requirejs就是一种实现了这些接口的 AMD Loader。

说到requirejs相信不少人都已经对它爱不释手了,它真是给我们的开发带来了不少便利性。只要我们每个模块都简单的遵守这个规则

// app.js define(function (require, exports, module) {     var a = require('a');     var b = require('b');      exports.action = function () {}; }); 

然后,简单一段

// 程序入口 require(['/app'], function(app) {     app.action(); }); 

就把指定的所有依赖都自动加载进来了。

于是,我们慢慢的会把一个大功能模块,拆得非常小,让每一个模块都只干最少的事,而且我们很享受这样的拆分,因为这样带给我们非常棒的可维护性。

问题

当我们把代码拆得非常小之后,直接用 requirejs 去加载的时候,很容就会出现这种情况。

当 AMD 遇上 FIS

性能好不好,可想而知。 于是乎,我们需要把这些依赖打包起来。如何打包?当然是r.js他提供一种指定入口文件将所有的依赖打包成一个文件的工具。常用的做法是,配置一个列表给每个入口程序都打成一个文件, 然后手动把所有的入口文件地址换成打包后的。

这样基本上能满足需求,但是仍然还有些问题?

  • 每个入口及其依赖打成了一个包,多个页面间公用的依赖被打包到了多处,页面切换公用依赖的缓存完全没有被利用起来。
  • 每个入口地址我都得手动替换新地址,麻烦!
  • 有些 amd 模块写法,需要 requirejs 在运行期需要将 function 转成字符分析依赖,性能会不会有问题?

优化方案

如果你使用FIS, 这些问题就都迎刃而解,而且还能带来其他更多的好处。你可以先试用一下这个fis amd demo。然后,让我让我来细说 fis 针对 amd 模块做了哪些优化以及在 fis中使用将带来哪些好处。

全新的编译插件

使用过 fis mod.js 方案的同学应该知道。原来对 js 模块依赖的解析只是简单粗暴的分析了两种用法。

即:

  1. require('xxxx')
  2. require.async('xxxx', cb);

将依赖生成 map.json, 然后,模块定义就是让用户去遵循 commonjs 规范,FIS 在编译期会自动封装成 amd module,其实就是包了一层define

define(moduleId, funciton(require, exports, module) {     // 源 JS 内容。     var a = require('a');     var b = require('b');      exports.action = function() {}; }); 

在页面渲染的时候,程序会根据 map.json 中依赖的申明,提前把同步依赖加载进来。

其实这样已经满足各种开发需求了,而且非常高效实用。但是随着外界开源组件的兴起以及 bower 的推广,目前已有大量的第三方组件涌现,而且他们都有一个特点,就是采用的 amd 规范。问题就是,这些组件拿过来放在 fis 中,没法直接用,必须得手动修改才能使用。

于是,全新的amd 依赖解析插件诞生了。

它会分析所有AMD规范中定义的各种写法。

有了它,模块间的依赖实际上在编译期就已经知道了,并把的依赖关系生成到了map.json, 这样只要借助工具,就可以提前把所需模块的全部依赖提前加载进来,而不需要让 requirejs 在前端用 js 去动态加载。

怎么让 requirejs 不重复加载?只要提前加载进来的模块,都带上 module id, 然后 require 入口引用的 module id 与之一致,requirejs 是不会重复加载的。这个自动补充 module id 的工作在这个插件中自动完成了,默认是自动把该文件在工程下面的路径去掉 .js 后缀的值作为 module id。

有了这些依赖信息,我们还可以利用 combo 或者pack 打包将依赖合成一个文件输出,这样就减少了多个请求带来的网络开销,以后可以愉快拆分模块代码了。

更好的模块化开发体验

一个大型的项目,一般情况都会包括三种类型的模块。

  1. 第三方模块
  2. 当前项目可公用的模块
  3. 应用级模块,每个页面都不一样。

针对这三种性质的模块,我们都比较喜欢放在不同的目录。这样带来的坏处是,不管我用绝对定位还是相对定位,都是如此的别扭。

感谢AMD规范中制定了3个非常便于查找模块路径的配置, 我们把这几个配置也应用到了编译期。

通过fis.config.set('settings.postprocessor.amd') 来设置。

fis.config.set('settings.postprocessor.amd', {     baseUrl: '.',      // 查看:https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md#paths-     // 不同的是,这是编译期处理,路径请填写编译路径。     paths: {         jquery: 'modules/libs/jquery/jquery.js',         bootstrap: 'modules/libs/bootstrap/js/bootstrap.js',         jqueryui: 'modules/libs/jquery-ui/ui/',         app: './modules/app',         css: './modules/css.js'     },      // 查看:https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md#packages-     // 不同的是,这是编译期处理,路径请填写编译路径。     packages: [          {             name: 'zrender',             location: 'modules/libs/zrender',             main: 'zrender'         },          {             name: 'echarts',             location: 'modules/libs/echarts',             main: 'echarts'         }     ] }); 

baseUrl

当设置了 baseUrl 后,所有绝对路径的模块查找都是基于此目录查找的,对于使用频率比较高的模块,可以把改目录设置成 baseUrl. 比如第三类模块。

paths

对于一些常用的库,可以通过这个来设置短引用或者说别名。比如:jquery,bootstrap

另外需要说明的是,有些第三方库在发布的时候,都是指定的别名依赖。如: jquery-ui 一系列。这种模块有很多很多。

(function( factory ) {     if ( typeof define === "function" && define.amd ) {          // AMD. Register as an anonymous module.         define([             "jquery",             "./core",             "./widget",             "./position"         ], factory );     } else {          // Browser globals         factory( jQuery );     } }(function( $ ) { }); 

所以,为了不动第三方源码,我们也需要明确的设置这个别名。

paths: {     jquery: 'modules/libs/jquery/jquery.js' } 

其次,我们可以给这类性质的“当前项目可公用的模块”,设置个 paths. 如:

paths: {     libs: '/widget/libs/' } 

这样对于内部公共模块目录下模块的引用无论你的代码在什么位置就可以这样引用。

define(function(require, exports, module) {     var dialog = require('libs/dialog');     ... }); 

packages

作用基本上和paths差不多,只是它更适合配置成一个完整的模块包。如 zrender、echarts 等等。

更智能的包装

在 FIS 开发环境中,你还可以编写满足 commonjs 规范的 js 模块,FIS 会自动包装成 AMD 模块以便于在浏览器中运行。如果直接就是 AMD 规范编写的,那就更不用说了。但是既不是 amd, 也不是 commonJS 规范的模块怎么办呢?

再次感谢 AMD 规范中的shim配置,同样,FIS 把这个配置应用到了编译期。

fis.config.set('settings.postprocessor.amd', {     // 设置 bootstrap 依赖 jquery     // 更多用法见:https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md#shim-     // key 为编译期路径。     shim: {         'modules/libs/bootstrap/js/bootstrap.js': ['jquery'],          'some/ohther/path.js': {             deps: ['libs/a', 'libs/b'],             exports: 'some.thing',             init: function (a, b) {                 return some.thing + 'another';             }         }     } }); 

FIS 在包装模块组件的时候,会读取此配置,自动把改模块的依赖和暴露的对象添加上。当然 requirejs 本来也能做这个事,但是考虑到性能开销,这个工作更应该在编译期完成。

更高级的插件加载机制

AMD 除了可以处理 JS 模块依赖加载,还能处理其他依赖加载,怎么做?就是利用amd plugin loader

换句话说 amd 还可以用来加载 css or 前端 tpl。在fis amd demo例子中有个示例,就是利用 css amd 插件来动态加载 css 文件。amd 依赖解析插件不仅只处理模块查找,还处理插件资源查找。

require(['css!./styles/demo.css'], function () {     document.getElementById('main').innerHTML = '<div id="demo">It works!</div>'; }); 

这样的好处是,对于当前工程下面的静态资源引用,可以用相对路径,也可以用绝对路径,且可以给资源加 md5 戳,甚至可以最终部署到 cdn 上,而不用改一句源码。

更智能的打包

FIS 的 pack打包方案本来就比较灵活,通过正则或者 glob语法,可以把任意多的文件合并成一个。同时当使用depscombine 插件的时候也支持 r.js 那种方式,将入口文件的所有依赖合并进来,只要在合并入口 JS 依赖前,配置一条规则把公用依赖部分的 js 合并成一个文件,就能把公共依赖抽离出来,这样公共的部分缓存就可以被利用起来。

fis.config.set('pack', {     // 依赖也会自动打包进来, 且可以通过控制前后顺来来定制打包,后面的匹配结果如果已经在前面匹配过,将自动忽略。     'pkg/zrender.js': ['modules/libs/zrender/zrender.js'],     'pkg/echarts.js': ['modules/libs/echarts/echarts.js'],      'pkg/bootstrap_jquery.js': ['modules/libs/bootstrap/js/bootstrap.js'],      'pkg/jquery_ui_tabs.js': ['modules/libs/jquery-ui/ui/tabs.js'] }); 

当 AMD 遇上 FIS

当配置好规则后,简单的一个fis release -p命令就把所有被打包文件的请求变成合并后的了,源码什么都不用改,如果想愉快的调试代码,release 时不带-p参数,又自动变成了非打包方案了。

被遗忘的技术细节

现在 require 入口调用,会自动把其同步依赖加载进来。但是,等等,貌似怪怪的,因为 require 入口的调用其语义就是异步调用,怎么变成同步的语义了?

按语义来应该针对 require('deps') 引用做同步处理,但是这种用法并不在 amd 规范中定义,amd 规范定义的同步调用用法,只出现在模块定义内部。所以没办法,把模块定义外的 require 用法当成同步来用吧(模块定义内部的 require 异步语义保持不变)。当然一定要当作异步来用也是可以的,只要在 require 调用的前面加段注释 fis async。这样编译期就会把找到依赖标记成异步依赖。

由于 FIS 对于静态文件是支持打包合并、加 md5 戳和部署到 cdn 的,也就是对于 js 的引用,我们是要忽略他的 release 后的路径的。如果纯同步依赖,似乎没问题,但是异步依赖怎么办呢?我在 require 里面的 module id 当然还是得用源码路径ID方便调试定位。

那么怎么转换路径呢?

原来 mod.js 方案是读取map.json生成一个异步所需的 resoucemap 表,通过 require.resourceMap({xxx}) 设置给 mod.js,这样在异步加载模块的时候,可以对应找到实际的存放地址。

amd 方案里面也是采用同样的方式,只是利用的是 amd 规范中的paths设置,根据 map.json 自动生成程序中所需要的异步依赖的路径转换规则,这样的话,fis 不是一定只能用 mod.js 才能做模块化开发,以后换成其他所有的 amd loader,比如还有 ecom 出的esl.js;

require.config({"paths":{     "modules/libs/zrender/lib/excanvas": "/pkg/zrender",     "modules/libs/zrender/tool/util": "/pkg/zrender",     "modules/libs/zrender/config": "/pkg/zrender",     "modules/libs/zrender/tool/log": "/pkg/zrender",     "modules/libs/zrender/tool/guid": "/pkg/zrender",     "modules/libs/zrender/tool/env": "/pkg/zrender",     "modules/libs/zrender/tool/event": "/pkg/zrender",     "modules/libs/zrender/Handler": "/pkg/zrender",     "modules/libs/zrender/tool/matrix": "/pkg/zrender",     "modules/libs/zrender/shape/mixin/Transformable": "/pkg/zrender",     "modules/libs/zrender/tool/color": "/pkg/zrender",     "modules/libs/zrender/shape/Base": "/pkg/zrender",     "modules/libs/zrender/shape/Path": "/pkg/zrender",     "modules/libs/zrender/tool/area": "/pkg/zrender",     "modules/libs/zrender/shape/Text": "/pkg/zrender",     "modules/libs/zrender/shape/Rectangle": "/pkg/zrender",     "modules/libs/zrender/loadingEffect/Base": "/pkg/zrender",     "modules/libs/zrender/shape/Image": "/pkg/zrender",     "modules/libs/zrender/Painter": "/pkg/zrender",     "modules/libs/zrender/shape/Group": "/pkg/zrender",     "modules/libs/zrender/Storage": "/pkg/zrender",     "modules/libs/zrender/animation/easing": "/pkg/zrender",     "modules/libs/zrender/animation/Clip": "/pkg/zrender",     "modules/libs/zrender/animation/Animation": "/pkg/zrender",     "modules/libs/zrender/zrender": "/pkg/zrender",     "modules/libs/zrender/shape/Circle": "/pkg/echarts",     "modules/libs/zrender/tool/math": "/pkg/echarts",     "modules/libs/zrender/shape/Ring": "/pkg/echarts",     ... }); 

另外,amd 依赖解析插件除了解析依赖,实际还会做一个小优化,就是会把 factory 中的各种依赖,提前放置在 define 的第二个参数里面。这样的好处是, amd loader 再也不要用正则查找 factory 函数体的 require 了,直接读第二个参数就能把所有依赖拿到。

总结

既然 fis 在编译 amd 模块的时候,优化了这么多,依赖处理啊, ID 生成啊之类的。那么我们还需要一个如此庞大的 require.js 吗? 当然不需要,FIS 组结合编译的处理,提供一个最小 amd loader 叫mod-amd.js仅仅 200 多行, 但是他暂时不支持 amd plugin loader,因为没有足够的理由要去支持它,像模板加载,样式加载,fis 中有更优的处理方案。

好吧,回头正视原来提出的那些问题。

  • 每个入口及其依赖打成了一个包,多个页面间公用的依赖被打包到了多处,页面切换公用依赖的缓存完全没有被利用起来。

    采用 fis pack 打包配置,很好的解决这个问题。

  • 每个入口地址我都得手动替换新地址,麻烦!

    在 fis 里面编译的时候加上 -p 就足够。

  • 有些 amd 模块写法,需要 requirejs 在运行期需要将 function 转成字符分析依赖,性能会不会有问题?

    编译期,自动将依赖前置。

Ok,今天先写到这,有说得不对的,欢淫吐槽。

相关文章
  • 当 AMD 遇上 FIS 2015-01-02

    前言 也许说AMD不知道这是啥,但说requirejs就都懂了.没错AMD就是一种模块定义的接口(API),用来定义模块间依赖以及自身暴露什么内容的一种规范.而requirejs就是一种实现了这些接口的 AMD Loader. 说到requirejs相信不少人都已经对它爱不释手了,它真是给我们的开发带来了不少便利性.只要我们每个模块都简单的遵守这个规则 // app.js define(function (require, exports, module) { var a = require('

  • MySQL批量插入遇上唯一索引避免方法 2014-06-02

    以前使用SQL Server进行表分区的时候就碰到很多关于唯一索引的问题,今天我们来了解MySQL唯一索引的一些知识:包括如何创建,如何批量插入,还有一些技巧上SQL,感兴趣的朋友可以了解下 一.背景 以前使用SQL Server进行表分区的时候就碰到很多关于唯一索引的问题:Step8:SQL Server 当表分区遇上唯一约束,没想到在MySQL的分区中一样会遇到这样的问题:MySQL表分区实战. 今天我们来了解MySQL唯一索引的一些知识:包括如何创建,如何批量插入,还有一些技巧上SQL:

  • IE 当eval遇上function的处理 2014-08-30

    在IE下,当eval遇上function,IE下会出现怪异情况,我们用例子一步步说明 情况1:eval里没有function,直接执行: eval("alert('ss');");//所有浏览器正确均输出 情况2:eval里有function,function立即执行: eval("(function(){alert('ss');})();");//所有浏览器正确输出 情况3:eval里有function,使用变量保存function引用并调用该function:

  • 为什么搜房网没有遇上强劲的对手? 2014-09-12

    巧了,本人2005年曾经在搜房网的一家分公司工作过.那时候的搜房网还没上市,不过在业内也已经初露锋芒,在业内开始有很好口碑和知名度.据我当时分公司的总经理说,搜房老总莫天全是个很低调的人,虽然当时已经是30多个分公司的老总,在房地产业也是个人物,但是做事很低调.但是个很务实的人,老莫认为在搜房网还没有在全国布好局,在市场份额上没有十拿九稳地占有绝对优势之前绝不高调. 如果对房地产互联网营销公司有所了解的人,都知道那时候有一家比搜房网还早的,专注做房地产网络营销的网站叫做焦点房地产网.那时候的焦点

  • Scrum遇上管理3.0 2015-03-31

    <Scrum遇上管理3.0>是Arne Ahlander在2014印度本地Scrum聚会上做的一个报告. 管理3.0是一套领导.管理和发展敏捷团队或组织的方法.Arne Ahlander是认证的Scrum培训师(Certified Scrum Trainer),他是瑞典Aqqurite公司创始人和首席顾问.在2014年印度本地Scrum聚会上,他做了一个关于如何将最新管理理念运用于增强Scrum实践的报告.他首先讨论了Scrum实施中的管理方面好与不好的例子.他把听众分成若干小组,然后请大家写

  • 为三位创业者遇上的障碍所作的断症和开出的处方 2014-07-13

    无论你是一年资历的创业菜鸟还是二十年经验的老手,在创业期间都必定会遇上困难和障碍.以下所收录的,是我们的专家团队为三位创业者遇上的障碍所作的断症和开出的处方,希望各位读者们看过之後也有所得着. 无名成衣 (No Name Clothing) 症状:三十三岁的Robert Smith,是伊利诺州Loves Park无名成衣的创办人.专门售卖T-shirts的无名成衣已经有两年历史,预计零七年生意额将会达到八十至一百万美元的水平.虽然公司财政状况良好,但Smith一直也未能建立一个可靠的营销及业务发

  • 当"牛"遇上"鸡"--职场新秀应当共谋发展 2014-10-22

    作为职场新人,踏实肯干的"牛"和左右逢源的"鸡",谁能在职场生存中游刃有余?2008年11月8日,由华夏时报和肯德基联手举办的当"牛"遇上"鸡"--职场能力发展论坛在中国人民大学逸夫会议中心第一报告厅热烈举行.与会职场专家.跨国公司高管.知名海归人才齐举一堂,就本次论题展开精彩的讨论. 在职场中,有两种类型的人才较为典型,一种可以叫做"牛"型人才,一种叫做"鸡"型人才."牛&q

  • 实战:当jquery遇上了json 2015-02-22

    jquery:大家一定很熟悉,就算没用过,也应该听说过,不多做介绍,不知道的赶紧google一下. json:一种数据格式,她小巧,轻盈.在javascript的世界中,完胜XML. jquery和json都是因为小与巧而被广泛使用,今天把她们弄到一起,大家应该没意见吧. 废话了一把,现在言归正传, 通过这篇文章你可以得到以下收获: 1.jqury如何用ajax的形式调用后台asp.net页面生成的json数据 2.jquery简单的dom操作 3.送本jquery的开发手册给大家(大家慢慢去研

  • 当while read 遇上ssh 2013-08-17

    [Bash Shell 程序设计]当while read 遇上ssh 先看一段简化过的BASH SHELL代码 TODAY=`date +%Y%m%d` SUFFIX="tar" CONF=the_config_file i=0 while read HOST SRCPATH DSTPATH do (( i++ )) if [ "X${HOST:0:1}" = "X#" -o ${#DSTPATH} -eq 0 ] then #忽略注释行及少于3

  • MySQL当批量插入遇上唯一索引 2013-12-26

    一. 背景 以前使用SQL Server进行表分区的时候就碰到很多关于唯一索引的问题:Step8:SQL Server 当表分区遇上唯一约束,没想到在MySQL的分区中一样会遇到这样的问题:MySQL表分区实战. 今天我们来了解MySQL唯一索引的一些知识:包括如何创建,如何批量插入,还有一些技巧上SQL: 这些问题的根源在什么地方?有什么共同点?MySQL中也有分区对齐的概念?唯一索引是在很多系统中都会出现的要求,有什么办法可以避免?它对性能的影响有多大? 二.过程 (一) 导入差异数据,忽略

  • 在IE下,当eval遇上function 2014-03-27

    在IE下,当eval遇上function,IE下会出现怪异情况,我们用例子一步步说明 情况1:eval里没有function,直接执行: eval("alert('ss');");//所有浏览器正确均输出 情况2:eval里有function,function立即执行: eval("(function(){alert('ss');})();");//所有浏览器正确输出 情况3:eval里有function,使用变量保存function引用并调用该function:

  • 当菜鸟遇上?客之二:端口扫描 2013-12-19

    黑客的探测方式里除了侦察IP,还有一项--端口扫描.通过"端口扫描"可以知道被扫描的计算机哪些服务.端口是打开而没有被使用的(可以理解为寻找通往计算机的通道). 一.端口扫描 网上很容易找到远程端口扫描的工具,如Superscan.IP Scanner.Fluxay(流光)等(如图1),这就是用"流光"对试验主机192.168.1.8进行端口扫描后的结果.从中我们可以清楚地了解,该主机的哪些非常用端口是打开的:是否支持FTP.Web服务:且FTP服务是否支持&quo

  • 当菜鸟遇上?客之三:QQ防盗篇 2013-12-30

    上网了吧,用Q了吧,被盗了吧,正常.想上网吧,想用Q吧,不想被盗Q吧,正常.那就来了解一些盗QQ方面的知识吧! 一.名词解释 1.字典 所谓字典,其实就是一个包含有许多密码的文本文件.字典的生成有两种方式:用字典软件生成和手动添加.一般字典软件能生成包含生日.电话号码.常用英文名等密码的字典,不过由于这样生成的字典体积大,而且不灵活,所以黑客往往会手动添加一些密码到字典里去,形成一个"智能化"的密码文件. 2.暴力破解 所谓暴力破解,其实就是用无数的密码来与登录QQ的密码进行核对,直到

  • [机器学习]当机器学习遇上计算机视觉 2013-12-30

    这是两部分中的第一部分,由英国剑桥微软研究所的JamieShotton,AntonioCriminisi和SebastianNowozin合著.第二部分将会稍后被发表在这儿. 计算机视觉,是开发计算机算法用以自动理解图像内容的领域,在1960年代左右从人工智能(ArtificialInteligence)和认知神经科学(cognitiveneuroscience)衍化出来.为了"解决"视觉问题,麻省理工大学(MIT)在1966年开设了一个暑期项目,该项目在当时广受关注但是人们发现对于该

  • 当菜鸟遇上?客(5):?客入侵窗口:IIS 2014-01-15

    使用IIS(Internet Information Server)可以让有条件的用户轻易地建立一个本地化的网站服务器同时提供流量不大的Http访问,及一些文件传输的FTP服务,不过正是这个IIS(本章内容只针对IIS建立的服务器做介绍)成为黑客攻击的目标或者入侵本机的"云梯". 攻击 针对IIS的攻击方式可以说是五花八门,使用大量的数据请求,使IIS超负荷而停止工作,是初级黑客的必修课程.不过鉴于篇幅不对IIS的攻击做详细介绍,而是说说入侵IIS. 自IIS问世以来,其漏洞或缺口即层

  • 当视觉设计师遇上产品经理.开发工程师- 2014-09-30

    我是一个初入互联网的视觉设计师,和以往做设计感受最大的不同就是:一个设计的最终定稿会受到多方面的挑战,有来自产品经理的,来自开发的,来自测试的-等等.那如何在其他团队成员的面前不卑不亢,游刃有余地应对呢?下面这篇文章给了我很大的启发,特别分享给大家. 产品经理.开发工程师和市场策划专员等产品利益关系人认为--视觉设计师在整个团队中没有突出的地位.难道这个论断是正确的吗?我们还能用哪些实例来向这些利益关系人证明视觉视觉设计的重要性呢? 尽管,视觉设计师在他的职业生涯中或者是在某个产品开发进程中会面

  • 微博与社会化招聘:当51job遇上社会化招聘还能前程无忧吗? 2013-10-30

    当51job.智联招聘等传统的网络招聘还在打到广告战的时候,一种新型的招聘方式--社会化招聘正在慢慢地崛起,越来越来的企业尝试通过微博来招聘员工,特别是一些初创企业,创始人直接在微博上求贤的现象更是比比皆是,而最近新浪微博更是与大街网推出了微招聘,与传统招聘网站开始正面争夺市场. 我们通过新浪微博搜索"微博招聘"这个关键字单单今年1月份到7月底就有10几万之多,也有很多专门发布招聘信息的微博账号,如@实用微招聘和@微博招聘信息,他们的粉丝数都在10万以,以电商社会化活动家@mrbran

  • 竞争性分析:当电子商务遇上恶意炒作 2014-02-08

    网盛科技日前发布公开信,否认与对阿里的攻击事件有关. 但网盛文章认为阿里的群发询盘模式"导致供应商血拼价格,相互残杀","收了客户的钱,但是并不能成交,这种行为是欺诈,是对浙商信用的破坏"云云.在我看来,这即使不是对阿里的恶毒攻击,至少也是一个很幼稚.很无知的论调. 首先阿里是一个电子商务平台,提供的是一种交易环境和交易场所式的服务,是买卖双方的信息桥梁:阿里自己既非供应商,也非采购商,所以何出成交欺诈之言? 更重要的是,电子商务的高效率不仅在于流通渠道的缩短,也在

  • 当设计师遇上前端开发 2014-05-31

    作为互联网产品设计师,在和前端开发人员沟通时你是否常常会听到这样的声音: -- "大姐,给点专业精神好不好,这个表格是自适应的,你这样设计页面不好扩展啊-" --"用ajax不是不行,不过你要事前给我说嘛,你不说我怎么知道呢,你说了我就知道了嘛-" 面对这些回答,除了欲哭无泪,你有没有想过是什么原因导致出现这样沟通偏差,有没有解决的办法呢?设计师需要了解哪些知识才能和前端开发人员来更好的合作呢? 首先得从这两者之间都有哪些不同说起.我认为最主要原因在于设计师和前端开

  • 百年一遇的奇怪问题:当IE遇上.NET Framework 4.5 2014-07-18

    一个是微软的 IE,一个是微软的 .NET Framework 4.5,竟然出现如此离奇的问题,不得不让人想起一句诗句:"本是同根生,相煎何太急". 下面我们来一睹这个百年一遇的奇怪问题. 问题背景 最近将 job.cnblogs.com 项目中的 Entity Framework 升级到了 5.0,据说 EF 5.0 在 .NET Framework 4.5 之下性能会有大幅提升(相关博文),于是在服务器上安装了 .NET Framework 4.5. 安装后发现,.NET Fram