ivan 发布于 12月06, 2017

层叠上下文

何为层叠上下文?

默认情况下,网页内容是没有偏移角的垂直视觉呈现,当内容发生层叠的时候,一定会有一个前后的层叠顺序产生。

三维坐标空间

何为层叠水平?

层叠水平决定了同一层叠上下文中元素在z轴上的显示顺序。也通俗讲就是在z轴上谁层叠水平高谁就在最上面(外面)。(其实是绘制先后,层叠水平高的后绘制,会遮盖先绘制的元素)

需要注意的是:

1. 层叠水平只有在同一层叠上下文中比较才有意义。
2. z-index可以影响定位元素和flex盒子的孩子元素的层叠水平,但它不代表层叠水平,因为所有元素都有层叠水平!

何为层叠顺序?

一个层叠上下文中一共有7种层叠等级:

1. 背景和边框 —— 形成层叠上下文的元素的背景和边框。 层叠上下文中的最低等级。
2. 负z-index值 —— 层叠上下文内有着负z-index值的子元素。
3. 块级盒 —— 文档流中非行内非定位子元素。
4. 浮动盒 —— 非定位浮动元素。
5. 行内盒 —— 文档流中行内级别非定位子元素。
6. z-index: 0 —— 定位元素。 这些元素形成了新的层叠上下文。
7. 正z-index值 —— 定位元素。 层叠上下文中的最高等级。

层叠上下文中的七种层叠等级

  1. z-index:auto和z-index:0的定位元素虽然看上去效果一样,但是有本质区别。(对于z-index为auto的一般定位元素,其只是普通元素,不会创建层叠上下文,所以层叠时要么看子元素层叠水平,要么按"后来居上"原则;对于z-index为0的一般定位元素,自身会创建层叠上下文,从而会影响子元素的层叠显示问题)

  2. inline/inline-block表现的是内容,所以层叠顺序优先,而块状元素和浮动用作布局,则次之。因为网页中最重要的是展示内容。

  3. 背景和边框为创建层叠上下文的元素的,因为他们的内容肯定是覆盖在背景之上的,所以也有层叠关系。

  4. 内联元素还有inline-table

如何创建层叠上下文?

MDN中描述: 文档中的层叠上下文由满足以下任一个条件的元素组成:

* 根元素 (HTML),
* z-index 值不为 "auto"的 绝对/相对定位,
* 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
* opacity 属性值小于 1 的元素(参考 the specification for opacity),
* transform 属性值不为 "none"的元素,
* mix-blend-mode 属性值不为 "normal"的元素,
* filter值不为“none”的元素,
* perspective值不为“none”的元素,
* isolation 属性被设置为 "isolate"的元素,
* position: fixed
* 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
* -webkit-overflow-scrolling 属性被设置 "touch"的元素

总结:

  1. 给一个 HTML 元素 定位z-index 赋值 创建一个层叠上下文,(opacity 值不为 1 的也是相同)。
  2. 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个有层级的层叠上下文。
  3. 每个层叠上下文完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
  4. 每个层叠上下文是自包含的:当元素的内容发生层叠后,整个该元素将会 在父层叠上下文中 按顺序进行层叠。

来,举例说明:

不设置z-index的层叠

<div style="position: absolute;">div #1</div>
<div style="position: relative;">div #2</div>
<div style="position: relative;">div #3</div>
<div style="position: absolute;">div #4</div>
<div>div #5</div>

1512542818747.png

由于属于同一层叠水平,所以层叠顺序按照“后来居上”原则;

float层叠

<div style="position: absolute;">div #1 absolute</div>
<div style="float:left;">div #2 float-left</div>
<div style="float:right;">div #3 float-right</div>
<div style="position: absolute;">div #4 absolute</div>
<div>div #5 no-position</div>

1512542918972.png

设置了z-index的层叠

<div style="position:absolute; z-index:5;"> div#1 z-index:5 </div>
<div style="position:relative; z-index:3;"> div#2 z-index:3 </div>
<div style="position:relative; z-index:2;"> div#3 z-index:2 </div>
<div style="position:absolute; z-index:1;"> div#4 z-index:1 </div>
<div style="position:static; z-index:8;"> div#5 z-index:8 </div>

1512543022468.png

虽然div#5的z-index值最大,但是由于它不是定位元素(position: relative | absolute),所以它依然在层叠的最下面,因为他是普通元素,不具备层叠上下文。

