分类 前端技术 下的文章

好吧,没啥,就是他们最近在迁移服务器的时候,安装 npm 包的时候又遇到 Please try running this command again as root/Administrator. 这个问题了,然后就准备把这个问题记一下,方便为遇到同样问题的同学参考吧

原文地址: https://docs.npmjs.com/getting-started/fixing-npm-permissions

当你安装一个包到全局的时候可能会遇到一个 EACCES 错误,这是因为你没有 npm 存储全局包的目录的写权限。

你可以通过两种途径来修复这个问题:

  1. 修改 npm 默认目录的权限
  2. 修改 npm 默认目录到其他目录

在进行一下操作之前,请先备份一下你的电脑

方法1:修改 npm 默认目录的权限

  1. 找到 npm 默认目录的路径
npm config get prefix

对于大多数的系统来说,应该是 /usr/local

注意: 如果你显示的路径是只是 /usr,请使用 方法2

  1. 修改 npm 目录所有者为当前用户
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

这将修改所有被 npm 和其他工具(lib/node_modules, bin 和 share)使用的子目录的权限

方法2:修改 npm 默认目录到其他目录

有些时候你会因为某些问题不想修改 npm 目录(像:/usr)的所有关系,比如你在跟另外的用户共享系统的时候。

我们可以通过修改配置让 npm 使用一个不同目录来代替。在下面的例子里,我们使用了一个在我们 home 目录下的一个隐藏目录

  1. 创建一个用于安装全局包的目录
mkdir ~/.npm-global
  1. 配置 npm 使用新的目录路径
npm config set prefix '~/.npm-global'
  1. 打开或者创建一个 ~/.profile 文件并且添加一行
export PATH=~/.npm-global/bin:$PATH
  1. 回到命令行,更新系统变量
source ~/.profile

测试一下,不使用 sudo 下载一个包到全局

npm install -g jshint

你也可以使用环境变量来代替 2~4 步(当你不想更改 ~/.profile

NPM_CONFIG_PREFIX=~/.npm-global npm install -g jshint

OK, 就这样啦~ 希望会有帮助吧

好久之前遇到的,一直没有时间记录下,今天记录一下

贴个代码

import Component1 from "./component1.jsx";
import Component2 from "./component2.jsx";

这时候我们想要在 render 的时候动态判断,然后加载不同的组件,怎么办呢?
试试这个:

render() {
    let Comp = choose1 ? eval(Component1) : eval(Component2);
    
    return (
        <Comp prop1={data1} prop2={data2} />
    );
}

嗯嗯,大概就是这样~ 很简单吧~

好啦,就这样吧,晚安~

----------- 2016.08.31 更新 ----------------

好久没有写 react 了,最近又开始写的时候,发现已经不需要这么麻烦了

大概这个样子就可以

render() {
    let Comp = choose1 ? Component1 : Component2;
    
    return (
        <Comp prop1={data1} prop2={data2} />
    );
}

嗯嗯,就是这样!

周末了解了一下HTTP2.0相关的一点儿东西,然后就迫不及待的在博客上搞一下试试。

博客是用的 Nginx 1.6 比较老的版本,然后 Nginx 在 1.9.5 的版本已经加入了 HTTP2.0 的扩展模块,之前的版本可以使用 SPDY 扩展模块来实现 SPDY 协议。

先不扯了,搞起搞起~

先升级一下 Nginx,下载最新的 Nginx 版本,现在最新是1.9.7,然后要下载最新的SSL模块,接下来就是编译安装啦

进到你的 Nginx 源码目录,配置要添加的模块,需要至少 http_v2_module 和 http_ssl_module 两个模块

./configure --with-openssl=../openssl-x.x.x --with-http_v2_module --with-http_ssl_module

然后

make

替换 nginx

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/nginx
make upgrade

OK,去HTTP/2 Test测试一下效果

哇哈哈哈,去看看速度测试跑个分儿

然后,据说 HTTP 2.0 在IE 11(据说只有win 10的IE 11才支持)以下都不支持,然后我在IE 10下打开了一下博客,貌似也能打开,但是是HTTP 1.1,难道会降级? 这个再研究一下~

好啦,就到这儿啦~

发现了一个比较神奇的坑,拿过来记一下。

今天用browserify构建代码的时候,发现老是提示:
Error: EMFILE, open '.........'
郁闷的很,完全看不出原因,于是乎求助全知的谷姐,被告知一条消息:“打开文件过多”

What's the ....

好吧,大概翻了一下,因为browserify是将你require的若干个模块打到一个文件里,所以会有大量的文件读写操作,然后如果你reqiure的模块比较多的时候,就会出现使用文件超出系统限制的情况,据说OS X默认是255个文件。。。

好吧,果然平时不操作文件不知道还有这些问题。。。

那解决办法呢?

ulimit -n 2560

执行这条命令或者把它添加到你的 bash_profile 里面就OK了~

然后回来来看看这个 ulimit 命令,大概瞅了一下,主要是用于限制资源的,比如说,来限制最多可占用多少的内存呀、限制最多可以起多少的进程呀、读写文件的大小呀等等,对于优化系统性能以及做约束感觉还是很有用的,详情可以自行度娘,我这“眨眼忘”的记性也是记不住了,知道一下,以后方便查找就好。

嗯嗯,又是一篇水文~

好吧,先这样吧,晚安啦~

说到less是好久以前就用过了,因为语法很简单,很容易上手,能很方便的提高书写css的效率,自己玩儿的也是飞起。直到那一次为了写动画,出现了一个问题: 因为用到很多keyframes,所以就要写大量的重复的前缀做兼容。当时自己尚年少,还木有接触到前端自动化的各大神器,所以当时想到的就是自己写个mixin来做这些事情呗。然后纠结着写了一上午,愣是写不出一个可以方便使用的mixin,简直沮丧。 然后翻阅google,发现sass可以很方便的解决这个问题,因为人家有个很方便的特性叫做@content,可以很方便的解决问题,比如这样

@mixin keyframes($name) {
  @-webkit-keyframes #{$name} {
    @content;
  }

  @-moz-keyframes #{$name} {
    @content;
  }

  @keyframes #{$name} {
    @content;
  }
}

