使用requirejs缓存问题时怎么解决文件版号和增量更新的问题

Grunt 中使用 requirejs 合并和压缩文件的配置问题 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
最近在看jQuery源码 。。 简直云里雾里
jQeury是怎么样把这么多源文件合并混淆为一个jQuery.ver.min.js文件的呢
Release脚本
其实这和Grunt没什么太大的关系… 主要还是Jquery自己写了一些task来处理自己特殊的业务逻辑和项目构建,甚至包括了googleCDN,MicrosoftCDN release等内容。
自己的项目一般用不到这么复杂的…
非常感谢 0 0
以前只注意到了第一个文件
build/tasks/build.js 里有一个 grunt 注册
grunt.registerTask( “custom”, function() {
var args = this.args,
modules = args.length ? args[ 0 ].replace( /,/g, “:” ) : “”;
grunt.log.writeln( “Creating custom build…\n” );
grunt.task.run([ “build::” + (modules ? “:” + modules : “”), “uglify”, “dist” ]);
所以一直以为 运行一个 grunt custom 就会生成一个合并压缩的文件 感觉很神奇
// Trace dependencies and concatenate files
requirejs.optimize( config, function( response ) {
grunt.verbose.writeln( response );
grunt.log.ok( “File '” + name + “’ created.” );
}, function( err ) {
done( err );
这个函数好像很重要 requirejs 官网 在nodejs中使用requirejs页面有这个函数的介绍 。。 但是看不懂。。
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的静态资源(JS、CSS)的版本化、优化及增量部署 - 为程序员服务
静态资源(JS、CSS)的版本化、优化及增量部署
Web前端性能优化中很重要的一个部分是文件加载的优化,静态文件在客户端缓存的做法可减少请求量,减小服务器和带宽压力的同时让页面加载更顺畅,提升浏览体验。
所以在服务环境中(产品上线后),一般会通过header允许浏览器缓存,并设置一个过期时间(Expires)。但若在Expires期内对资源文件做修改,客户端仍由缓存读取旧版文件而非从服务器加载,则可能造成样式破坏或脚本报错等问题。这就要求我们在开启缓存的同时,在文件更新后通知客户端更新缓存文件,也就是这里要说的“版本化”——对静态文件uri中加入版本信息,每次文件改动的同时更新版本信息,告知浏览器文件版本,从而确保始终调用最新的资源文件。
常见的做法是将版本信息加入到资源文件uri中的QueryString部分,如WordPress对jQuery库文件的引用
/wp-includes/js/jquery/jquery.js?ver=1.8.3(QueryString用红色标记)
按照规范,这么做是没有问题的,因为任何动态资源都不应进行缓存,但偏偏有部分浏览器未严格执行规范,造成此做法存在浏览器兼容性问题。
针对此问题,比较彻底的解决办法是将版本信息加入到资源文件uri中的路径或者文件名部分。
/wp-includes/js/jquery/jquery.js(路径部分用红色标记,文件名部分用蓝色标记)
但这样一来,每次文件改动都需进行重命名操作,将给文件管理带来不便。我们可通过配置rewrite规则将资源文件请求uri中的版本信息去除来规避此问题。
分两边做:
在资源文件名中加入版本信息,确保客户端请求资源文件时加载到最新版本;
服务器配置rewrite规则,在接收到文件请求时将请求uri中的版本信息去除,避免文件管理上的麻烦。
具体到厝边项目中,我们使用的是在文件名结尾处加入以“=V”标识起始的版本信息,如对jQuery库文件的引用:
/servtools/lib/jquery=V80.js
目标资源文件为“/servtools/lib/jquery.js”,但页面上引用的uri文件名中的“=V80”是由文件哈希值计算而来,每次文件改动都会变化,文件名变化则浏览器当作新的文件向服务器请求。
服务器接到uri为“/servtools/lib/jquery=V80.js”的请求后,按rewrite规则将起始标识“=V”至文件后缀“.js”的版本信息(红色标记)部分去除,读取的是实际资源文件“/servtools/lib/jquery.js”。
所以以下这些路径请求到的实际都是同一个文件
版本信息的加入,是在网站编译时完成的,编译时通过正则匹配,将模板文件中对指定目录下css、js文件的引用uri获取,读取文件哈希值计算版本号,然后在中文件名加入该信息。
编译时能做的另外一个小优化是对静态文件使用子域名,如来访问图片、音乐、css、和js等,好处有三点:
无cookie信息
静态文件部署前进行合并、压缩也是前端性能优化的一个重要途径,在厝边项目我们使用了完成这些工作。得益于nodejs中丰富的模块,我们得以在投入较少的时间和学习成本后,每次发布仅需一个命令行即可完成这些优化,使有限的人力能够更多的投入到开发工作中,这对于像我们这样的创业团队尤为可贵。
css压缩:cssmin
js压缩:uglify(gruntjs)
js模块打包:requirejs(r.js)
js模板预编译:handlebars
优化后的文件不覆盖原文件,而是在文件名后缀部分之前加入发布标识“.pub”,如“/servtools/lib/jquery.js”,压缩后文件为“/servtools/lib/jquery.pub.js”,在服务器上同时保留两份。通过rewrite规则将不带“.pub”标识的请求返回带“.pub”标识的文件内容,这样做的目的是,若在非工作时间发现严重错误,可直接使用未优化的文件排错、改名后重新发布,减小对工作环境依赖,同时确保通过Web无法直接访问未优化的源文件。
由于具体规则与服务器环境和程序上下文关联紧密,这里仅探讨思路,正则匹配和rewrite规则代码这里也没必要公布。我作为前端一枚都能想得到的规则,想必也难不到您。
php 正则:
/*l开头如localhost、 为调试模式;
为预发布模式;
127.0.0.1、 为发布模式。
function isLocal(){ //访问
return strpos($_SERVER['SERVER_NAME'], ‘l’)=== 0;
function isTag(){ //访问
return strpos($_SERVER['SERVER_NAME'], ‘tag’)=== 0;
function isPublished(){
return !(isLocal()|| isTag());
/* 读取文件上次修改时间作为版本号加入url路径 */
function autoVer($url, $fileRoot= “../”, $keepExtension= true){
$path = pathinfo($url);
$pubStr= isLocal()? ”: ‘.pub’;
$verStr = ‘=V’.substr(md5_file($fileRoot.$path['dirname']. ‘/’. $path['filename']. $pubStr. ‘.’. $path['extension']), 2, 2);
$notVer= strpos($path['filename'], ‘!ver’);
$extension= $keepExtension? ‘.’ .$path['extension']: ”;//是否保留后缀
$host= (!isPublished()|| $notVer)? ”: ‘///’;//是否加入域名
$file_ver= $notVer? str_replace(‘!ver’, ”, $path['filename']): $path['filename']. $verS//文件名含’!ver’则不进行版本化
return $host. $path['dirname']. ‘/’. $file_ver. $
$compile_file= preg_replace(“/(?&!\/)(servtools|skin\/default|sysadmin)\/(.+)\.(js|css)/e”, “autoVer(‘$0′)”, $compile_file);
nginx write 规则:
location ~ ^/(servtools|skin/default|sysadmin)/(.+)=(.*).(js|css)$ {
set $path $1;
set $file $2;
set $version $3;
set $ext $4;
rewrite ^.*$ /$path/${file}.$
location ~ ^/(servtools|skin/default|sysadmin)/([^.]+)(.js|.css)$ {
set $dir $1;
set $pathName $2;
set $dotExt $3;
rewrite ^.*$ /$dir/$pathName.pub$dotE
.htaccess rewrite 规则:
RewriteEngine on
#Rules for Versioned Static Files 转.pub文件
#RewriteRule ^(servtools|skin/default|sysadmin)/(.+)=(.+)\.(js|css)$ $1/$2.pub.$4 [L]
#Rules for Versioned Static Files
RewriteRule ^(servtools|skin\/default|sysadmin)\/(.+)=(.+)\.(js|css)$ $1/$2.$4 [L]
版本管理软件svn
每工作日例行的增量部署开始于下班前半小时,一般十分钟内完成。每月或每次有重大改动,进行一次版本合并,并重传全部网站文件。
以上是个人在所参与项目中关于网站文件部署的一些实践心得,也希望有经验者参与到交流中来。
分享本文到:
版权申明:
转载请注明作者、出处及原文链接:
(C) 2010 作者及版权归属:
(R) 联络作者:. 写于异年同日:2010:
关?生活,关注互联网。
原文地址:, 感谢原作者分享。
您可能感兴趣的代码菜鸟问个问题,requirejs的入口文件是有且只有一个吗?假设我有两个页面,一个首页一个内容页面,index.html和content.html,我也要分别都包含main.js吗?这样的话只有首页用到的模块和只有内容页面用到的模块就不能区分了吧,一股脑全部塞到main.js里好像不好吧。还是有什么机制可以有页面级别的入口文件,比如index.html和content.html都只包含main.js,但是main.js能够判断当前页面真正需要哪些模块,比如判断当前页面是index.html就只加载index.js模块。不知道我说清楚了没有....百度谷歌了好久,没找到准确答案,求大神解惑!
我也有这个疑问,查了github上的资料,对于多个页面的话,requirejs的config是可以做到多个页面共享的,而每个页面的有自己单独的入口js ,每个入口js首先会加载配置路径的文件,然后再写自己页面的逻辑
具体例子:/requirejs/example-multipage
congfig多个页面共享 就得嵌套两层require方法,是不是木有别的好些的方法了
写下你的评论...
写下你的评论...
写下你的评论...
写下你的评论...
写下你的评论...
Copyright (C)
All Rights Reserved | 京ICP备 号-2,Web前端程序员
&blockquote&先说明一个现状,很多公司前端不了解后端,也不理解业务逻辑。都只是做一些“切图”工作。就需要后端掌握一些的前端技能。&b&一个优秀的前端必须了解一些后端基础知识&/b&&/blockquote&&br&&br&1. 需要后端熟悉 HTML 并将 HTML “翻译”为后端模板(jsp php)&br&2. 前端不会也不想写AJAX,导致后端需要写AJAX相关前端代码(但因为不是全职前端,很多功能不能做到理性状态)&br&&br&小型项目是没问题的,因为业务逻辑简单。业务逻辑稍微复杂一点的项目就会处处碰壁。如果后端很强悍就不会有什么问题(后端熟练使用 JS)&br&&br&----&br&根据你描述的信息,你无法改变前端同事的技能水平。有三种解决方法&br&&br&&b&1. 辞职&/b&&br&&b&2. 提升自己部分前端技能&/b&&br&&b&3. 等待前端同事成长&/b&&br&&br&----&br&&br&&blockquote&1.后台程序员要做的工作是不是把后台接口做出来就好?使用ajax对接的时候,ajax这部分代码是后台程序员去写吗?网页改成jsp的时候,是后台程序员去做吗? &/blockquote&&br&后端程序员只需要提供数据相关接口,AJAX代码应该是前端写。网页改成 jsp 最好的方式是让前端写 jsp 。&a href=&///?target=http%3A//fmsjs.org/view.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&模拟后端模板引擎渲染&i class=&icon-external&&&/i&&/a& 对应的工具可以用 &a href=&///?target=http%3A//fmsjs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&FMS - FMS&i class=&icon-external&&&/i&&/a& (前端控制后端模板的方式我已经实践2年多) 感兴趣可以加我 QQ 我给你配一套前端本地开发环境,能在让前端在本地写 jsp。并且自动生成数据约定文档。&br&&br&&br&&blockquote&2.HTML页面也可以通过ajax与后台交互,也可以通过对uri的处理获得路径参数,有没有必要改成jsp页面呢?&br&&/blockquote&很多团队为了解耦将所有数据传输都通过 AJAX 处理,这是不对的。应该根据业务场景去考虑用什么方式。方法可参考 &a href=&///?target=https%3A///nimojs/blog/issues/13& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前后端数据交互方法 · Issue #13 · nimojs/blog · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&&blockquote&3.目前的微信端web开发需不需要用到前台UI框架,比如weui,bootstrap?jq呢?&br&&/blockquote&你不应该过问这方面的问题,即使是前端是新手,也应该让他自己做前端框架技术选型。除非你是技术总监,或者你也熟悉前端。&br&&br&&br&说一下我们目前的情况吧&br&&br&前端用自己写的 Node 工具在本地写 PHP Smarty 模板,事先需要跟后端约定数据。最终创建一个这样的数据交互文档 &a href=&///?target=http%3A//smarty.fmsjs.org/fms/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前端数据模拟服务器&i class=&icon-external&&&/i&&/a& 。然后在本地写AJAX相关代码写 Smarty 模板即可。&br&&br&&img src=&/f43f0cd813dfb59ba002a4_b.png& data-rawwidth=&636& data-rawheight=&729& class=&origin_image zh-lightbox-thumb& width=&636& data-original=&/f43f0cd813dfb59ba002a4_r.png&&&br&我们前端是直接写 Smarty 的不是写 HTML&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&{include file=&include/header1.php&}
&title&Index&/title&
{include file=&include/header2.php&}
&div class=&row container&&
&div class=&col-md-6&&
&h2&新闻&/h2&
{foreach $news as $this}
&a href=&{$this.link}&&{$this.title}&/a&
{/foreach}
&a href=&/news/& class=&btn btn-default&&查看更多&/a&
&div class=&col-md-6&&
&h2&留言&/h2&
{foreach $message as $this}
{$this.text} - &strong&{$this.nickname}&/strong&
{/foreach}
&a href=&/message/& class=&btn btn-default&&查看更多&/a&
{include file=&include/footer1.php&}
&/code&&/pre&&/div&&br&这么做的原因是:&a href=&///?target=http%3A//fmsjs.org/translate-template.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&后端将HTML翻译成模板&i class=&icon-external&&&/i&&/a&
先说明一个现状,很多公司前端不了解后端,也不理解业务逻辑。都只是做一些“切图”工作。就需要后端掌握一些的前端技能。一个优秀的前端必须了解一些后端基础知识1. 需要后端熟悉 HTML 并将 HTML “翻译”为后端模板(jsp php)2. 前端不会也不想写AJAX,…
这种非常坑,直接报错不给详细信息。我是用 stream-combiner2 解决的&br&&br&&a href=&///?target=https%3A///nimojs/gulp-book/blob/master/chapter7.md%23stream-combiner2& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gulp-book/chapter7.md at master · nimojs/gulp-book · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&&a href=&///?target=https%3A///gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gulp/combining-streams-to-handle-errors.md at master · gulpjs/gulp · GitHub&i class=&icon-external&&&/i&&/a&&br&&blockquote&Combining streams to handle errors&br&&br&By default, emitting an error on a stream will cause it to be thrown unless it already has a listener attached to the errorevent. This gets a bit tricky when you're working with longer pipelines of streams.&br&By using stream-combiner2 you can turn a series of streams into a single stream, meaning you only need to listen to theerror event in one place in your code.&br&Here's an example of using it in a gulpfile:&/blockquote&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&kd&&var&/span& &span class=&nx&&combiner&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'stream-combiner2'&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&uglify&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'gulp-uglify'&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&gulp&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'gulp'&/span&&span class=&p&&);&/span&
&span class=&nx&&gulp&/span&&span class=&p&&.&/span&&span class=&nx&&task&/span&&span class=&p&&(&/span&&span class=&s1&&'test'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&combined&/span& &span class=&o&&=&/span& &span class=&nx&&combiner&/span&&span class=&p&&.&/span&&span class=&nx&&obj&/span&&span class=&p&&([&/span&
&span class=&nx&&gulp&/span&&span class=&p&&.&/span&&span class=&nx&&src&/span&&span class=&p&&(&/span&&span class=&s1&&'bootstrap/js/*.js'&/span&&span class=&p&&),&/span&
&span class=&nx&&uglify&/span&&span class=&p&&(),&/span&
&span class=&nx&&gulp&/span&&span class=&p&&.&/span&&span class=&nx&&dest&/span&&span class=&p&&(&/span&&span class=&s1&&'public/bootstrap'&/span&&span class=&p&&)&/span&
&span class=&p&&]);&/span&
&span class=&c1&&// any errors in the above streams will get caught&/span&
&span class=&c1&&// by this listener, instead of being thrown:&/span&
&span class=&nx&&combined&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'error'&/span&&span class=&p&&,&/span& &span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&error&/span&&span class=&p&&.&/span&&span class=&nx&&bind&/span&&span class=&p&&(&/span&&span class=&nx&&console&/span&&span class=&p&&));&/span&
&span class=&k&&return&/span& &span class=&nx&&combined&/span&&span class=&p&&;&/span&
&span class=&p&&});&/span&
&/code&&/pre&&/div&
这种非常坑,直接报错不给详细信息。我是用 stream-combiner2 解决的Combining streams to handle errorsBy…
这个问题的分类是前端开发,那么以被提问者是前端的情况来回答这个问题。&br&&br&首先:&b&这个需求不明确,且此问题应该是产品经理去考虑的,不应该丢给前端解决。&/b&&br&&br&---------------------------------------------------------&br&&br&如果遇到这种坑的时候,前端应该&b&向产品经理提出『技术建议』和『解决方案』&/b&,让产品经理明确需求。千万不要前端擅自决定并执行。&br&&br&其他答案已经给出了一些技术建议和解决方案。&br&比如:&br&1.
草稿应该是变更时立刻做保存。这样你开多少页面都能确保你存的是你最后想要的,因为用户编辑了
&a data-hash=&8366575cfcfb919baedbd19& href=&///people/8366575cfcfb919baedbd19& class=&member_mention& data-editable=&true& data-title=&@小爝& data-tip=&p$b$8366575cfcfb919baedbd19&&@小爝&/a&&br&2. 多个页面中某个页面修改后, 同步到其他页面, 或者作出提示
&a data-hash=&dcca380425ecb01db245481& href=&///people/dcca380425ecb01db245481& class=&member_mention& data-editable=&true& data-title=&@匿名用户& data-tip=&p$b$dcca380425ecb01db245481&&@匿名用户&/a&&br&&br&需求不明确的情况下即使**给出具体的技术方案都无法解决问题**。只有先&b&帮助产品经理明确需求&/b&,然后与后端沟通商量出实现方案才能解决问题。
这个问题的分类是前端开发,那么以被提问者是前端的情况来回答这个问题。首先:这个需求不明确,且此问题应该是产品经理去考虑的,不应该丢给前端解决。---------------------------------------------------------如果遇到这种坑的时候,前端应该向产品经…
MD!,其实我想说直接学 nodejs ,用 commonjs 先熟悉起来什么是模块化开发。编译用 browserify&br&&br&否则对于初学者来说又 AMD 又 CMD 又 CommonJS 包装成 AMD CMD 不是要玩死人么?&br&&br&偏个题,学习模块化时要注意 :&br&&blockquote&很多人觉得模块化开发的工程意义是复用,我不太认可这种看法,在我看来,模块化开发的最大价值应该是分治,是分治,分治!(重说三)。&a data-hash=&e9306aab1b61e74e7ae6& href=&///people/e9306aab1b61e74e7ae6& class=&member_mention& data-editable=&true& data-title=&@张云龙& data-tip=&p$b$e9306aab1b61e74e7ae6&&@张云龙&/a&&/blockquote&
MD!,其实我想说直接学 nodejs ,用 commonjs 先熟悉起来什么是模块化开发。编译用 browserify否则对于初学者来说又 AMD 又 CMD 又 CommonJS 包装成 AMD CMD 不是要玩死人么?偏个题,学习模块化时要注意 :很多人觉得模块化开发的工程意义是复用,我不太认…
有兴趣可以现在直接把 npm3 用起来(建议自己玩玩,官方未推荐使用前不建议用于正式环境)&br&&a href=&///?target=https%3A///package/npm3& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&/package/npm3&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&div class=&highlight&&&pre&&code class=&language-text&&npm install -g npm3
npm3 install
npm3 search
&/code&&/pre&&/div&
有兴趣可以现在直接把 npm3 用起来(建议自己玩玩,官方未推荐使用前不建议用于正式环境)npm install -g npm3
npm3 install
npm3 search
搬运我在另外一个主题的答案&br&-----&br&在此介绍几种常用的前后端数据交互方法,并给出使用建议。以提高前后端协同开发的效率。 &br&&b&目录:&/b&&br&&br&1. HTML赋值&br&2. JS赋值&br&3. script填充JSON&br&4. AJAX获取JSON&br&5. WebSocket实时传输数据&br&6. 总结&br&&br&&b&1. HTML赋值&/b&&br&输出到 Element 的 value 或 data-name &br&&div class=&highlight&&&pre&&code class=&language-text&&&input type=&hidden& value=&&?php echo $user_?&& /&
&div data-value=&&?php echo $user_?&&&&/div&
&/code&&/pre&&/div&&br&渲染结果&br&&div class=&highlight&&&pre&&code class=&language-cfm&&&span class=&nt&&&input&/span& &span class=&na&&type=&/span&&span class=&s&&&hidden&&/span& &span class=&na&&value=&/span&&span class=&s&&&/u/3949015?v=3&s=40&&/span& &span class=&nt&&/&&/span&
&span class=&nt&&&div&/span& &span class=&na&&data-avatar=&/span&&span class=&s&&&/u/3949015?v=3&s=40&&/span&&span class=&nt&&&&/div&&/span&
&/code&&/pre&&/div&&br&使用 JS 获取&br&&div class=&highlight&&&pre&&code class=&language-text&&$('input').val();
// /jQuery.data/
$('div').data('avatar');
&/code&&/pre&&/div&&br&&b&优点:&/b&&br&不占用全局变量,由 JS 自由获取。&br&&br&&br&&b&使用建议:&br&&/b&&br&适合传递简单数据,也非常适合多个简单数据与 Element 绑定关系。&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&&ul&
&li&nimojs &span data-userid=&1& &删除&/span&&/li&
&li&nimo22 &span data-userid=&2& &删除&/span&&/li&
&li&nimo33 &span data-userid=&3& &删除&/span&&/li&
&li&nimo44 &span data-userid=&4& &删除&/span&&/li&
&li&nimo55 &span data-userid=&5& &删除&/span&&/li&
$('span').on('click',function(){
$.post('/ajax/remove/',$(this).data('userid'),function(data){
&/code&&/pre&&/div&&br&&br&&b&2. JS赋值&/b&&br&&br&&br&将数据填充到 `&script&` 的 JavaScript 变量声明中。&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&&script&
var user_avatar = &&?php echo $user_?&&;
// 渲染结果
// var user_avatar = &/u/3949015?v=3&s=40&;
&/code&&/pre&&/div&&br&或使用 Smarty 后端模板引擎:&br&&div class=&highlight&&&pre&&code class=&language-text&&&script&
var user_avatar = &{$user_avatar}&;
&/code&&/pre&&/div&&br&&b&优点:&/b&&br&传递数据非常方便。前端直接调用 user_avatar 变量使用数据。&br&&br&&b&缺点:&/b&&br&1. 为了传递一个字符串数据占用了全局变量 `user_avatar`,当有很多数据需要传输时则会占用很多全局变量。&br&2. 如果返回数据存在换行将会导致JS报错&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&// 渲染结果有换行符
var user_id = &
/u/3949015?v=3&s=40&;
// Uncaught SyntaxError: Unexpected token ILLEGAL
&/code&&/pre&&/div&&br&&b&优化:&/b&&br&可以通过指向的某一个变量存放所有后端返回的内容,最小程度占用全局变量。例:&br&&div class=&highlight&&&pre&&code class=&language-text&&// PHP 代码
var SERVER_DATA = {
username: {$username},
userid: {$userid},
title: {$title}
// 渲染结果
var SERVER_DATA = {
username: &NimoChu&,
userid: 1,
title: 'F2E'
&/code&&/pre&&/div&&br&&b&使用建议:&/b&&br&需要最快速度传递数据给 JS 并十分确定此数据稳定时,使用此方式。数据格式复杂的建议使用script填充JSON 或AJAX获取JSON 方法。&br&&br&&b&3. script填充JSON&/b&&br&&b&&a href=&///?target=http%3A//.cn/json/json_syntax.asp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JSON 语法&i class=&icon-external&&&/i&&/a&&br&&/b&&br&填充 JSON 数据到 `&script&` 标签中,前端通过 DOM 获取 JSON字符串并解析成对象。&br&&div class=&highlight&&&pre&&code class=&language-text&&&script type=&text/template& id=&data&&{&username&:&nimojs&,&userid&:1}&/script&
var data = JSON.parse($('#data').html());
//{username:&nimojs&,userid:1}
&/code&&/pre&&/div&&br&&b&优点:&/b&&br&页面加载完成后就可以获取到数据。不占用全局变量,可传递大量数据集合。&br&&br&&b&缺点:&/b&&br&数据量特别大时会导致页面初次加载变慢。变慢并不只是文件大小导致的,也因为服务器查询数据并返回合集是需要时间,可使用AJAX获取JSON完成按需加载和加载等待。&br&&br&&b&使用建议:&/b&&br&适合传递在DOM加载完成时就需要用到的大量数据集合。例如:前端控制页面渲染,后端将JSON数据源填充到 `&script&` 由前端使用 JavaScript模板引擎 进行页面渲染。&br&&a href=&///?target=http%3A///technology/javascript/-javascript-template-engine-chooser/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&如何选择Javascript模板引擎(javascript template engine)?&i class=&icon-external&&&/i&&/a&&br&&br&&b&4. AJAX获取JSON&/b&&br&使用 AJAX 获取JSON数据&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&&span id=&showdata&&查看资料&/span&
&div style=&display:& id=&box&&
&h2&用户信息&/h2&
&p id=&info&&&img src=&loading.gif& /&&/p&
&/code&&/pre&&/div&&br&&div class=&highlight&&&pre&&code class=&language-text&&$('#showdata').on('click',function(){
$('#box').show();
$.getJSON('/ajax/userdata/',function(oData){
// oData = {&username&:&nimojs&,&userid&:1}
$('#info').html('用户名:' + oData.username + '&br&用户ID:' + oData.userid);
&/code&&/pre&&/div&&br&这是一个通过AJAX 获取用户资料的示例。流程如下:&br&1. 页面上只显示查看资料&br&2. 用户点击查看资料&br&3. 显示用户信息和 loading 图片&br&4. 向服务器发送获取用户信息的AJAX请求&br&5. 服务器返回JSON字符串,$.getJSON 自动将返回的 JSON字符串转换为对象&br&6. 填充内容到 `&p id=&info&&`&br&&br&&b&优点:&/b&&br&不占用全局变量和 DOM 节点,可以自由控制获取数据的触发条件(页面加载完成&br&时、用户点击查看资料时或用户点击某个按钮时)。当开始获取数据时可使用 loading 图片占位提示用户数据正在读取。防止页面加载所有数据导致的页面加载缓慢。&br&&br&&b&缺点:&/b&&br&会产生额外的HTTP请求。不能在DOM加载完成以后立即获取,需要发送请求-接收响应。&br&&br&&b&使用建议:&/b&&br&适合加载非主要信息、设定触发条件(用户点击查看资料时),并提供友好的数据读取等待提示。&br&&br&&b&5. WebSocket实时传输数据&/b&&br&如果将 AJAX请求和响应比喻成给服务器发短信和等待服务器回复短信,而 WebSocket 就如同和服务器打电话。&br&&br&此处不对WebSocket做过多介绍,附上参考资料:&br&1. &a href=&///?target=http%3A//zh.wikipedia.org/wiki/WebSocket& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&WebSocket&i class=&icon-external&&&/i&&/a&&br&2. &a href=&///?target=http%3A///developerworks/cn/web/1112_huangxa_websocket/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用 HTML5 WebSocket 构建实时 Web 应用&i class=&icon-external&&&/i&&/a&&br&3. &a href=&///?target=http%3A//www./article/20372.html%3Futm_source%3Dtuicool& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ajax vs WebSocket&i class=&icon-external&&&/i&&/a&&br&&br&&b&6. 总结&/b&&br&每种情况都有每种情况的用处,没有绝对正确的方法。&b&根据实际情况灵活的选择获取数据方式&/b&。&br&&br&若作者显示不是Nimo(被转载了),请访问Github原文进行讨论:&a href=&///?target=https%3A///nimojs/blog/issues/13& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&前后端数据交互方法 · Issue #13 · nimojs/blog · GitHub&i class=&icon-external&&&/i&&/a&
搬运我在另外一个主题的答案-----在此介绍几种常用的前后端数据交互方法,并给出使用建议。以提高前后端协同开发的效率。 目录:1. HTML赋值2. JS赋值3. script填充JSON4. AJAX获取JSON5. WebSocket实时传输数据6. 总结1. HTML赋值输出到 Element 的 value …
&img src=&/f930dd3f68dcf1fe2082bd_b.jpg& data-rawwidth=&780& data-rawheight=&475& class=&origin_image zh-lightbox-thumb& width=&780& data-original=&/f930dd3f68dcf1fe2082bd_r.jpg&&&img src=&/881a4269d0acfc229fb8fded_b.jpg& data-rawwidth=&888& data-rawheight=&629& class=&origin_image zh-lightbox-thumb& width=&888& data-original=&/881a4269d0acfc229fb8fded_r.jpg&&&a href=&///?target=https%3A///geekcompany/ResumeSample& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&geekcompany/ResumeSample · GitHub&i class=&icon-external&&&/i&&/a& 程序员简历模板&br&&br&请按照这个简历模板书写
程序员简历模板请按照这个简历模板书写
&b&# 如何开发一个合格的前端组件 #&/b&&br&&br&&ol&&li&&b&API的设计&/b&&br&&/li&&li&&b&文档&/b&&br&&/li&&li&&b&示例&/b&&br&&/li&&li&&b&单元测试&/b&&br&&/li&&/ol&&br&& 如何开发合格的组件:明确组件要解决哪一类功能,不要让它“大而全”。多写文档,示例要全,单元测试要有。&br&&br&我会以一个 JavaScript 分页生成器组件作为例子说明如何开发一个合格的前端组件。&a href=&///?target=https%3A///nimojs/paging& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/paging · GitHub&i class=&icon-external&&&/i&&/a&&br&&img src=&/bad24aa45c4a51e1dc65b4_b.jpg& data-rawwidth=&1057& data-rawheight=&62& class=&origin_image zh-lightbox-thumb& width=&1057& data-original=&/bad24aa45c4a51e1dc65b4_r.jpg&&&br&&br&&br&&b&# 如何设计API?&/b&(组件提供的可配置参数和功能)&br&一个合格的前端组件必须明确要解决的是哪一类问题,这样能&b&避免组件变的“大而全”&/b&。大而全的是框架。组件应当是解决某一类问题,如果要解决另外一类问题就重新开发一个组件。&br&&br&设计API的过程中应时刻思考这个API帮助使用者解决的问题是这个组件应该解决的吗?&br&&br&&a href=&///?target=https%3A///nimojs/paging& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/paging · GitHub&i class=&icon-external&&&/i&&/a& 组件是用来生成分页的,用于解决 AJAX无刷新分页这个开发需求。&br&&br&## 如何与 AJAX 结合?&br&我的设计是不在 API 中增加 AJAX 相关,Paging 的功能是生成HTML,与AJAX的结合通过示例让使用者自由控制 AJAX 相关操作。&a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/ajax.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - AJAX无刷新分页&i class=&icon-external&&&/i&&/a&&br&&br&我不会增加 url 参数用来配置 AJAX 地址,通过 AJAX 获取分页所需的总页数信息,而是让使用者自己发送 AJAX ,再将值传递给 pageCount 参数。&br&因为增加了 url 参数还需要增加 type(请求方式GET POST) 参数,还需要增加 data(提交数据)参数,还需要增加 ajaxdone(服务器响应请求后的处理回调) 参数。&br&&br&通过与 AJAX 结合的思考我明确了 Paging 组件的功能是根据参数&b&生成分页HTML&/b&,那么以后的 API 设计我都遵循这一点。当使用者对功能有疑惑时引导他们将 Paging 当做生成HTML的工具,生成HTML以外的操作全部由使用者写业务代码解决。 &a href=&///?target=https%3A///nimojs/paging/issues/2& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&建议可以多点api,比如回调事件多点,由自己配选项 · Issue #2 · nimojs/paging · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&API的设计一定要三思而后行,方向错误的API会让你的组件偏离正确的方向。&br&&br&---------------------------------------------------------------------------&br&&br&&b&# 编写文档&/b&&br&当明确 API 以后我们应该对API有相关的&b&说明文档和使用建议&/b&。不应该只写一个简单的使用 Demo。&br&&br&一下两个链接分别是 Paging 的 API说明和使用建议。使用建议解释了 Paging 的内部实现机制,告诉使用者可以通过控制模板自由输出HTML。&br&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/docs/api.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - API 说明&i class=&icon-external&&&/i&&/a&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/docs/template.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - 基于模板生成 HTML&i class=&icon-external&&&/i&&/a&&br&&br&使用建议很重要。使用者按照使用建议去使用组件后才能利用这个组件满足这一类开发需求,不至于没有找到某个API就是认为组件不能实现这个功能。&br&&br&---------------------------------------------------------------------------&br&&br&&b&# 示例&/b&&br&组件应该能解决一类问题,而不是只能解决一个问题。那在示例中应该给使用者展示出组件能解决的所有问题示例。&br&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - 自定义界面&i class=&icon-external&&&/i&&/a&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/ajax.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - AJAX无刷新分页&i class=&icon-external&&&/i&&/a&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/before-page-count.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - 控制前后几页显示数量&i class=&icon-external&&&/i&&/a&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/bootstrap.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - bootstrap 分页&i class=&icon-external&&&/i&&/a&&br&- &a href=&///?target=http%3A//docs.spmjs.io/paging/latest/examples/handlebars.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paging - handlebars & createData&i class=&icon-external&&&/i&&/a&&br&&br&千万不要开发一个组件,只提供一个基础示例。只有开发者才知道每个API怎么用和在什么情况下用最合适。&br&&br&---------------------------------------------------------------------------&br&&br&&b&# 单元测试&/b&&br&囧,因为懒 Paging 组件我没有写测试用例。严格意义上它现在不算是合格的组件。&br&&br&编写测试用例能够让你的代码更稳定,某些功能在你最初开发的时候测试没问题不代表在后续的代码修改过程中不会出问题。所以需要测试用例自动化测试保证功能正常。不至于每改一个代码都需要重新检查一遍所有代码。&br&&br&使用正则匹配 &a& 中的 href=&& 内容&a href=&///?target=http%3A//nimojs.github.io/regexp-href/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RegExp a tag href&i class=&icon-external&&&/i&&/a& 。这个项目的测试用例是最好的例子。你不知道你的正则修改一个单词后会发生什么变化,是否还能匹配到这16种HTML中的 href。&br&&br&---------------------------------------------------------------------------&br&&br&&b&组件开发最重要的是 API 的设计。API设计决定了实现方式,好的实现方式能让你的组件解决很多问题,而且实现简单,使用简单。&/b&
# 如何开发一个合格的前端组件 #API的设计文档示例单元测试& 如何开发合格的组件:明确组件要解决哪一类功能,不要让它“大而全”。多写文档,示例要全,单元测试要有。我会以一个 JavaScript 分页生成器组件作为例子说明如何开发一个合格的前端组件。
&b&在没有当面接触的情况下,学历可以证明你的比没学历的人学习能力强一点。&/b&&br&&br&有比没有好,但要看学历所付出的时间。&b&对于已经从业的人员来说如果要花太多时间在学历上不如多花点时间增长自己的前端技术。&/b&
在没有当面接触的情况下,学历可以证明你的比没学历的人学习能力强一点。有比没有好,但要看学历所付出的时间。对于已经从业的人员来说如果要花太多时间在学历上不如多花点时间增长自己的前端技术。
支持分离,有利于前端部门的成长。优秀的前端 leader 会让整个开发体系更健全。&br&&br&&b&部门和开发环境可以分离,但前端的开发环境必须与后端的开发环境紧密结合。&/b&比如前端所有流程规范、开发环境和文件部署全部与后端协商制定。具体如何执行需要前端 leader 与后端 leader 把控。&br&&br&&b&你需要一个前端架构师建立前端开发体系&/b&
支持分离,有利于前端部门的成长。优秀的前端 leader 会让整个开发体系更健全。部门和开发环境可以分离,但前端的开发环境必须与后端的开发环境紧密结合。比如前端所有流程规范、开发环境和文件部署全部与后端协商制定。具体如何执行需要前端 leader 与后端…
我愿意打赏,因为这笔账很好算。为好的内容花钱稳赚不赔。包括我买好书也都是从不手软。&br&&br&&b&但是!写技术博客的目的大都是分享知识和提高知名度,半开放的付费阅读无法达到这个目的。想通过写作赚钱的都去出书了。&/b&&br&&br&&br&自由打赏也不错,如何支付是个问题。常用方式是博主挂自己的支付宝。我也看到过在文章中挂支付宝链接得到“打赏”的。&br&&br&如果能有一个博客平台,根据用户的贡献增加积分。积分可以提现到支付宝。用户只需要打赏自己的积分给博主,博主积累积分提现。这样解决了支付问题,但最终是由社区运营方买单。&br&&br&&br&&b&其实完全不需要通过打赏鼓励发优质文章。一个技术人员维护好自己的博客能给自己带来很多价值。这些价值会以另外一种方式得到“打赏”(RMB)&/b&
我愿意打赏,因为这笔账很好算。为好的内容花钱稳赚不赔。包括我买好书也都是从不手软。但是!写技术博客的目的大都是分享知识和提高知名度,半开放的付费阅读无法达到这个目的。想通过写作赚钱的都去出书了。自由打赏也不错,如何支付是个问题。常用方式是…
第一次看到 gulp/grunt 的文章时我也不清楚它们的作用。大量的教程都是零散的说某一个插件的使用方式。对于当时的我并不理解为什么要用它们。所以我写了一系列的gulp基础教程来说明为什么要用 gulp 去构建项目。&br&&br&&a href=&///?target=http%3A///nimojs/gulp-book& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/gulp-book · GitHub&i class=&icon-external&&&/i&&/a&&br&&blockquote&&p&gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能够极大的提高开发效率。&/p&&br&&p&在 Web 前端开发工作中有很多“重复工作”,比如压缩CSS/JS文件。而这些工作都是有规律的。找到这些规律,并编写 gulp 配置代码,让 gulp 自动执行这些“重复工作”。&/p&&/blockquote&&b&一名合格的前端开发工程师应该至少会使用一种构建工具。&/b&
第一次看到 gulp/grunt 的文章时我也不清楚它们的作用。大量的教程都是零散的说某一个插件的使用方式。对于当时的我并不理解为什么要用它们。所以我写了一系列的gulp基础教程来说明为什么要用 gulp 去构建项目。gulp 是基于 node…
我没法告诉你你的初心是什么,因为每个人的原因都不一样。&br&但我觉得有几件事可以让你调整到喜欢 coding 的状态。&br&&br&1. 写&b&技术博客&/b&,不要写百度能搜得到的常识性文章,写有干货的文章,写自己对某些知识点的理解。然后发到各大社区,关注读者的反馈。&br&2.&b& 在 GitHub 创建自己的开源项目&/b&,并一直维护它们。设计它们的 API,用心编写相关文档。&br&----------&br&&b&为什么要这么做?&/b&&br&&br&写基础博客是一个沉淀的过程,将自己所学的知识&b&回顾、整理、归纳、总结、分享&/b&。一篇用心写的文章成型后你能收获到读者给你的反馈和赞同。一个点赞也是对作者重要的鼓励和认同。&br&&br&在 GitHub 创建开源项目是自己给自己写代码的过程,自己是需求方也是开发者。在创建开源项目的过程中你会收到别人给你的反馈,能将这个项目做的越来越好。而这些项目是最能表达你开发能力的代码。最重要的是:&b&你能长时间的进入专注状态,并得到快乐。&/b&
我没法告诉你你的初心是什么,因为每个人的原因都不一样。但我觉得有几件事可以让你调整到喜欢 coding 的状态。1. 写技术博客,不要写百度能搜得到的常识性文章,写有干货的文章,写自己对某些知识点的理解。然后发到各大社区,关注读者的反馈。2. 在 GitHu…
&a href=&///?target=https%3A///nimojs/learn-js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/learn-js · GitHub&i class=&icon-external&&&/i&&/a&&blockquote&一个 JavaScript 互助学习的项目。接受组件开发的挑战,提交代码让他人评论你的代码以提高。&br&&/blockquote&互助学习吧,非工作关系一对一是不可能的。收钱别人都不一定愿意。&br&如果你在学习过程中遇到问题,可以留言到 &a href=&///?target=https%3A///nimojs/learn-js/issues/new& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/nimojs/learn&/span&&span class=&invisible&&-js/issues/new&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&&a href=&///?target=https%3A///baidu-ife/ife& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&baidu-ife/ife · GitHub&i class=&icon-external&&&/i&&/a& 百度前端技术学院(&b&强烈推荐&/b&)&br&&br&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript 标准参考教程(alpha)&i class=&icon-external&&&/i&&/a&&br&&blockquote&阮一峰的教程理解起来比常见的教程轻松很多&/blockquote&
一个 JavaScript 互助学习的项目。接受组件开发的挑战,提交代码让他人评论你的代码以提高。互助学习吧,非工作关系一对一是不可能的。收钱别人都不一定愿意。如果你在学习过程中遇到问题,可以留言到
《Gulp 入门指南》 &a href=&///?target=https%3A///nimojs/gulp-book& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/gulp-book · GitHub&i class=&icon-external&&&/i&&/a&&br&里面有如何自动化压缩JS相关的内容。
《Gulp 入门指南》 里面有如何自动化压缩JS相关的内容。
有很多事放到 github 上,我的工作积累几乎全部移到github上了。你可以看看 &a href=&///?target=https%3A///nimojs/blog& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/blog · GitHub&i class=&icon-external&&&/i&&/a& (我通过 issues 搭建博客的方式 - 低成本不操心) &a href=&///?target=https%3A///nimojs/blog/issues& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Issues · nimojs/blog · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&还有一些其他开源项目&br&&br&&a href=&///?target=https%3A///nimojs/gulp-book& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/gulp-book · GitHub&i class=&icon-external&&&/i&&/a& gulp入门指南 - 使用 github写一系列的gulp入门教程 &br&&a href=&///?target=https%3A///nimojs/rain& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/rain · GitHub&i class=&icon-external&&&/i&&/a& 团队开发规范&br&&a href=&///?target=https%3A///nimojs/paging& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/paging · GitHub&i class=&icon-external&&&/i&&/a& 分页生成器&br&&a href=&///?target=https%3A///nimojs/handlebarsjs.org& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/handlebarsjs.org · GitHub&i class=&icon-external&&&/i&&/a& 我翻译的handlebarsjs 中文网&br&&a href=&///?target=https%3A///nimojs/ibackstage& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/ibackstage · GitHub&i class=&icon-external&&&/i&&/a& 快速搭建管理后台&br&&a href=&///?target=https%3A///nimojs/seajs-cmd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/seajs-cmd · GitHub&i class=&icon-external&&&/i&&/a& 在线 combo打包seajs解决方案&br&&a href=&///?target=https%3A///nimojs/gulp-watch-path& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/gulp-watch-path · GitHub&i class=&icon-external&&&/i&&/a& 一个gulp.watch工具&br&&a href=&///?target=https%3A///nimojs/regexp-href& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/regexp-href · GitHub&i class=&icon-external&&&/i&&/a& 跟工作相关的一个正则测试用例&br&&a href=&///?target=https%3A///nimojs/handlebars-helper-is& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nimojs/handlebars-helper-is · GitHub&i class=&icon-external&&&/i&&/a& 基于别人进行二次开发的 handlebars helper&br&&br&还有一些非公开项目,与公司前端团队论坛都是基于github去搭建的。
有很多事放到 github 上,我的工作积累几乎全部移到github上了。你可以看看
(我通过 issues 搭建博客的方式 - 低成本不操心) 还有一些其他开源项目 gulp入门指南 - 使用…
接着小志的回答。&br&&br&& 如果要实现一套HTML结构,并且要兼容多浏览器,那么HTML结构还是比较关键&br&&br&可以与需求方沟通,是否可以采用 markdown 作为内容编辑文本。在编辑内容时提供同时预览 PC 端和 mobile 端显示效果的功能。&br&&br&这样开发人员只要维护好纯 HTML 的响应式布局就可以了。&br&&br&如果不能使用 markdown 也实现在编辑内容时同事预览
PC 端和 mobile 端效果,编辑人员编辑时就可以预览到效果,利用预览效果调整自己编辑的内容。
接着小志的回答。& 如果要实现一套HTML结构,并且要兼容多浏览器,那么HTML结构还是比较关键可以与需求方沟通,是否可以采用 markdown 作为内容编辑文本。在编辑内容时提供同时预览 PC 端和 mobile 端显示效果的功能。这样开发人员只要维护好纯 HTML 的响应…
github 搜索 blog
github 搜索 blog
&a href=&///?target=https%3A///fouber/blog/issues/6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&大公司里怎样开发和部署前端代码? · Issue #6 · fouber/blog · GitHub&i class=&icon-external&&&/i&&/a&&br&试试阅读这篇文章能不能解决你的问题。
试试阅读这篇文章能不能解决你的问题。
&a href=&///?target=https%3A//mtjs.github.io/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&mtjs.github.io/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&在快速迭代版本过程中,我们有时候只修改了某个js中的几行代码,却需要用户下载整个js文件,这在重视流量的移动端显得非常浪费,mt独创的增强更新算法实现了修改多少代码就只下载修改代码的功能,为用户和公司节省大量流量&br&&br&localstorage里面存储的上个版本的js内容和版本号,当本次版本号和上次版本号不一致的时候,mt拼接出增量文件url去拉取增量文件,并和上个版本的js内容合并生成新版本内容。整个方案得核心在于增量文件得计算和合并&br&&br&吊炸天
在快速迭代版本过程中,我们有时候只修改了某个js中的几行代码,却需要用户下载整个js文件,这在重视流量的移动端显得非常浪费,mt独创的增强更新算法实现了修改多少代码就只下载修改代码的功能,为用户和公司节省大量流量localstorage…
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 android 增量更新 的文章

 

随机推荐