层叠上下文的实例

未完待续

阅读全文 »

ivan 发布于 11月15, 2017

实现虚线框的两种方式

背景: 实现虚线可以使用 border:2px dashed red; 但是这种方式不能定制虚线和实线的间隔,并且在不同浏览器下的效果也不一致。(IE下2像素的虚框是采用4-2-4-2的形式重复下去,转角等宽相连;Firefox和Chrome浏览器都是6-6-6-6的形式重复,虚框起点Firefox从实框顶端开始平铺,而Chrome不是。)

最终效果预览

  1. border-image( css3 属性) 使用方式:

     width: 260px;
     height: 180px;
     border-width: 6px;
     border-style: solid;
     -webkit-border-image: url(http://www.zhangxinxu.com/study/image/dashed_red2.png) 6 repeat;
     border-image: url(http://www.zhangxinxu.com/study/image/dashed_red2.png) 6 repeat;
     background: yellow;
    

    不细说,比较复杂的是图片的制作,参考张鑫旭老师博客实现兼容性的CSS粗虚线边框(dashed)效果

  2. svg svg 可以通过 dash-dasharray 来实现

     margin-top: 20px;
     width: 200px;   
     height: 150px;
     background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="150"><path stroke="red" fill="none" stroke-width="1" stroke-dasharray="5" d="M0 0 L200 0 L200 150 L0 150 L0 0"></path></svg>');
     background-repeat: no-repeat;
    

    也可以直接在html中插入svg,这里是通过background-image方式实现。

阅读全文 »

ivan 发布于 07月26, 2017

哦,async

async

在异步回调比较多情况下使用 async 确实方面很多。在使用中发现一些注意事项, 以做记录。(FROM 阮一峰async 函数的含义和用法

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。

注意:

await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中。

async function myFunction(){
    try {
        await sometingThatReturnsAPromise();
    } catch (err) {
        console.log(err);
    }
}

//另外一个写法
async function myFunction() {
    await somethingThatReturnsAPromise().catch(function (err){
        console.log(err);
    });
}

await 命令只能用在 async 函数之中,如果用在普通函数,就会报错。

async function dbFuc(db) {
    let docs = [{}, {}, {}];

    //报错
    docs.forEach(function(doc) {
        await db.post(doc);
    });
}

上面代码会报错,因为 await 用在普通函数之中了。但是,如果将 forEach 方法的参数改成async 函数,也有问题。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];

     //可能得到错误结果
     docs.forEach(async function(doc) {
         await db.post(doc);
     })
 }

上面代码可能不会正常工作,原因是这时三个 db.post 操作将是并发执行,也就是同时执行,而不是继发执行。正确的写法是采用 for 循环。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     for (let doc of docs) {
         await db.post(doc);
     }
 }

如果确实希望多个请求并发执行,可以使用 Promise.all 方法。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     let promises = docs.map( (doc) => db.post(doc));

     let results = await Promise.all(promises);
     console.log(results);
 }

 //或者使用下面的写法

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     let promises = docs.map( (doc) => db.post(doc));

     let results = [];
     for (let promise of promises) {
         results.push(await promise);
     }
     console.log(results);
 }

阅读全文 »

ivan 发布于 06月16, 2017

动画小结

动画本质:采用定时器改变显示元素的一些属性的过程。

待续

动画的种类

JavaScript动画

DOM动画

Canvas动画

CSS3动画

transition

animation

SVG动画

block.addEventListener("click",function(){
      var self = this;
      requestAnimationFrame( function change(){
        self.style.transform = "rotate(" + (deg++) +"deg)";
        requestAnimationFrame(change);
      });
    });
时间 增量
幅度控制 ✔️ ✔️
时间控制 ✔️
速度控制 ✔️ ✔️
不会延迟 ✔️
不会掉帧 ✔️

SVG

.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear forwards;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}

但是在UC和QQ浏览器上不支持。

先来了解两个属性 stroke-dasharraystroke-dashoffset

属性 stroke-dasharray 可控制用来描边的点划线的图案范式。作为一个外观属性,它也可以直接用作一个CSS样式表内部的属性。

值 none | | inherit

它是一个数列,数与数之间用逗号或者空白隔开,指定短划线和缺口的长度。如果提供了奇数个值,则这个值的数列重复一次,从而变成偶数个值。