@include keyframes(fadeIn) {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

然后就会被编译成这样:

@-webkit-keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

@-moz-keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
}

这酸爽~ 然后稍做考虑,就从less跳向了sass。后来和sass相处也一直很愉快,因为sass有很多特性都特别好用,能完成更复杂的事情。最开始选less没选sass主要是因为sass写起来要比less麻烦一些,从上面的例子中就稍微可以看出一些来。

再然后就是最近的项目又开始用less了,主要原因是因为less实在写起来很简单,再一个就是sass的特性也不是很经常用,日常用less足矣,接着就又出现了上面说的问题。。。

脑子当时第一时间的反应是:“妹的!不会又要转去sass吧?!”,后来少做冷静,我觉得再用less试试,说不能会有好办法,继续翻阅google,然后就发现了这样一条信息
“LESS在1.7.0版本中加入了一个新特性,叫做 passing rulesets to mixins”,哎呦喂~ 果断去文档瞅了两眼,就是这货!
然后就出现了下面的代码:

.keyframes(@name, @rules) {
  @-webkit-keyframes @name {
    @rules();
  }

  @-moz-keyframes @name {
    @rules();
  }

  @keyframes @name {
    @rules();
  }
}

.keyframes(fadeIn, {
  from {
    opacity: 0%;
  }
  to {
    opacity: 100%;
  }
});

怎么样,“就是这个味儿!”,而且还加量不加价哦~

文档中说这里可以传入的不只是变量,css代码块,还可以传入mixin哦~ 将函数作为参数听上去是不是有些耳熟?没错,就是js,利用这个特性我们可以写出很多有趣的东西出来,这里就不多扯了,嘿嘿~

很好,今天也就这样吧,感觉扯了一堆没有用的,最后干货就最后几句话。。。 Orz, 不要在意这些细节,就全当看短篇小说了,乐呵一下就好。

就这样吧,晚安啦~

麻麻说人丑就该多读书,换到程序员身上就是:“人丑就要多写代码”。。。


今天又是写代码的时候就突然对meta标签产生了浓厚的兴趣,原因是因为今天在去偷瞄某网站的代码的时候,发现了一个奇葩的属性值
<meta name="renderer" content="webkit">
傻傻的愣了几秒,“这货是个啥?没见过呀。。。”,因为做前端的都知道要在meta标签里设置一些浏览器渲染属性,网页属性,还有一些SEO属性等等,但是这个renderer值还是真的没见过,果断去查了下资料,发现了一个新的世界!
这货是针对360浏览器的一个标识。因为现在很多浏览器都引进了双核的概念,所以360就搞了这么一个属性来表示如果是双核的浏览器的话,渲染页面的时候使用后面指定的浏览器内核,也就是webkit内核进行渲染。。。
好吧,尽然还是个国产标签,然后在查资料的时候还发现了另外一些好玩儿的东西,比如:

<!-- uc强制竖屏 -->
<meta name="screen-orientation" content="portrait">
<!-- QQ强制竖屏 -->
<meta name="x5-orientation" content="portrait">
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes">
<!-- QQ强制全屏 -->
<meta name="x5-fullscreen" content="true">
<!-- UC应用模式 -->
<meta name="browsermode" content="application">
<!-- QQ应用模式 -->
<meta name="x5-page-mode" content="app">
<!-- windows phone 点击无高光 -->
<meta name="msapplication-tap-highlight" content="no">