stroke-dashoffset 属性指定了dash模式到路径开始的距离,如果使用了一个 <百分比> 值, 那么这个值就代表了当前viewport的一个百分比。值可以取为负值。

##CSS3动画属性

transform(v.变形)

属性: 旋转 rotate (中心为原点) 扭曲、倾斜 skew(skew(x,y),skewX(x),skewY(y)) 缩放 scale(scale(x,y),scaleX(x),scaleY(y)) 移动 translate(translateX,translateY) 矩阵变形 matrix

备注:以下demo中的 div 的初始状态为: demo origin

rotate 的用法

rotate(a) a单位为deg,可以通过 transform-origin来指定旋转的中心点,默认值为 50% 50% 0

transform: rotate(30deg);

rotate用法

transform: rotate(30deg);
transform-origin: 0 0;

rotate用法

/* 单值语法 */
transform-origin: 2px;
transform-origin: bottom;

/* 双值语法 */
/* 用两个数字值先水平后垂直,用一个数值一关键字或两关键字不强求顺序 */
transform-origin: 3cm 2px;   /* x-offset y-offset */
transform-origin: 2px left;  /* y-offset x-offset-keyword */
transform-origin: left 2px;  /* x-offset-keyword y-offset */
transform-origin: right top; /* x-offset-keyword y-offset-keyword */
transform-origin: top right; /* y-offset-keyword x-offset-keyword */

/* 三值语法 */
transform-origin: 2px 30% 10px;     /* x-offset y-offset z-offset */
transform-origin: 2px left 10px;    /* y-offset x-offset-keyword z-offset */
transform-origin: left 5px -3px;    /* x-offset-keyword y-offset z-offset */
transform-origin: right bottom 2cm; /* x-offset-keyword y-offset-keyword z-offset */
transform-origin: bottom right 2cm; /* y-offset-keyword x-offset-keyword z-offset */

skew 的用法,倾斜 transform: skew(30deg); 等同于 transform: skewX(30deg); skewX用法

transform: skewY(30deg); skewY用法

scale(sx) 的用法,比例;当坐标值处于区间 [-1, 1] 之外时,该变换将在相应的坐标方向上放大该元素,当处在区间之中时,该变换将在相应的坐标方向上缩小该元素。当值为1时将不进行任何处理,当为负数时,将进行像素点反射之后再进行大小的修改。

1497441658537.png

transform: scale(1.1);

scale用法

transform: scale(-0.5);

1497441531738.png

translate的用法,变动,位移;下图,向右下各移动10px。

transform: translate(15px,15px);

1497441867848.png

整合起来的效果

-webkit-transform: rotate(10deg) skew(-10deg) scale(0.8) translate(100px,0);
-moz-transform: rotate(10deg) skew(-10deg) scale(0.8) translate(100px,0);
transform: rotate(10deg) skew(-10deg) scale(0.8) translate(100px,0);

1497442234372.png

transition(转换)

css的transition允许css的属性值在一定的时间区间内平滑地过渡。

属性 transition-property 指定当元素其中一个属性改变时执行transition效果。

* none(没有属性改变):transition马上停止执行
* all(所有属性改变):任何属性值变化时都将执行transition效果
* width(元素属性名):指定元素的某一个属性值

transition-duration 指定元素转换过程的持续时间,以秒或毫秒计 transition-timing-function

描述 效果等同于
linear 规定以相同速度开始至结束的过渡效果 cubic-bezier(0,0,1,1)
ease 规定慢速开始,然后变快,然后慢速结束的过渡效果 cubic-bezier(0.25,0.1,0.25,1)
ease-in 规定以慢速开始的过渡效果 cubic-bezier(0.42,0,1,1)
ease-out 规定以慢速结束的过渡效果 cubic-bezier(0,0,0.58,1)
ease-in-out 规定以慢速开始和结束的过渡效果 cubic-bezier(0.42,0,0.58,1)
cubic-bezier(n,n,n,n) 在 cubic-bezier 函数中定义自己的值。n∈[0,1] cubic-bezier(n,n,n,n)

1497443486998.png

transition-delay 延迟,指定一个动画开始执行的时间,也就是说当改变元素属性值后多长时间开始执行transition效果。

综合起来:

transition: background 0.5s ease-in,color 0.3s ease-out;
transition: transform .4s ease-in-out;

点这里➡️ 看个demo

animation(动画)

CSS3中添加的新属性animation是用来为元素实现动画效果的,但是animation无法单独担当起实现动画的效果。承载动画的另一个属性——@keyframes。使用的时候为了兼容可加上-webkit-、-o-、-ms-、-moz-、-khtml-等前缀以适应不同的浏览器。

创建动画的原理是,将一套 CSS 样式逐渐变化为另一套样式。 通过 @keyframes 规则来定义具体的动画效果,以百分比来规定改变发生的时间,或者通过关键词 "from" 和 "to",等价于 0% 和 100%。

属性

animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction

阅读全文 »

ivan 发布于 06月05, 2017

crontab

crontab

修改集群的crontab,如何追加crontab?

  1. 将需要追加的crontab内容写到crontab.add中(添加新的crontab)
  2. crontab -l >> crontab.add (把当前的crontab追加到crontab.add中)
  3. crontab crontab.add(重载crontab)

Crontab格式说明

星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。

逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”

中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”

正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。


-u user:用来设定某个用户的crontab服务,例如,“-u ivan”表示设定ivan用户的crontab服务,此参数一般有root用户来运行。

file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。

-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。

-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。

-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。

-i:在删除用户的crontab文件时给确认提示。

阅读全文 »

ivan 发布于 05月18, 2017

samba服务配置

why

本地写了一个demo,想在手机上看到效果,并且也方便其他人看到效果,想到了在服务器上搭建一个samba服务,直接把静态文件扔到服务器上。简单快捷,为自己的机智点赞,哈哈,进入正题~

安装

yum install -y samba.x86_64

samba配置

  • 进入samba配置目录,vi /etc/samba/smb.conf 添加配置信息
  • 设置samba密码 sudo smbpasswd -a $USERNAME
  • 重启samba服务 sudo /etc/init.d/smb restart
  • mac,command+k,smb://$USERNAME@10...*
  • windows \10...*

vi /etc/samba/smb.conf

写入以下

[onebox]
        comment = All Printers
        path = /home/ivan/www
        browseable = yes
        writable = yes
        public = yes
        valid users = ivan
        create mask = 123456
        directory mask = 123456

以上。

ps 配置完成之后 是可以方便快捷的从本地把文件同步上自己的服务器上,但是真的有点慢 ....

阅读全文 »

ivan 发布于 03月03, 2017

Understanding node.js

The article is reprinted from Felix Geisendörfer - Understanding node.js

Node.js has generally caused two reactions in people I've introduced it to. Basically people either "got it" right away, or they ended up being very confused.

If you have been in the second group so far, here is my attempt to explain node:

  • It is a command line tool. You download a tarball, compile and install the source.
  • It let's you run JavaScript programs by typing 'node my_app.js' in your terminal.
  • The JS is executed by the V8 javascript engine (the thing that makes Google Chrome so fast).
  • Node provides a JavaScript API to access the network and file system

"But I can do everything I need in: ruby, python, php, java, ... !".

I hear you. And you are right! Node is no freaking unicorn that will come and do your work for you, sorry. It's just a tool, and it probably won't replace your regular tools completely, at least not for now.

"Get to the point!"

Alright, I will. Node is basically very good when you need to do several things at the same time. Have you ever written a piece of code and said "I wish this would run in parallel"? Well, in node everything runs in parallel, except your code.

"Huh?"

That's right, everything runs in parallel, except your code. To understand that, imagine your code is the king, and node is his army of servants.

The day starts by one servant waking up the king and asking him if he needs anything. The king gives the servant a list of tasks and goes back to sleep a little longer. The servant now distributes those tasks among his colleagues and they get to work.

Once a servant finishes a task, he lines up outside the kings quarter to report. The king lets one servant in at a time, and listens to things he reports. Sometimes the king will give the servant more tasks on the way out.

Life is good, for the king's servants carry out all of his tasks in parallel, but only report with one result at a time, so the king can focus.[1]

"That's fantastic, but could you quit the silly metaphor and speak geek to me?"

Sure. A simple node program may look like this:

var fs = require("fs")
  , sys = require("sys");

fs.readFile("treasure-chamber-report.txt", function(report) {
  sys.puts("oh, look at all my money: "+report);
});