真的进入了一个全新的世界!!有木有!! 原来这货还有这么多奇葩的标签!!!
然后还有一些比较有趣的标签,比如:

<!-- 5秒钟刷新 -->
<meta http-equiv="refresh" content="5" />

好吧,这依然只是冰山一角而已,后来又查到了大量的这种基本都很少(mei)见(yong)的标签,就不一一的列下了,放下几个链接下来,留着各位看官老爷闲时翻翻看看。
也算给自己mark一下,说不定哪天心(sang)情(xin)大(bing)好(kuang)的时候就翻来戳到代码里~

HTML Meta标签知多少
HTML Meta Tags
meta | MDN


好吧,今天也就先写这些吧,也没啥技术含量
顺手打个广告,出门右转,可以进入“传送门”页面,然后,嘿嘿,你懂的~
好了木有了,晚安吧~

很好,每天折腾涨姿势~

最近赶进度,速度记一下:
就是今天写了一个json的配置文件,然后随手标上了两行注释,然后node读的时候就报错了,一直以后json就是js的语法,后来查阅了一下发现了说json文件是不支持注释的,想了想也对,人家本来就是一个数据形式,一条字符串而已,注释这种东西貌似确实有点儿不适合。。。。
所以呢,我们就放弃注释了么?想象一下别人看你这配置文件是的表情,就这个feel,倍儿爽~~ 爽爽爽爽~~
咳咳,拉回来。所以我们怎么加注释呢?
咳咳,小葵花妈妈课堂开课啦~ 孩子调试BUG老不好,多半是废了!
不扯了,在github上发现了这么一个货:

{
  "//": "a comment",
  "//": "another comment"
}

妈妈再也不用担心我的学习!

先记这么多,吃包辣条继续赶项目~

好久没更新技术文章了,这次更新还是有点儿水。。。 没事儿,水惯了就好了,哈哈

这次这个货呢主要是最近在写一个比较好玩儿的东西,在做动画的主程序循环的时候,想起了这货 -- requestAnimationFrame, HTML5的新增函数,主要在于提高动画的执行效率,尤其是canvas和svg这种的。用起来很赞,但是兼容性嘛。。。。 呵呵。。。

so~ 这次我主要是记一下这货的兼容写法(终于进入正题了。。。)

(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) {
    var currTime = new Date().getTime();
    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    var id = window.setTimeout(function() {
        callback(currTime + timeToCall);
    }, timeToCall);
    lastTime = currTime + timeToCall;
    return id;
};
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) {
    clearTimeout(id);
};
}());

嗯嗯,大概就是这样。。。 也没啥好细说的,简单明了

很好,水贴完成! 走你~

很好,这篇主要是mark用,方便以后再翻阅


首先是用到CSS的filter属性,最开始貌似是IE4开始加的私有属性,可以实现透明、模糊、阴影、发光、灰度等效果,代码是长这样式儿的:


filter: gray /* IE6 - IE9 */



再后来IE10就开始抛弃这个属性了,但是CSS3借鉴了这个做法,标准的CSS Filter方案里面可以支持grayscale灰度、sepia褐色、saturate饱和度、hue-rotate色相旋转、invert反色、opacity透明度、brightness亮度、contrast对比度、blur模糊、drop-shadow阴影等十种效果,然后代码是长这样式儿的:


filter: grayscale(100%);    /* 标准写法 */ 


然后对各个浏览器再单独加前缀


css filter的浏览器兼容情况是这样的: 

        Chrome31+,

        Safari7+,

        Opera20+,

        ios Safari6+,

        Android Browser4.4+,

        Blackberry 10+均支持了-webkit-filter的方式,

但是:

        IE不支持,firefox不支持


再然后呢,Firefox虽说不支持css filter,但是支持svg effects for html,html文件可以调用svg里面的效果,不仅仅是滤镜、还可以是mask、clip等

然后呢,Firefox下我们可以写成这样的:


filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 3.5+ */


很好,现在就只剩下 IE10 和 IE11 了,那么有什么办法呢?


呵呵,很高兴的告诉你,CSS不行!


但是我们可以用js

http://james.padolsey.com/demos/grayscale/grayscale.js

这个插件,引进来以后用

grayscale(document.body);

执行生效

但是 ---- 注意!!!!!

这货执行起来非常的慢,并且后面如果后续的动态修改的dom是不生效的,所以不建议使用


然后那我们的CSS就可以写成这样:


html {
        filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
        -webkit-filter: grayscale(100%); /* chrome+ */
        filter: grayscale(100%); /* 未来浏览器 */
        filter: gray; /* ie6-8 */
        filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);/*ie6-9 */
}