fs.writeFile("letter-to-princess.txt", "...", function() {
  sys.puts("can"t wait to hear back from her!");
});

Your code gives node the two tasks to read and write a file, and then goes to sleep. Once node has completed a task, the callback for it is fired. But there can only be one callback firing at the same time. Until that callback has finished executing, all other callbacks have to wait in line. In addition to that, there is no guarantee on the order in which the callbacks will fire.

"So I don't have to worry about code accessing the same data structures at the same time?"

You got it! That's the entire beauty of JavaScripts single-threaded / event loop design!

"Very nice, but why should I use it?"

One reason is efficiency. In a web application, your main response time cost is usually the sum of time it takes to execute all your database queries. With node, you can execute all your queries at once, reducing the response time to the duration it takes to execute the slowest query.

Another reason is JavaScript. You can use node to share code between the browser and your backend. JavaScript is also on its way to become a really universal language. No matter if you did python, ruby, java, php, ... in the past, you've probably picked up some JS along the way, right?

And the last reason is raw speed. V8 is constantly pushing the boundaries in being one of the fastest dynamic language interpreters on the planet. I can't think of any other language that is being pushed for speed as aggressively as JavaScript is right now. In addition to that, node's I/O facilities are really light weight, bringing you as close to fully utilizing your system's full I/O capacities as possible.

"So you are saying I should write all my apps in node from now on?"

Yes and no. Once you start to swing the node hammer, everything is obviously going to start looking like a nail. But if you're working on something with a deadline, you might want to base your decision on:

  • Are low response times / high concurrency important? Node is really good at that.
  • How big is the project? Small projects should be fine. Big projects should evaluate carefully (available libraries, resources to fix a bug or two upstream, etc.).

"Does node run on Windows?"

No. If you are on windows, you need to run a virtual machine (I recommend VirtualBox) with Linux. Windows support for node is planned, but don't hold your breath for the next few months unless you want to help with the port.

"Can I access the DOM in node?"

Excellent question! No, the DOM is a browser thingy, and node's JS engine (V8) is thankfully totally separate from all that mess. However, there are people working on implementing the DOM as a node module, which may open very exciting possibilities such as unit testing client-side code.

"Isn't event driven programming really hard?"

That depends on you. If you already learned how to juggle AJAX calls and user events in the browser, getting used to node shouldn't be a problem.

Either way, test driven development can really help you to come up with maintainable designs.

"Who is using it?"

There is a small / incomplete list in the node wiki (scroll to "Companies using Node"). Yahoo is experimenting with node for YUI, Plurk is using it for massive comet and Paul Bakaus (of jQuery UI fame) is building a mind-blowing game engine that has some node in the backend. Joyent has hired Ryan Dahl (the creator of node) and heavily sponsors the development.

Oh, and Heroku just announced (experimental ) hosting support for node.js as well.

"Where can I learn more?"

Tim Caswell is running the excellent How To Node blog. Follow #nodejs on twitter. Subscribe to the mailing list. And come and hang out in the IRC channel, #node.js (yes, the dot is in the name). We're close to hitting the 200 lurker-mark there soon : ).

I'll also continue to write articles here on debuggable.com.

That's it for now. Feel free to comment if you have more questions!

--fg

[1]: The metaphor is obviously a simplification, but if it's hard to find a counterpart for the concept of non-blocking in reality.

阅读全文 »

ivan 发布于 02月12, 2017

前端模块化规范

前端模块化规范

看看现在三分天下的流行框架:React、Angular2、Vue,他们的最大的共同点就是:模块化、组件化;还有由Nodejs衍生而来的各种前端构建工具:Webpack、Gulp、Systemjs,使用它们的基础也是模块化、组件化。

至于模块化的好处,网上各种论调就不多说了,除此之外,更重要的是:在模块化的基础上形成一种团队成员间的默契化规范,形成团队内的私有仓库,统一管理,达到像后端调用package一样自然而然的调用前端模块的目的;

一切源自CommonJS:

不要怕这又是个什么框架要去花时间学习,CommonJS是JS的模块化规范,由于JS的历史原因,起初并没有模块化之说,之后JS成为了浏览器端的事实标准,地位越来越重要,CommonJS规范就是为了解决这个问题而提出的,并希望JS不仅仅运行于浏览器端,而是任何地方;感觉很牛逼的样子!然后,Nodejs在服务端实现了CommonJS规范,从而将JS从浏览器的小环境拉到了前后端通行的大环境,丑小鸭终于变白天鹅了!

按照CommonJS规范,文件即模块,使用require引用和加载模块,exports定义和导出模块,module标识模块,使用require时需要去读取并执行该文件,然后返回exports导出的内容,由于模块的读取执行是同步的文件操作,所以CommonJS只能在服务端由Nodejs发扬光大;但是在浏览器端,这种同步操作并不适用,至少会很耗时,阻塞后续代码的运行;从而在浏览器端由CommonJS衍生出两大分支:AMD(异步模块定义)和CMD(通用模块定义);

AMD(异步模块定义):

AMD的代表是RequireJS,通过define(id?, dependencies?, factory)来定义模块,require([dependencies], function(){})来调用模块,使用提前异步加载依赖模块的方式,模块加载完毕后执行回调函数,这里要好好理解JS的异步机制,不可按同步顺序执行的思维去理解,多个文件异步并行加载,哪个先执行完不是你按照加载顺序可预料到的,而是等所有依赖执行完毕,最后一并回调结果;

CMD(通用模块定义):

CMD的代表是SeaJS(已过时?),与RequireJS定义和加载模块的方式略有不同,同样可以通过define(id?, dependencies?, factory)定义模块,但是SeaJS是采用的就近依赖的方式来加载模块,一般不在dependencies里依赖模块,而是统一写法:define(function(require, exports, module){}),在factory里就近加载依赖模块,由seajs.use([dependencies],function(mod,[mod]){})来使用模块;本质上也是异步的加载模块,只是和RequireJS相比加载和执行的时机不一样罢了;

相比来说,Seajs和Requirejs都是很不错的前端模块化组织方案,各有千秋;Requirejs要等到所有前置依赖加载并执行完毕,再回调主要的代码逻辑,如果非要说有所欠缺,就得在前置依赖那里做优化了,但大致上是很流畅的;Seajs只是将依赖模块预先加载并不执行,在需要时就近使用,这时就可能也许会出现延迟的现象;

工具是非常重要的生产力:

虽然浏览器端流行的模块化规范是AMD和CMD,但是借助工具的力量,我们依然可以在浏览器端模拟CommonJS规范,比如借助Gulp、Webpack之类的工具,我们在开发环境依然可以像写Nodejs一样写前端的JS代码,由工具打包成浏览器可运行的JS,同样,异步的调用代码块也是可行的;

UMD(通用模块规范):

现在JS已经可以通行前后端了,那么很大程度上一个JS模块是既可以在浏览器端运行,同时也能在服务端跑了,UMD方案即是对AMD和CommonJS规范的整合,实现对JS模块化的跨平台;像下面这个鬼样子:

(function(root, factory){
  if(typeof define ==="function"&& define.amd){
    // AMD
    define(["jquery"], factory);
    }elseif(typeof exports ==="object"){
      // Node, CommonJS之类的
      module.exports = factory(require("jquery"));
    }else{
      // 浏览器全局变量(root 即 window)
      root.returnExports = factory(root.jQuery);
    }
  }(this,function($){
  // 方法
  function myFunc(){};
    // 暴露公共方法
    return myFunc;
}));

ES6的模块化:

ES6作为JavaScript新的标准,自带了模块化的buff,通过import和export导入导出模块;基本思想与CMD、AMD差不多,只是多了更多语法糖式的东西,毕竟属于原生的支持,当然更加好用和易于理解;由于当前的浏览器环境,要想安心的使用,还是得借助工具的力量进行转换;

转载&参考

前端各种模块化规范常回顾

前端工程之模块化

阅读全文 »

ivan 发布于 02月09, 2017

package.json文件

package.json文件

生成package.json文件

npm init #初始化生成一个package.json文件 npm install react --save #将该模块写入dependencies属性 npm install react --save-dev #将该模块写入devDependencies属性 npm install #安装dependencies和devDependencies下的模块 npm install --production #仅安装dependencies下的模块 npm install --dev #仅安装devDependencies下的模块

###dependencies && devDependencies dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。

  1. 指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
  2. 波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
  3. 插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
  4. latest:安装最新版本。

###peerDependencies 字段,就是用来供插件指定其所需要的主工具的版本。

阅读全文 »