恩恩,大概就长这样儿,不兼容 IE10 和 IE11



貌似还有几个jQuery的插件,但是没有去试,如果有发现好的欢迎留言告诉我~

最后,为鲁甸祈福~

故事的起因源于群中有人提的一个问题:

a(1)=1;

a(1)(2)=3;

a(1)(2)(3)=6;

还原出函数a

好吧,我刚看到这个题目的时候,第一反应就是递归的闭包,然后就写了下面这一版:

var a = function(num){
    this.sum = this.sum || 0;
    if(num){
        this.sum += num;
        return a;
    }
    var result = this.sum;
    delete this.sum;
    return result;
}

但是这样的执行是这样的:

a(1)();    // 1

a(1)(2)(); // 3

和题目要求的不一样,而且还有sum没有及时重置,所以,这个办法不行

然后想了一会儿没想出好办法,就去求助原公司大牛。果然大牛就是不一样,给出了下面这个解决方案

function a(x){
    var list = [];
    list.push(x);
    var y = function(xx){
        list.push(xx);
        return y;
    };
    y.valueOf = function(){
        return list.reduce(function(a,b){return a+b;},0);
    }
    return y;
}

利用valueOf和闭包里的一个list做的,果断膜拜了一下

然后,后来有看到群里有人给出了这样的答案:

function a(num){
    function b(i){
        return a(num+i);
    }
    b.toString = function(){
        return num;
    };
    return b;
}

也是可以的,然后就比较好奇,这个valueOf和toString是怎样被执行的呢?

果断去补习了一下基础知识:

对于所有的js对象(除了null以外),都有valueOf和toString方法,这是为了更方便的对一个对象进行值的操作

比如说我们要比较两个object的大小的时候,就可以定义一下它的valueOf方法或者toString來比较大小,那么到底什么时候会调用这两个方法呢?

来看一个小测试:

    var bbb = {
        i: 10,
        toString: function() {
          console.log('toString');
          return this.i;
        },
        valueOf: function() {
          console.log('valueOf');
          return this.i;
        }
      }
      alert(bbb);          // 10 toString
      alert(+bbb);         // 10 valueOf
      alert(''+bbb);       // 10 valueOf
      alert(String(bbb));  // 10 toString
      alert(Number(bbb));  // 10  valueOf
      alert(bbb == '10');  // true valueOf
      alert(bbb === '10'); // false

貌似是跟字符串有关的会调用toString,而根数字有关的会调用valueOf方法,但是,我们发现(''+bbb)这个调用的是valueOf,而最后的===则什么都没有调用,那我们再试一下:

    var aa = {
        i: 10,
        toString: function() {
          console.log('toString');
          return this.i;
        }
      }
      alert(aa);         // 10 toString
      alert(+aa);        // 10 toString
      alert(''+aa);      // 10 toString
      alert(String(aa)); // 10 toString
      alert(Number(aa)); // 10 toString
      alert(aa == '10'); // true toString

很和谐的全是toString,再看看valueOf的:

    var bb = {
        i: 10,
        valueOf: function() {
          console.log('valueOf');
          return this.i;
        }
      }
      alert(bb);         // [object Object]
      alert(+bb);        // 10 valueOf
      alert(''+bb);      // 10 valueOf
      alert(String(bb)); // [object Object]
      alert(Number(bb)); // 10 valueOf
      alert(bb == '10'); // true valueOf

我们发现中间出现了[object Object],貌似是从Object那里继承过来的,我们把它去掉试试:

Object.prototype.toString = null;
var cc = {
    i: 10,
    valueOf: function() {
        console.log('valueOf');
        return this.i;
    }
}
alert(cc);         // 10 valueOf
alert(+cc);        // 10 valueOf
alert(''+cc);      // 10 valueOf
alert(String(cc)); // 10 valueOf
alert(Number(cc)); // 10 valueOf
alert(cc == '10'); // true valueOf

貌似和谐多了,那我们基本可以看到是这样的,如果只定义了toString方法,那么当遇到需要类型转换的时候,就会直接调用toString方法,然后如果只定义了valueOf方法的话,转换数字的时候会优先调用valueOf方法,然后在转换字符串的时候,如果实在没有toString可以调用才会用valueOf代替,对于有操作符的情况下(比如=),valueOf的优先级要比toString要高

感谢 小秦 同学纠正:当转换为数字类型的时候,如果 valueOf 返回的不是基础类型,才会调用 toString 方法

好了,那我们还有最后一个问题,(''+bbb),这个字符串拼接为什么是调用的valueOf呢?

这个问题应该是因为+操作符上,这里会有一个getValue操作,然后就调用valueOf方法了

嗯,好的,今天就这么多,有不对的地方欢迎指正~