-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathm2mbob.ghost.2016-05-30.json
1 lines (1 loc) · 120 KB
/
m2mbob.ghost.2016-05-30.json
1
{"db":[{"meta":{"exported_on":1464595243778,"version":"004"},"data":{"posts":[{"id":1,"uuid":"7773c41c-7513-46d6-a5eb-a1256d0f73a2","title":"Welcome to Ghost","slug":"welcome-to-ghost","markdown":"You're live! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at `<your blog URL>/ghost/`. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!\n\n## Getting Started\n\nGhost uses something called Markdown for writing. Essentially, it's a shorthand way to manage your post formatting as you write!\n\nWriting in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use *shortcuts* to **style** your content. For example, a list:\n\n* Item number one\n* Item number two\n * A nested item\n* A final item\n\nor with numbers!\n\n1. Remember to buy some milk\n2. Drink the milk\n3. Tweet that I remembered to buy the milk, and drank it\n\n### Links\n\nWant to link to a source? No problem. If you paste in a URL, like http://ghost.org - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to [the Ghost website](http://ghost.org). Neat.\n\n### What about Images?\n\nImages work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:\n\n![The Ghost Logo](https://ghost.org/images/ghost.png)\n\nNot sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:\n\n![A bowl of bananas]\n\n\n### Quoting\n\nSometimes a link isn't enough, you want to quote someone on what they've said. Perhaps you've started using a new blogging platform and feel the sudden urge to share their slogan? A quote might be just the way to do it!\n\n> Ghost - Just a blogging platform\n\n### Working with Code\n\nGot a streak of geek? We've got you covered there, too. You can write inline `<code>` blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.\n\n .awesome-thing {\n display: block;\n width: 100%;\n }\n\n### Ready for a Break? \n\nThrow 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.\n\n---\n\n### Advanced Usage\n\nThere's one fantastic secret about Markdown. If you want, you can write plain old HTML and it'll still work! Very flexible.\n\n<input type=\"text\" placeholder=\"I'm an input field!\" />\n\nThat should be enough to get you started. Have fun - and let us know what you think :)","html":"<p>You're live! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. You can manage your content by signing in to the admin area at <code><your blog URL>/ghost/</code>. When you arrive, you can select this post from a list on the left and see a preview of it on the right. Click the little pencil icon at the top of the preview to edit this post and read the next section!</p>\n\n<h2 id=\"gettingstarted\">Getting Started</h2>\n\n<p>Ghost uses something called Markdown for writing. Essentially, it's a shorthand way to manage your post formatting as you write!</p>\n\n<p>Writing in Markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use <em>shortcuts</em> to <strong>style</strong> your content. For example, a list:</p>\n\n<ul>\n<li>Item number one</li>\n<li>Item number two\n<ul><li>A nested item</li></ul></li>\n<li>A final item</li>\n</ul>\n\n<p>or with numbers!</p>\n\n<ol>\n<li>Remember to buy some milk </li>\n<li>Drink the milk </li>\n<li>Tweet that I remembered to buy the milk, and drank it</li>\n</ol>\n\n<h3 id=\"links\">Links</h3>\n\n<p>Want to link to a source? No problem. If you paste in a URL, like <a href=\"http://ghost.org\">http://ghost.org</a> - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to <a href=\"http://ghost.org\">the Ghost website</a>. Neat.</p>\n\n<h3 id=\"whataboutimages\">What about Images?</h3>\n\n<p>Images work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:</p>\n\n<p><img src=\"https://ghost.org/images/ghost.png\" alt=\"The Ghost Logo\" /></p>\n\n<p>Not sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:</p>\n\n<h3 id=\"quoting\">Quoting</h3>\n\n<p>Sometimes a link isn't enough, you want to quote someone on what they've said. Perhaps you've started using a new blogging platform and feel the sudden urge to share their slogan? A quote might be just the way to do it!</p>\n\n<blockquote>\n <p>Ghost - Just a blogging platform</p>\n</blockquote>\n\n<h3 id=\"workingwithcode\">Working with Code</h3>\n\n<p>Got a streak of geek? We've got you covered there, too. You can write inline <code><code></code> blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.</p>\n\n<pre><code>.awesome-thing {\n display: block;\n width: 100%;\n}\n</code></pre>\n\n<h3 id=\"readyforabreak\">Ready for a Break?</h3>\n\n<p>Throw 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.</p>\n\n<hr />\n\n<h3 id=\"advancedusage\">Advanced Usage</h3>\n\n<p>There's one fantastic secret about Markdown. If you want, you can write plain old HTML and it'll still work! Very flexible.</p>\n\n<p><input type=\"text\" placeholder=\"I'm an input field!\" /></p>\n\n<p>That should be enough to get you started. Have fun - and let us know what you think :)</p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463567128012,"created_by":1,"updated_at":1463567128012,"updated_by":1,"published_at":1463567128044,"published_by":1},{"id":2,"uuid":"9a9d44c4-cfa6-45eb-85aa-0ad8e81d4389","title":"redux源码分析系列之compose.js","slug":"compose-js","markdown":"## compose.js\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=27566686&auto=1&height=66\"></iframe>\n\n听宝宝的话要早点睡,所以就先写最简单的一个哈😳!废话不多说先贴源码:\n\n```\nexport default function compose(...funcs) {\n if (funcs.length === 0) {\n return arg => arg\n } else {\n const last = funcs[funcs.length - 1]\n const rest = funcs.slice(0, -1)\n return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))\n }\n}\n```\n\n先来看看代码的意思,如果没有传入函数,则返回了一个接受参数并原样返回的函数;如果传入的函数数组长度大于0,则取出右边的函数为`last`,其余的为`rest`,然后返回一个函数。这个函数用`last(...args)`为高阶函数`reduceRight`迭代的初始值进行迭代,每次迭代的结果将被传入下一个函数充当参数。\n> 注:`reduceRight`为es5引入的方法,使用形式如下Array.reduceRight((prev,current,index,array) => (...), initialValue),它会为数组中的元素从右向左执行回调方法。\n\n举例来说,有三个函数`a,b,c`,参数为args,`f=compose(a,b,c)`,`f(...args)`执行的效果就和`a(b(c(...args)))`一样,目的就是将多个函数组合起来。在redux中像`middleware`、`reducer`等多处使用到了compose。不早了,今天先到这哈😀!\n\n","html":"<h2 id=\"composejs\">compose.js</h2>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=27566686&auto=1&height=66\"></iframe>\n\n<p>听宝宝的话要早点睡,所以就先写最简单的一个哈😳!废话不多说先贴源码:</p>\n\n<pre><code>export default function compose(...funcs) { \n if (funcs.length === 0) {\n return arg => arg\n } else {\n const last = funcs[funcs.length - 1]\n const rest = funcs.slice(0, -1)\n return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))\n }\n}\n</code></pre>\n\n<p>先来看看代码的意思,如果没有传入函数,则返回了一个接受参数并原样返回的函数;如果传入的函数数组长度大于0,则取出右边的函数为<code>last</code>,其余的为<code>rest</code>,然后返回一个函数。这个函数用<code>last(...args)</code>为高阶函数<code>reduceRight</code>迭代的初始值进行迭代,每次迭代的结果将被传入下一个函数充当参数。</p>\n\n<blockquote>\n <p>注:<code>reduceRight</code>为es5引入的方法,使用形式如下Array.reduceRight((prev,current,index,array) => (...), initialValue),它会为数组中的元素从右向左执行回调方法。</p>\n</blockquote>\n\n<p>举例来说,有三个函数<code>a,b,c</code>,参数为args,<code>f=compose(a,b,c)</code>,<code>f(...args)</code>执行的效果就和<code>a(b(c(...args)))</code>一样,目的就是将多个函数组合起来。在redux中像<code>middleware</code>、<code>reducer</code>等多处使用到了compose。不早了,今天先到这哈😀!</p>","image":"/content/images/2016/05/687474703a2f2f692e696d6775722e636f6d2f4a65567164514d2e706e67-2.png","featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463567445619,"created_by":1,"updated_at":1463802780875,"updated_by":1,"published_at":1463755965662,"published_by":1},{"id":3,"uuid":"4cfddac0-e27b-478d-a53e-21edf2583e73","title":"mac木有随意行的解决方案——实践篇","slug":"macmu-you-sui-yi-xing-de-jie-jue-fang-an-shi-jian-pian","markdown":"由于把旧的电脑带回家了,宝宝再也不能够在床上玩电脑了,可恶的是还要配置mac的网络。万恶的移动没有提供mac版的随意行,因此需要自己设置vpn,可怕!宝宝慌了,还好凭借宝宝的聪明脑瓜,把网络配置好了,先拿出来分享。至于其中原理,宝宝还要研究研究,下次分享哈!\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=26590186&auto=1&height=66\"></iframe>\n\n#### 第一步 买一个端口转换器\n\n> 注:附上我的购买链接[点我点我。](https://detail.tmall.com/item.htm?_u=l22095huca16&id=524667361946)不过这个上网网速还不如实验室2M小水管,建议大家上京东买正版,可恶的奎君周不早说😒!\n\n#### 第二步 连接网线、端口转换器、usb端口\n\n> 此时会自动产生如下图选中的Apple USB Ethernet Adapter。\n\n![](http://i2.buimg.com/2ccebf51fda84a4f.png)\n\n#### 第三步 选择此处的创建PPPoE服务\n\n![](http://i2.buimg.com/fbd4a285336f5a32.png)\n\n#### 第四步 设置PPPoE服务相关参数,也就是宽带连接的用户名密码\n\n![](http://i2.buimg.com/0439e1aa3491c16a.png)\n\n#### 第五步 创建vpn,选择IPSec上的L2TP\n\n![](http://ww2.sinaimg.cn/large/74311666jw1f43bdxaykmj21140va44u.jpg)\n\n### 第六步 设置vpn相关参数,服务器地址和账户名,密码,并把高级设置里的通过VPN发送所有流量钩上\n\n![](http://i2.buimg.com/313dab572cd9de9c.png)\n\n### 第七步 增加 /etc/ppp/options 配置文件,内容如下图\n\n![](http://i4.buimg.com/09da1eb1c2bff5ff.png)\n\n![](http://i4.buimg.com/cb065aab4219b762.png)\n\n","html":"<p>由于把旧的电脑带回家了,宝宝再也不能够在床上玩电脑了,可恶的是还要配置mac的网络。万恶的移动没有提供mac版的随意行,因此需要自己设置vpn,可怕!宝宝慌了,还好凭借宝宝的聪明脑瓜,把网络配置好了,先拿出来分享。至于其中原理,宝宝还要研究研究,下次分享哈!</p>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=26590186&auto=1&height=66\"></iframe>\n\n<h4 id=\"\">第一步 买一个端口转换器</h4>\n\n<blockquote>\n <p>注:附上我的购买链接<a href=\"https://detail.tmall.com/item.htm?_u=l22095huca16&id=524667361946\">点我点我。</a>不过这个上网网速还不如实验室2M小水管,建议大家上京东买正版,可恶的奎君周不早说😒!</p>\n</blockquote>\n\n<h4 id=\"usb\">第二步 连接网线、端口转换器、usb端口</h4>\n\n<blockquote>\n <p>此时会自动产生如下图选中的Apple USB Ethernet Adapter。</p>\n</blockquote>\n\n<p><img src=\"http://i2.buimg.com/2ccebf51fda84a4f.png\" alt=\"\" /></p>\n\n<h4 id=\"pppoe\">第三步 选择此处的创建PPPoE服务</h4>\n\n<p><img src=\"http://i2.buimg.com/fbd4a285336f5a32.png\" alt=\"\" /></p>\n\n<h4 id=\"pppoe\">第四步 设置PPPoE服务相关参数,也就是宽带连接的用户名密码</h4>\n\n<p><img src=\"http://i2.buimg.com/0439e1aa3491c16a.png\" alt=\"\" /></p>\n\n<h4 id=\"vpnipsecl2tp\">第五步 创建vpn,选择IPSec上的L2TP</h4>\n\n<p><img src=\"http://ww2.sinaimg.cn/large/74311666jw1f43bdxaykmj21140va44u.jpg\" alt=\"\" /></p>\n\n<h3 id=\"vpnvpn\">第六步 设置vpn相关参数,服务器地址和账户名,密码,并把高级设置里的通过VPN发送所有流量钩上</h3>\n\n<p><img src=\"http://i2.buimg.com/313dab572cd9de9c.png\" alt=\"\" /></p>\n\n<h3 id=\"etcpppoptions\">第七步 增加 /etc/ppp/options 配置文件,内容如下图</h3>\n\n<p><img src=\"http://i4.buimg.com/09da1eb1c2bff5ff.png\" alt=\"\" /></p>\n\n<p><img src=\"http://i4.buimg.com/cb065aab4219b762.png\" alt=\"\" /></p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463834942922,"created_by":1,"updated_at":1463838155173,"updated_by":1,"published_at":1463837040160,"published_by":1},{"id":4,"uuid":"52d5cb6e-e34b-46a8-a91f-adda39d7e944","title":"mac安装mongodb","slug":"macan-zhuang-mongodb","markdown":"<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=41665696&auto=1&height=66\"></iframe>\n\n#### 安装Homebrew\n Homebrew是Mac OSX下一个包依赖管理工具,用它来安装软件非常的方便只需要brew install 软件名这一条命令就可以将你所需要的软件安装好,不用再操心安装过程中软件的依赖问题,这些问题Homebrew统统帮你搞定。Homebrew安装方法也很简单:打开终端,然后输入命令\n \n<!--bash-->\n\truby -e \"$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)\"\n\n#### 安装mongodb\n 如果是之前就已经安装好的Homebrew,那先要更新一下库:\n \n<!--bash-->\n\tbrew update\n 然后执行下面命令安装mongodb:\n \n<!--bash-->\n\tbrew install mongodb\n --with-openssl参数表示通过ssl源安装,--devel表示安装最新开发版。此时通过mongod --config /usr/local/etc/mongodb.conf命令已经可以启动。(3.0.7版本是如此。)\n\n#### 遇到的几个问题\n1.\t我第一次安装完以后,装了Robomongo,但是在连接时发现了bug,一直Authorization skip by you的错误。然后改dbpath、logpath等等操作,都不奏效,就把mongodb玩坏了。最后google得到Robomongo还不支持mongodb3,解决方案在此[http://http://liyanjie918.blog.163.com/blog/static/2022729020156261410274/](http://http://liyanjie918.blog.163.com/blog/static/2022729020156261410274/ \"使用Robomongo 连接MongoDB 3.x 报 Authorization failed 解决办法\")\n2.\t可能还会遇到找不到/data/db路径,这是mongdb在之前版本时默认的dbpath,如果安装的是2.*的版本可能就会遇到这个问题,就需要:mkdir -p /data/db\n另外,最后还会有一个权限问题,用sudo chmod R 当前用户名 /data 命令能够解决。\n3.\t大致问题如上,出现这些问题主要还是对mac系统文件和权限等不熟,已经太久没有动mongo,所以也有点生疏了。","html":"<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=41665696&auto=1&height=66\"></iframe>\n\n<h4 id=\"homebrew\">安装Homebrew</h4>\n\n Homebrew是Mac OSX下一个包依赖管理工具,用它来安装软件非常的方便只需要brew install 软件名这一条命令就可以将你所需要的软件安装好,不用再操心安装过程中软件的依赖问题,这些问题Homebrew统统帮你搞定。Homebrew安装方法也很简单:打开终端,然后输入命令\n \n<!--bash--> \n\n<pre><code>ruby -e \"$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)\"\n</code></pre>\n\n<h4 id=\"mongodb\">安装mongodb</h4>\n\n 如果是之前就已经安装好的Homebrew,那先要更新一下库:\n \n<!--bash--> \n\n<pre><code>brew update\n</code></pre>\n\n 然后执行下面命令安装mongodb:\n \n<!--bash--> \n\n<pre><code>brew install mongodb\n</code></pre>\n\n<p> --with-openssl参数表示通过ssl源安装,--devel表示安装最新开发版。此时通过mongod --config /usr/local/etc/mongodb.conf命令已经可以启动。(3.0.7版本是如此。)</p>\n\n<h4 id=\"\">遇到的几个问题</h4>\n\n<ol>\n<li>我第一次安装完以后,装了Robomongo,但是在连接时发现了bug,一直Authorization skip by you的错误。然后改dbpath、logpath等等操作,都不奏效,就把mongodb玩坏了。最后google得到Robomongo还不支持mongodb3,解决方案在此<a href=\"http://http://liyanjie918.blog.163.com/blog/static/2022729020156261410274/\" title=\"使用Robomongo 连接MongoDB 3.x 报 Authorization failed 解决办法\">http://http://liyanjie918.blog.163.com/blog/static/2022729020156261410274/</a> </li>\n<li>可能还会遇到找不到/data/db路径,这是mongdb在之前版本时默认的dbpath,如果安装的是2.*的版本可能就会遇到这个问题,就需要:mkdir -p /data/db <br />\n另外,最后还会有一个权限问题,用sudo chmod R 当前用户名 /data 命令能够解决。</li>\n<li>大致问题如上,出现这些问题主要还是对mac系统文件和权限等不熟,已经太久没有动mongo,所以也有点生疏了。</li>\n</ol>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463838003388,"created_by":1,"updated_at":1463838618095,"updated_by":1,"published_at":1463838208563,"published_by":1},{"id":5,"uuid":"2b51ebd5-cda4-4792-b84e-5874f72d42a2","title":"koa1源码分析之Application","slug":"koa1yuan-ma-fen-xi-zhi-application","markdown":"##Application\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=32507038&auto=1&height=66\"></iframe>\n\n原来写的文章,迁移过来,还是koa1的,koa2也出了,待更新。\n\n###依赖\n\n- debug:debug源码分析;\n- compose_es7:与co.wrap相似,不过能够接受 async/await 函数;\n- onFinished:捕捉finish或error事件,并根据第二个参数执行回调;\n- compose:compose_es7的简化版,只接受generator;\n- isJSON:顾名思义,判断传入参数是否为JSON;\n- statuses:将http码分为三类,redirect、empty以及retry,然后根据传入的http来判断属于哪一类;\n- accepts:根据req的内容判断(content negotiation)字段,如accept,Accept-Encoding,Accept-Language等字段对这些字段进行格式化,方便后续处理;\n- only:只返回在传入参数里所包含的字段;\n- co:co源码解析\n\n###构造器源码\n\n<!--javascript-->\n\t/**\n\t * Initialize a new `Application`.\n\t *\n\t * @api public\n\t */\n\tfunction Application() {\n\t if (!(this instanceof Application)) return new Application;\n\t this.env = process.env.NODE_ENV || 'development';\n\t this.subdomainOffset = 2;\n\t this.middleware = [];\n\t this.proxy = false;\n\t this.context = Object.create(context);\n\t this.request = Object.create(request);\n\t this.response = Object.create(response);\n\t}\n\n上面koa的Application的构造函数,可以看到在创建Application时有初始化如下属性:\n\n1. env表示是开发环境还是生产环境,通过process.env.NODE_ENV读取环境变量中的参数设置,如果没有设置默认为开发环境\n2. subdomainOffset,表示子域名的偏移,默认为2\n3. proxy如果为true,则解析 \"Host\" 的 header 域,并支持X-Forwarded-Host,默认为false。\n4. context上下文\n5. request请求对象\n6. response响应对象\n\n#### 有哪些方法\n\n#### app.listen\n\n<!--javascript-->\n\t/**\n\t * Shorthand for:\n\t *\n\t * http.createServer(app.callback()).listen(...)\n\t *\n\t * @param {Mixed} ...\n\t * @return {Server}\n\t * @api public\n\t */\n\tapp.listen = function(){\n\t debug('listen');\n\t var server = http.createServer(this.callback());\n\t return server.listen.apply(server, arguments);\n\t};\n\n 这个方法调用了node原生的http模块创建了一个server,要关注的是传入的这个callback。\n\n\n\n#### app.callback\n<!--javascript-->\n\n\t/**\t\n\t * Return a request handler callback\n\t * for node's native http server.\n\t *\n\t * @return {Function}\n\t * @api public\n\t */\n\tapp.callback = function(){\n\t var fn = this.experimental\n\t ? compose_es7(this.middleware)\n\t : co.wrap(compose(this.middleware));\n\t var self = this;\n\t if (!this.listeners('error').length) this.on('error', this.onerror);\n\t return function(req, res){\n\t res.statusCode = 404;\n\t var ctx = self.createContext(req, res);\n\t onFinished(res, ctx.onerror);\n\t fn.call(ctx).then(function () {\n\t respond.call(ctx);\n\t }).catch(ctx.onerror);\n\t }\n\t};\n\n 返回一个适合 http.createServer() 方法的回调函数用来处理请求。 您也可以使用这个回调函数将您的app挂载在 Connect/Express 应用上。一点点看下来,this.middleware是中间件的一个数组,用co.wrap或者compose_es7进行包装,co是tj大神的一个用来包装执行generator函数的库,而compose_es7应该是es7可能会引入的相似功能的特性,不同的是后者支持es7的async/await。后面一句处理错误,最后是返回一个请求处理函数。在函数中会调用createContext创建上下文,用onFinished模块捕捉finish或error事件,并根据第二个参数执行回调。然后调用co包装返回的promise对象进行中间件的调用,调用就由co来进行。调用成功后执行调用respond函数。\n\n#### 最后就来看看respond函数\n\n<!--javascript-->\n\n\t/**\t\n\t * Response helper.\n\t */\n\tfunction respond() {\n\t // allow bypassing koa\n\t if (false === this.respond) return;\n\t var res = this.res;\n\t if (res.headersSent || !this.writable) return;\n\t var body = this.body;\n\t var code = this.status;\n\t // ignore body\n\t if (statuses.empty[code]) {\n\t // strip headers\n\t this.body = null;\n\t return res.end();\n\t }\n\t if ('HEAD' == this.method) {\n\t if (isJSON(body)) this.length = Buffer.byteLength(JSON.stringify(body));\n\t return res.end();\n\t }\n\t // status body\n\t if (null == body) {\n\t this.type = 'text';\n\t body = this.message || String(code);\n\t this.length = Buffer.byteLength(body);\n\t return res.end(body);\n\t }\n\t // responses\n\t if (Buffer.isBuffer(body)) return res.end(body);\n\t if ('string' == typeof body) return res.end(body);\n\t if (body instanceof Stream) return body.pipe(res);\n\t // body: json\n\t body = JSON.stringify(body);\n\t this.length = Buffer.byteLength(body);\n\t res.end(body);\n\t}\n\n 在1.0.0版本中respond函数第一行就是yield *next,也就是一开始不执行,到所有中间件执行完后对res进行处理。但co进入4.*以后,用promise代替了thunk函数的实现,返回一个promise,因此当前1.1.2版本中的respond函数的调用写在了co返回的promise的第一个回调中。\n\n#### 其它\n\n- app.use向中间件数组中添加中间件\n- app.createContext创建请求上下文\n- app.inspect/toJSON返回配置的参数subdomainOffset、proxy和env。","html":"<h2 id=\"application\">Application</h2>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=32507038&auto=1&height=66\"></iframe>\n\n<p>原来写的文章,迁移过来,还是koa1的,koa2也出了,待更新。</p>\n\n<h3 id=\"\">依赖</h3>\n\n<ul>\n<li>debug:debug源码分析;</li>\n<li>compose_es7:与co.wrap相似,不过能够接受 async/await 函数;</li>\n<li>onFinished:捕捉finish或error事件,并根据第二个参数执行回调;</li>\n<li>compose:compose_es7的简化版,只接受generator;</li>\n<li>isJSON:顾名思义,判断传入参数是否为JSON;</li>\n<li>statuses:将http码分为三类,redirect、empty以及retry,然后根据传入的http来判断属于哪一类;</li>\n<li>accepts:根据req的内容判断(content negotiation)字段,如accept,Accept-Encoding,Accept-Language等字段对这些字段进行格式化,方便后续处理;</li>\n<li>only:只返回在传入参数里所包含的字段;</li>\n<li>co:co源码解析</li>\n</ul>\n\n<h3 id=\"\">构造器源码</h3>\n\n<!--javascript--> \n\n<pre><code>/**\n * Initialize a new `Application`.\n *\n * @api public\n */\nfunction Application() {\n if (!(this instanceof Application)) return new Application;\n this.env = process.env.NODE_ENV || 'development';\n this.subdomainOffset = 2;\n this.middleware = [];\n this.proxy = false;\n this.context = Object.create(context);\n this.request = Object.create(request);\n this.response = Object.create(response);\n}\n</code></pre>\n\n<p>上面koa的Application的构造函数,可以看到在创建Application时有初始化如下属性:</p>\n\n<ol>\n<li>env表示是开发环境还是生产环境,通过process.env.NODE_ENV读取环境变量中的参数设置,如果没有设置默认为开发环境 </li>\n<li>subdomainOffset,表示子域名的偏移,默认为2 </li>\n<li>proxy如果为true,则解析 \"Host\" 的 header 域,并支持X-Forwarded-Host,默认为false。 </li>\n<li>context上下文 </li>\n<li>request请求对象 </li>\n<li>response响应对象</li>\n</ol>\n\n<h4 id=\"\">有哪些方法</h4>\n\n<h4 id=\"applisten\">app.listen</h4>\n\n<!--javascript--> \n\n<pre><code>/**\n * Shorthand for:\n *\n * http.createServer(app.callback()).listen(...)\n *\n * @param {Mixed} ...\n * @return {Server}\n * @api public\n */\napp.listen = function(){\n debug('listen');\n var server = http.createServer(this.callback());\n return server.listen.apply(server, arguments);\n};\n</code></pre>\n\n<p> 这个方法调用了node原生的http模块创建了一个server,要关注的是传入的这个callback。</p>\n\n<h4 id=\"appcallback\">app.callback</h4>\n\n<!--javascript-->\n\n<pre><code>/** \n * Return a request handler callback\n * for node's native http server.\n *\n * @return {Function}\n * @api public\n */\napp.callback = function(){\n var fn = this.experimental\n ? compose_es7(this.middleware)\n : co.wrap(compose(this.middleware));\n var self = this;\n if (!this.listeners('error').length) this.on('error', this.onerror);\n return function(req, res){\n res.statusCode = 404;\n var ctx = self.createContext(req, res);\n onFinished(res, ctx.onerror);\n fn.call(ctx).then(function () {\n respond.call(ctx);\n }).catch(ctx.onerror);\n }\n};\n</code></pre>\n\n<p> 返回一个适合 http.createServer() 方法的回调函数用来处理请求。 您也可以使用这个回调函数将您的app挂载在 Connect/Express 应用上。一点点看下来,this.middleware是中间件的一个数组,用co.wrap或者compose<em>es7进行包装,co是tj大神的一个用来包装执行generator函数的库,而compose</em>es7应该是es7可能会引入的相似功能的特性,不同的是后者支持es7的async/await。后面一句处理错误,最后是返回一个请求处理函数。在函数中会调用createContext创建上下文,用onFinished模块捕捉finish或error事件,并根据第二个参数执行回调。然后调用co包装返回的promise对象进行中间件的调用,调用就由co来进行。调用成功后执行调用respond函数。</p>\n\n<h4 id=\"respond\">最后就来看看respond函数</h4>\n\n<!--javascript-->\n\n<pre><code>/** \n * Response helper.\n */\nfunction respond() {\n // allow bypassing koa\n if (false === this.respond) return;\n var res = this.res;\n if (res.headersSent || !this.writable) return;\n var body = this.body;\n var code = this.status;\n // ignore body\n if (statuses.empty[code]) {\n // strip headers\n this.body = null;\n return res.end();\n }\n if ('HEAD' == this.method) {\n if (isJSON(body)) this.length = Buffer.byteLength(JSON.stringify(body));\n return res.end();\n }\n // status body\n if (null == body) {\n this.type = 'text';\n body = this.message || String(code);\n this.length = Buffer.byteLength(body);\n return res.end(body);\n }\n // responses\n if (Buffer.isBuffer(body)) return res.end(body);\n if ('string' == typeof body) return res.end(body);\n if (body instanceof Stream) return body.pipe(res);\n // body: json\n body = JSON.stringify(body);\n this.length = Buffer.byteLength(body);\n res.end(body);\n}\n</code></pre>\n\n<p> 在1.0.0版本中respond函数第一行就是yield <em>next,也就是一开始不执行,到所有中间件执行完后对res进行处理。但co进入4.</em>以后,用promise代替了thunk函数的实现,返回一个promise,因此当前1.1.2版本中的respond函数的调用写在了co返回的promise的第一个回调中。</p>\n\n<h4 id=\"\">其它</h4>\n\n<ul>\n<li>app.use向中间件数组中添加中间件</li>\n<li>app.createContext创建请求上下文</li>\n<li>app.inspect/toJSON返回配置的参数subdomainOffset、proxy和env。</li>\n</ul>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463838292023,"created_by":1,"updated_at":1463838903875,"updated_by":1,"published_at":1463838479996,"published_by":1},{"id":6,"uuid":"9a4be2b6-a671-4302-99fe-d0a54af86417","title":"Yesterday's","slug":"yesterday","markdown":"T团20周年的开场曲,晚上写作业时又拿出来循环播放,听完又是元气满满的一天呀!歌词很棒,拿出来分享分享!\n看到网易云音乐的评论里,一个考研党在2015年9月24日23点33发了一句“正在考研的我听着每一句都是泪”,到4月13日他又评论了一句“我考上了”,中间没有任何别的回复,但多了4个赞。我看到这莫名地就释然了,点了个赞,继续写作业去了,很奇妙的感受,我叫它感同身受!\n20周年那一版因为版权无法生成外链,只有下面这个版本了,不过也很不错!\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=22690729&auto=1&height=66\"></iframe>\n\n風の無い夜の公園で 動かないブランコ達は<br>\n在无风的夜晚公园里 不会摇晃的秋千们<br>\n与此刻的自己 有着可怕的相似<br>\n恐い位似てるんだよ 今の僕自身に<br>\n欲しい物は山ほどある<br>\n想要的东西如山般高<br>\n但手中却什么也没有<br>\nだけど欠片(かけら)も手にできず<br>\n無くしてきた 色んな夢を探してる<br>\n只是搜寻着 那些消逝的梦想<br>\n弱さは人の運命(さだめ)だと<br>\n命运两字是人生的无奈<br>\nなんとなく気付いてるけど<br>\n似乎我也注意到了<br>\n「支えられたい、支えてみたい」忙しく思うよ<br>\n却不停的想着「能撑得,在撑撑看」<br>\n強がる事に不器用で<br>\n就算是徒费力气<br>\n空回りしてもいいから<br>\n硬撑也无所谓<br>\n我只是想不断追寻 那变化多端的未来<br>\n追い続けたい 色んな形の未来を<br>\n觉得容易的事情却意外地<br>\n容易(たやす)く思える事が意外に結構<br>\n无法简单得手<br>\n手に入れるのが難しく思える<br>\n这难道不是跟盯着自己的脚步<br>\nそれってもしかして自分の足元を<br>\n見つめてみればきっと転がってんじゃない<br>\n就会摔跤是一样的道理吗<br>\n激しい雨が降った後にはきれいな花が咲く<br>\n在倾盆大雨过后 娇艳的花儿即将绽放<br>\nあきらめたりしない 届くはずさ想いは<br>\n千万不要放弃 因为梦想即将到达<br>\nそしていっそ昨日までの自分を捨て去ろう<br>\n然后索性忘却到昨天为止的自己吧<br>\n静けさを引き裂くように 空き缶を強く蹴り飛ばす<br>\n仿佛是要将寂静撕裂 狠狠的将罐子踢飞<br>\n胸に秘めた 色んな迷いを詰め込んで<br>\n深藏在内心的 是满满的各种迷茫<br>\n結果だけにしがみついていたよずっと<br>\n一直以来总是只紧抓住结果不放<br>\nプロセスなんか馬鹿らしく思えて<br>\n觉得过程什么的都不重要<br>\n残缺的月 带着勇敢的微笑<br>\n満ち欠ける月のけなげな微笑み<br>\n看吧 太阳一定依旧在你眼前升起<br>\n日はまた昇るきっと目の前にほら<br>\n頬を伝ったどんな涙も大きな価値がある<br>\n脸颊上滑落的 是无价眼泪带来的讯息<br>\n二度とない時を負けないように進むよ<br>\n怀着仅此一次绝不认输的心情前进<br>\n激しい雨が降った後にはきれいな花が咲く<br>\n在大雨倾盆过后 娇艳的花儿即将绽放<br>\nあきらめたりしない 届くはずさ願いは<br>\n千万不要放弃 因为梦想即将到达<br>\nそしていっそ昨日までの自分を捨て去ろう<br>\n然后索性忘却到昨天为止的自己吧<br>\n遠くない近くない捉えずらいホントにいつもやっかいもんは自分<br>\n最难琢磨的是那忽远忽近难以搞定的真实的自己<br>\nそれでも向き合って生きていかなきゃダメさ<br>\n但是不好好奋斗下去是不行的<br>\nだから「昨日までの自分を捨て去ろう」って唄おう<br>\n所以 就让我们唱着「忘却到昨天为止的自己吧」<br>\nいつかはどんな部分(こころ)も愛せる気がするよ<br>\n无论何时 无论何地都感受到爱<br>\n何が起こっても構わない荒波に打たれても<br>\n无论发生任何事 就算是再大的风浪<br>\n僕は信じている最終形の自分を<br>\n我始终相信着最真实的自己<br>\nどれ位こうしてたんだろう<br>\n到底这样过了多久<br>\n街は息を吹き返した<br>\n整个街道重新开始呼吸<br>\n不思議なんだ僕の胸に光がともってく<br>\n不可思议的是我的心也渐渐亮了起来<br>\nそよぎはじめていた風が淋しさを全部連れ去り<br>\n徐徐吹起的微风将一切寂寞带走<br>\n踊りだしたブランコ達も笑ってる<br>\n跳起舞来的秋千们也露出笑意<br>","html":"<p>T团20周年的开场曲,晚上写作业时又拿出来循环播放,听完又是元气满满的一天呀!歌词很棒,拿出来分享分享! <br />\n看到网易云音乐的评论里,一个考研党在2015年9月24日23点33发了一句“正在考研的我听着每一句都是泪”,到4月13日他又评论了一句“我考上了”,中间没有任何别的回复,但多了4个赞。我看到这莫名地就释然了,点了个赞,继续写作业去了,很奇妙的感受,我叫它感同身受!\n20周年那一版因为版权无法生成外链,只有下面这个版本了,不过也很不错!</p>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=22690729&auto=1&height=66\"></iframe>\n\n<p>風の無い夜の公園で 動かないブランコ達は<br>\n在无风的夜晚公园里 不会摇晃的秋千们<br>\n与此刻的自己 有着可怕的相似<br>\n恐い位似てるんだよ 今の僕自身に<br>\n欲しい物は山ほどある<br>\n想要的东西如山般高<br>\n但手中却什么也没有<br>\nだけど欠片(かけら)も手にできず<br>\n無くしてきた 色んな夢を探してる<br>\n只是搜寻着 那些消逝的梦想<br>\n弱さは人の運命(さだめ)だと<br>\n命运两字是人生的无奈<br>\nなんとなく気付いてるけど<br>\n似乎我也注意到了<br>\n「支えられたい、支えてみたい」忙しく思うよ<br>\n却不停的想着「能撑得,在撑撑看」<br>\n強がる事に不器用で<br>\n就算是徒费力气<br>\n空回りしてもいいから<br>\n硬撑也无所谓<br>\n我只是想不断追寻 那变化多端的未来<br>\n追い続けたい 色んな形の未来を<br>\n觉得容易的事情却意外地<br>\n容易(たやす)く思える事が意外に結構<br>\n无法简单得手<br>\n手に入れるのが難しく思える<br>\n这难道不是跟盯着自己的脚步<br>\nそれってもしかして自分の足元を<br>\n見つめてみればきっと転がってんじゃない<br>\n就会摔跤是一样的道理吗<br>\n激しい雨が降った後にはきれいな花が咲く<br>\n在倾盆大雨过后 娇艳的花儿即将绽放<br>\nあきらめたりしない 届くはずさ想いは<br>\n千万不要放弃 因为梦想即将到达<br>\nそしていっそ昨日までの自分を捨て去ろう<br>\n然后索性忘却到昨天为止的自己吧<br>\n静けさを引き裂くように 空き缶を強く蹴り飛ばす<br>\n仿佛是要将寂静撕裂 狠狠的将罐子踢飞<br>\n胸に秘めた 色んな迷いを詰め込んで<br>\n深藏在内心的 是满满的各种迷茫<br>\n結果だけにしがみついていたよずっと<br>\n一直以来总是只紧抓住结果不放<br>\nプロセスなんか馬鹿らしく思えて<br>\n觉得过程什么的都不重要<br>\n残缺的月 带着勇敢的微笑<br>\n満ち欠ける月のけなげな微笑み<br>\n看吧 太阳一定依旧在你眼前升起<br>\n日はまた昇るきっと目の前にほら<br>\n頬を伝ったどんな涙も大きな価値がある<br>\n脸颊上滑落的 是无价眼泪带来的讯息<br>\n二度とない時を負けないように進むよ<br>\n怀着仅此一次绝不认输的心情前进<br>\n激しい雨が降った後にはきれいな花が咲く<br>\n在大雨倾盆过后 娇艳的花儿即将绽放<br>\nあきらめたりしない 届くはずさ願いは<br>\n千万不要放弃 因为梦想即将到达<br>\nそしていっそ昨日までの自分を捨て去ろう<br>\n然后索性忘却到昨天为止的自己吧<br>\n遠くない近くない捉えずらいホントにいつもやっかいもんは自分<br>\n最难琢磨的是那忽远忽近难以搞定的真实的自己<br>\nそれでも向き合って生きていかなきゃダメさ<br>\n但是不好好奋斗下去是不行的<br>\nだから「昨日までの自分を捨て去ろう」って唄おう<br>\n所以 就让我们唱着「忘却到昨天为止的自己吧」<br>\nいつかはどんな部分(こころ)も愛せる気がするよ<br>\n无论何时 无论何地都感受到爱<br>\n何が起こっても構わない荒波に打たれても<br>\n无论发生任何事 就算是再大的风浪<br>\n僕は信じている最終形の自分を<br>\n我始终相信着最真实的自己<br>\nどれ位こうしてたんだろう<br>\n到底这样过了多久<br>\n街は息を吹き返した<br>\n整个街道重新开始呼吸<br>\n不思議なんだ僕の胸に光がともってく<br>\n不可思议的是我的心也渐渐亮了起来<br>\nそよぎはじめていた風が淋しさを全部連れ去り<br>\n徐徐吹起的微风将一切寂寞带走<br>\n踊りだしたブランコ達も笑ってる<br>\n跳起舞来的秋千们也露出笑意<br></p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1463918607786,"created_by":1,"updated_at":1463919901297,"updated_by":1,"published_at":1463919661601,"published_by":1},{"id":7,"uuid":"d4620769-971a-4d03-b3f7-dac29ab33ead","title":"浏览器下载Google Play的apk","slug":"liu-lan-qi-xia-zai-google-playde-apk","markdown":"","html":"","image":null,"featured":0,"page":0,"status":"draft","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1464107300210,"created_by":1,"updated_at":1464163006931,"updated_by":1,"published_at":null,"published_by":null},{"id":8,"uuid":"b8b11fe7-0536-434c-ab84-10bfa539d770","title":"转:Reactjs 的 PropTypes 使用方法","slug":"zhuan-reactjs-de-proptypes-shi-yong-fang-fa","markdown":"### Reactjs 的 PropTypes 使用方法\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=35528482&auto=1&height=66\"></iframe>\n\npropTypes 使用来规范组件Props的类型\n\n```\n var Test = React.createClass({\n propTypes: {\n // required\n requiredFunc: React.PropTypes.func.isRequired,\n requiredAny: React.PropTypes.any.isRequired,\n\n // primitives, optional by default\n bool: React.PropTypes.bool,\n func: React.PropTypes.func,\n number: React.PropTypes.number,\n string: React.PropTypes.string,\n },\n render:function(){\n return <div/>\n }\n});\n\nvar component = React.render(\n <Test requiredFunc=\"bar\" bool=\"true\" requiredAny=\"a\"/>, \n document.body\n);\n```\n\n若没有按照规范,会显示警告。\n\n```\nReact.PropTypes 的种类\nReact.PropTypes.array // 数组\nReact.PropTypes.bool.isRequired // Boolean 且必要。\nReact.PropTypes.func // 函数\nReact.PropTypes.number // 数字\nReact.PropTypes.object // 对象\nReact.PropTypes.string // 字符串\nReact.PropTypes.any // 任何类型的: numbers, strings, elements等\nReact.PropTypes.element // React 元素\nReact.PropTypes.instanceOf(XXX) // 某种XXX类型的实体\nReact.PropTypes.oneOf(['foo', 'bar']) // 其中一个字符串\nReact.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.array]) // 其中一种类型\nReact.PropTypes.arrayOf(React.PropTypes.string) // 某种类型的数组\nReact.PropTypes.objectOf(React.PropTypes.string) // 某种类型的对象\nReact.PropTypes.shape({ // 是否符合指定的格式\n color: React.PropTypes.string,\n fontSize: React.PropTypes.number\n});\nReact.PropTypes.any.isRequired // 可以是任何格式,且必要。\n\n// 自定义格式(当不符合的时候,会显示Error) \n// 不要用`console.warn` 或者 throw, 因为它在`oneOfType` 的情况下无效。\ncustomPropType: function(props, propName, componentName) {\n if (!/^[0-9]/.test(props[propName])) {\n return new Error('Validation failed!');\n }\n}\n```\n\ngetDefaultProps\n\n当父组件没有提供props的属性时,可以采用getDefaultProps,预设props属性的方式,让元件使用预设的值,确保有props带入。\n\n```\n var ComponentWithDefaultProps = React.createClass({ \n getDefaultProps : function () { \n return {\n value : 'default value' \n }; \n }, \n /* ... */ \n});\n```\n\nPosted by James Yang March 19, 2015 ReactJS","html":"<h3 id=\"reactjsproptypes\">Reactjs 的 PropTypes 使用方法</h3>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=35528482&auto=1&height=66\"></iframe>\n\n<p>propTypes 使用来规范组件Props的类型</p>\n\n<pre><code> var Test = React.createClass({\n propTypes: {\n // required\n requiredFunc: React.PropTypes.func.isRequired,\n requiredAny: React.PropTypes.any.isRequired,\n\n // primitives, optional by default\n bool: React.PropTypes.bool,\n func: React.PropTypes.func,\n number: React.PropTypes.number,\n string: React.PropTypes.string,\n },\n render:function(){\n return <div/>\n }\n});\n\nvar component = React.render( \n <Test requiredFunc=\"bar\" bool=\"true\" requiredAny=\"a\"/>, \n document.body\n);\n</code></pre>\n\n<p>若没有按照规范,会显示警告。</p>\n\n<pre><code>React.PropTypes 的种类 \nReact.PropTypes.array // 数组 \nReact.PropTypes.bool.isRequired // Boolean 且必要。 \nReact.PropTypes.func // 函数 \nReact.PropTypes.number // 数字 \nReact.PropTypes.object // 对象 \nReact.PropTypes.string // 字符串 \nReact.PropTypes.any // 任何类型的: numbers, strings, elements等 \nReact.PropTypes.element // React 元素 \nReact.PropTypes.instanceOf(XXX) // 某种XXX类型的实体 \nReact.PropTypes.oneOf(['foo', 'bar']) // 其中一个字符串 \nReact.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.array]) // 其中一种类型 \nReact.PropTypes.arrayOf(React.PropTypes.string) // 某种类型的数组 \nReact.PropTypes.objectOf(React.PropTypes.string) // 某种类型的对象 \nReact.PropTypes.shape({ // 是否符合指定的格式 \n color: React.PropTypes.string,\n fontSize: React.PropTypes.number\n});\nReact.PropTypes.any.isRequired // 可以是任何格式,且必要。\n\n// 自定义格式(当不符合的时候,会显示Error) \n// 不要用`console.warn` 或者 throw, 因为它在`oneOfType` 的情况下无效。\ncustomPropType: function(props, propName, componentName) { \n if (!/^[0-9]/.test(props[propName])) {\n return new Error('Validation failed!');\n }\n}\n</code></pre>\n\n<p>getDefaultProps</p>\n\n<p>当父组件没有提供props的属性时,可以采用getDefaultProps,预设props属性的方式,让元件使用预设的值,确保有props带入。</p>\n\n<pre><code> var ComponentWithDefaultProps = React.createClass({ \n getDefaultProps : function () { \n return {\n value : 'default value' \n }; \n }, \n /* ... */ \n});\n</code></pre>\n\n<p>Posted by James Yang March 19, 2015 ReactJS</p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1464234823225,"created_by":1,"updated_at":1464247927106,"updated_by":1,"published_at":1464247836046,"published_by":1},{"id":9,"uuid":"727848e2-4e25-4943-bb82-5a6f2bba13b5","title":"什么是视差滚动","slug":"shi-yao-shi-shi-chai-gun-dong","markdown":"下午在研究facebook今年f8大会上开源的基于react native的f8app的时候看到一个ParallaxBackground组件,不明觉厉啊!于是查了一下单词Parallax,意思为视差,所以ParallaxBackground其实是一个视差的背景,最后我把目光落到了视差滚动。\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=385757&auto=1&height=66\"></iframe>\n\n视差滚动是近些年国外web design中的一种潮流,它能够提高网页的立体性。它是如何运作的呢!上百度百科。\n> 视差效果,原本是一个天文学术语,当我们观察星空时,离我们远的星星移动速度较慢,离我们近的星星移动速度则较快。当我们坐在车上向车窗外 看时,也会有这样的感觉,远处的群山似乎没有在动,而近处的稻田却在飞速掠过。许多游戏中都使用视差效果来增加场景的立体感。说的简单点就是网页内的元素在滚动屏幕时发生的位置的变化,然而各个不同的元素位置变化的速度不同,导致网页内的元素有层次错落的错觉,这和我们人体的眼球效果很像。我看到多家产品商用视差滚动效果来展示产品,从不同的空间角度和用户体验,起到了非常不错的效果。 目前这种视差滚动效果被越来越多的国外网站所应用, 成为网页设计的热点趋势。 通过一个很长的网页页面,其中利用一些令人惊叹的插图和图形,并使用视差滚动(Parallax Scrolling)效果,让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。完美的展示了一个复杂的过程,让你犹如置身其中。\n\n百度百科看了还是木有很深刻的认识,那看看下面这个例子你一定会说“噢,来是这样”。[点我点我](http://hotdot.pro/#)\n\n在我看来视差滚动其实是通过页面多层次不同速度的滚动来达到一种视觉上的落差,使人感到页面有一种立体感!","html":"<p>下午在研究facebook今年f8大会上开源的基于react native的f8app的时候看到一个ParallaxBackground组件,不明觉厉啊!于是查了一下单词Parallax,意思为视差,所以ParallaxBackground其实是一个视差的背景,最后我把目光落到了视差滚动。</p>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=385757&auto=1&height=66\"></iframe>\n\n<p>视差滚动是近些年国外web design中的一种潮流,它能够提高网页的立体性。它是如何运作的呢!上百度百科。</p>\n\n<blockquote>\n <p>视差效果,原本是一个天文学术语,当我们观察星空时,离我们远的星星移动速度较慢,离我们近的星星移动速度则较快。当我们坐在车上向车窗外 看时,也会有这样的感觉,远处的群山似乎没有在动,而近处的稻田却在飞速掠过。许多游戏中都使用视差效果来增加场景的立体感。说的简单点就是网页内的元素在滚动屏幕时发生的位置的变化,然而各个不同的元素位置变化的速度不同,导致网页内的元素有层次错落的错觉,这和我们人体的眼球效果很像。我看到多家产品商用视差滚动效果来展示产品,从不同的空间角度和用户体验,起到了非常不错的效果。 目前这种视差滚动效果被越来越多的国外网站所应用, 成为网页设计的热点趋势。 通过一个很长的网页页面,其中利用一些令人惊叹的插图和图形,并使用视差滚动(Parallax Scrolling)效果,让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。完美的展示了一个复杂的过程,让你犹如置身其中。</p>\n</blockquote>\n\n<p>百度百科看了还是木有很深刻的认识,那看看下面这个例子你一定会说“噢,来是这样”。<a href=\"http://hotdot.pro/#\">点我点我</a></p>\n\n<p>在我看来视差滚动其实是通过页面多层次不同速度的滚动来达到一种视觉上的落差,使人感到页面有一种立体感!</p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1464244796501,"created_by":1,"updated_at":1464245506730,"updated_by":1,"published_at":1464245322285,"published_by":1},{"id":10,"uuid":"5995d7ae-ad04-4a41-9710-a30426873cf3","title":"一脸懵逼:git大小写不敏感","slug":"gitda-xiao-xie-bu-min-gan","markdown":"用了这么久git,今天第一次遇到文件大小写不区分的问题,因为node找依赖模块时区分大小写,项目就跑不起来了!!!\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=188647&auto=1&height=66\"></iframe>\n\n只能找办法解决:首先修改git的配置,使其大小写敏感\n```\ngit config core.ignorecase false\n```\n其次需要删除本地文件重新add和commit\n```\ngit rm -f filename\n\ngit add filename\n\ngit commit -m \"message\"\n```","html":"<p>用了这么久git,今天第一次遇到文件大小写不区分的问题,因为node找依赖模块时区分大小写,项目就跑不起来了!!!</p>\n\n<iframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=330 height=86 src=\"http://music.163.com/outchain/player?type=2&id=188647&auto=1&height=66\"></iframe>\n\n<p>只能找办法解决:首先修改git的配置,使其大小写敏感</p>\n\n<pre><code>git config core.ignorecase false \n</code></pre>\n\n<p>其次需要删除本地文件重新add和commit</p>\n\n<pre><code>git rm -f filename\n\ngit add filename\n\ngit commit -m \"message\" \n</code></pre>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1464334877736,"created_by":1,"updated_at":1464336310938,"updated_by":1,"published_at":1464335179180,"published_by":1},{"id":11,"uuid":"203b9723-2d0c-4d53-8634-98ad9d8087f4","title":"一口老血:ESLint配置文档翻译","slug":"pei-zhi-eslint-2","markdown":"## 配置ESLint\nESLint 被设计为完全可配置的,这意味着你可以关闭任意规则,仅仅运行基础的句法检查,或混合和匹配捆绑的规则和你习惯的规则来最适合你的项目。这有两种主要的方式来配置 ESLint 。\n\n1. 配置注释 - 直接把配置信息通过 JavaScript 注释的方式写入文件\n2. 配置文件 - 使用一个 JavaScript ,JSON or YAML 文件来具体说明整个文件夹和所有它的子文件夹的配置信息。它可以在一个 `.eslintrc.*` 文件或在 `package.json` 文件的 `eslintConfig` 字段,ESLint 将会自动寻找并读取它们,或者你可以通过命令行具体制定配置文件。\n\n有以下几块信息是可以被配置的:\n\n* Environments - 你的脚本被设计运行在什么环境。每个环境将会带有一组预定义的全局变量。\n* Globals - 你的脚本执行期间所需的额外的全局变量。\n* Rules - 将打开的规则,以及它的错误级别。\n\nESLint 所有这些选项使你你有了对你的代码细力度的控制力。\n\n## 制定解析器选项\nESLint 允许你去指定你想要支持的 JavaScript 语言选项。默认,ESLint 支持 ES5 的句法。你可以通过覆盖解析器选项的设置去启用 ES6 和 ES7 甚至JSX的支持。\n\n请注意支持 JSX 句法不等同于支持 React 。React 应用了 ESLint 无法识别的更具体的语法。如果你在使用 React 并想要支持 React 语法,我们推荐你使用 `eslint-plugin-react` 。\n\n解析器选项在你的 `.eslintrc.*` 文件的 `parserOptions` 属性中被指定。这个可用的选项如下:\n\n* ecmaVersion - 设置你想要使用的 ECMAScript 的具体版本,可以为3、5(默认)、6或者7。\n* sourceType - 设置 **\"script\"** (默认),如果你的代码 ECMAScript 模块当中则使用 **\"module\"** 。\n* ecmaFeatures - 一个指示你所想要使用的语言特性的对象:\n * globalReturn - 允许 return 表达式在全局作用域当中\n * impliedStrict - 开启严格模式(如果 ecmaVersion 大于等于5)\n * jsx - 启用 JSX\n * experimentalObjectRestSpread -启用对于实验性的对象剩余/展开参数的支持。(重要:这是一个实验特性,将来可能会出现显著的变化。建议你不要写依赖于这一功能的规则,除非你已经愿意去维护其改变时所引起的问题。)\n\n这有一个例子 `.eslintrc.json` 文件:\n\n```\n{\n \"parserOptions\": {\n \"ecmaVersion\": 6,\n \"sourceType\": \"module\",\n \"ecmaFeatures\": {\n \"jsx\": true\n }\n },\n \"rules\": {\n \"semi\": 2\n }\n}\n```\n\n设置解析器选项帮助 ESLint 决定什么是一个解析错误。所有语言选项默认是 false 。\n\n## 指定解析器\nESLint 默认使用 `Espree` 作为它的解析器。你可以在你的配置文件当中可选的指定一个不同的解析器,只要它满足以下的要求:\n\n1. 它必须是一个本地安装的npm模块。\n2. 它必须有一个 Esprima 兼容接口(它必须导出一个 `parse()` 方法)。\n3. 它必须产出 Esprima 兼容的抽象语法树和表意的对象。\n\n注意甚至有了这些兼容性,我们不保证一个外部的解析器将和 ESLint 正确地工作,ESLint将不会解决这些由其他解析器不兼容造成的问题。\n\n你需要使用 `.eslintrc` 文件中的 `parser` 选项来指定一个npm模块作为你的解析器。例如,下面指定使用 Esprima 来代替 Espree :\n\n```\n{\n \"parser\": \"esprima\",\n \"rules\": {\n \"semi\": \"error\"\n }\n}\n```\n\n下列解析器是兼容 ESLint 的:\n* Esprima\n* Babel-ESLint - 一个 Babel 解析器的包装,使其兼容 ESLint 。\n\n注意当你使用一个习惯的解析器时, `parserOptions` 配置属性仍然是 ESLint 在非默认的ES5环境工作所必须的。解析器通过了所有的 `parserOptions` ,可以也可以不使用它们去决定启用的特性。\n\n## 指定环境\n一个环境预定义了全局变量。可用的环境如下:\n\n* browser - 浏览器全局变量。\n* node - Node.js 全局变量和 Node.js 作用域。\n* commonjs - CommonJS 全局变量和 CommonJS 作用域(只有在使用 Browserify或WebPack产生的浏览器代码中使用)。\n* shared-node-browser - Node and Browser公共的全局变量。\n* es6 - 启用所有的 ES6 module 所需要的特性。\n* worker - web workers 全局变量.\n* amd - defines require() and define() as global variables as per the amd spec.\n* mocha - 加入 Mocha 测试的所有全局变量。\n* jasmine - 加入 Jasmine 测试的所有全局变量,针对1.3和2.0版本。\n* jest - Jest 全局变量。\n* phantomjs - PhantomJS 全局变量。\n* protractor - Protractor 全局变量。\n* qunit - QUnit 全局变量。\n* jquery - jQuery 全局变量。\n* prototypejs - Prototype.js 全局变量。\n* shelljs - ShellJS 全局变量。\n* meteor - Meteor 全局变量。\n* mongo - MongoDB 全局变量。\n* applescript - AppleScript 全局变量。\n* nashorn - Java 8 Nashorn 引擎全局变量。\n* serviceworker - Service Worker 全局变量。\n* atomtest - Atom 测试 helper 变量。\n* embertest - Ember 测试 helper 变量。\n* webextensions - WebExtensions 变量。\n* greasemonkey - GreaseMonkey 变量。\n\n这些环境不相互影响,所以你可以同时定义超过一个环境。\n\nEnvironments 能够在文件当中,在配置文件中或使用命令行的 `--env` 参数指定。\n\n在你的 JavaScript 中使用注释指定环境,使用下面的格式:\n\n```\n/*eslint-env node, mocha */\n```\n\n他启用了 Node.js 和 Mocha 的环境。\n\n在配置文件当中指定环境,使用 `env` 键并把你需要启用的环境的属性设为 `true` 。例如,下面例子启用了 brower 和 Node.js 环境:\n\n```\n{\n \"env\": {\n \"browser\": true,\n \"node\": true\n }\n}\n```\n\n或者在 `package.json` 文件\n\n```\n{\n \"name\": \"mypackage\",\n \"version\": \"0.0.1\",\n \"eslintConfig\": {\n \"env\": {\n \"browser\": true,\n \"node\": true\n }\n }\n}\n```\n\n在 YAML 文件中:\n\n```\n---\n env:\n browser: true\n node: true\n```\n\n如果你想去使用一个来自插件的环境,确保指定了插件名在 `plugins` 数组,然后使用不带前缀的插件名,其次是斜杠,再其次是环境名。举例来说:\n\n```\n{\n \"plugins\": [\"example\"],\n \"env\": {\n \"example/custom\": true\n }\n}\n```\n\n在一个 `package.json` 文件中\n\n```\n{\n \"name\": \"mypackage\",\n \"version\": \"0.0.1\",\n \"eslintConfig\": {\n \"plugins\": [\"example\"],\n \"env\": {\n \"example/custom\": true\n }\n }\n}\n```\n\nYAML 文件:\n\n```\n---\n plugins:\n - example\n env:\n example/custom: true\n```\n\n## 指定全局变量\nno-undef 规则将会警告将要访问的为定义的变量。如果你使用全局变量在一个文件中,它将是值得的去定义 globals 以至于 ESLint 将不会警告它们的使用。你可以定义全局变量使用文件中的注释或者配置文件。\n\n在你的 JavaScript 文件中指定全局变量,使用下面的格式:\n\n```\n/* global var1, var2 */\n```\n\n定义两个全局变量, `var1` 和 `var2` 。如果你想要去可选的制定这些全局变量不应当被修改(只读),你可以设置每个全局变量一个 false 标记:\n\n```\n/* global var1:false, var2:false */\n```\n\n在配置文件中配置全局变量,使用 `globals` 键并指出你想要使用的全局变量。设置全局变量为 `true` 来使其可以被覆盖或制定 `false` 使其只读。举例:\n\n```\n{\n \"globals\": {\n \"var1\": true,\n \"var2\": false\n }\n}\n```\n\nYAML中:\n\n```\n---\n globals:\n var1: true\n var2: false\n```\n\n这个例子允许 `var1` 可以在代码中覆盖,但 `var2` 不允许。\n\n## 配置插件\nESLint 支持使用第三方的插件。在使用插件前,需要用 npm 将它安装。\n\n在配置文件中配置插件,使用 `plugins` 键,它包含一个插件名的列表。 `eslint-plugin-` 的前缀可以从插件名中省略。\n\n```\n{\n \"plugins\": [\n \"plugin1\",\n \"eslint-plugin-plugin2\"\n ]\n}\n```\n\nYAML中:\n```\n---\n plugins:\n - plugin1\n - eslint-plugin-plugin2\n```\n\n注意:一个全局安装的 ESLint 只能改使用全局安装的 ESLint 插件。本地安装的 ESLint 能够使用本地和全局的 ESLint 插件。\n\n## 配置规则\nESlint 自带了大量的规则。你能够通过注释和配置文件的方式修改你项目中的规则。修改一个规则的设置,你必须设置 rule ID 为下列中的一个值:\n\n* `\"off\"` 或 `0` - 关闭规则\n* `\"warn\"` 或 `1` - 打开规则起提醒作用(不退出代码执行)\n* `\"error\"` 或 `2` - 打开规则起报错作用(将触发退出代码)\n\n在文件中使用注释配置,使用下面的格式:\n\n```\n/* eslint eqeqeq: \"off\", curly: \"error\" */\n```\n\n在这个例子中 `eqeqeq` 被关闭, `curly` 被打开 error 级别。你也可以使用等价的数字表示规则的级别:\n\n```\n/* eslint eqeqeq: 0, curly: 2 */\n```\n\n这个例子和上一个例子相同,只是它使用数字编号代替了字符串值。`eqeqeq` 被关闭, `curly` 被打开 error 级别。\n\n如果一个规则有可选的选项,你可以使用数组字面量设置它们,例如:\n\n```\n/* eslint quotes: [\"error\", \"double\"], curly: 2 */\n```\n\n这个注释为 `quotes` 规则指定了两个选项。数组的第一项总是严重的规则(数字或字符串)。\n\n在配置文件配置规则,使用 `rules` 键跟着一个 error 级别和任何选项你想要使用的。例如:\n\n```\n{\n \"rules\": {\n \"eqeqeq\": \"off\",\n \"curly\": \"error\",\n \"quotes\": [\"error\", \"double\"]\n }\n}\n```\n\nYAML 文件中:\n\n```\n---\nrules:\n eqeqeq: off\n curly: error\n quotes:\n - error\n - double\n```\n\n配置一个在插件中定义的规则,你必须为 rule ID 加上插件名作为前缀,以及 `/`。举例来说:\n\n```\n{\n \"plugins\": [\n \"plugin1\"\n ],\n \"rules\": {\n \"eqeqeq\": \"off\",\n \"curly\": \"error\",\n \"quotes\": [\"error\", \"double\"],\n \"plugin1/rule1\": \"error\"\n }\n}\n```\n\nYAML 文件中:\n\n```\n---\nplugins:\n - plugin1\nrules:\n eqeqeq: 0\n curly: error\n quotes:\n - error\n - \"double\"\n plugin1/rule1: error\n```\n\n在这个配置文件中,规则 `plugin1/rule1` 来自插件 `plugin1` 。你也能够使用如下格式配置注释的方式,例如:\n\n```\n/* eslint \"plugin1/rule1\": \"error\" */\n```\n\n注意:当指定来自插件的规则,确保省略 `eslint-plugin-` 。ESLint 只使用无前缀的名字来定位内部规则。\n\n## 使用行内注释来禁用规则\n使用如下的格式来临时地禁用文件中规则的警告:\n\n```\n/* eslint-disable */\n\n// Disables all rules between comments\nalert('foo');\n\n/* eslint-enable */\n```\n\n你也可以禁用或启用指定的规则:\n\n```\n/* eslint-disable no-alert, no-console */\n\n// Disables no-alert and no-console warnings between comments\nalert('foo');\nconsole.log('bar');\n\n/* eslint-enable no-alert, no-console */\n```\n\n在整个文件中禁用规则警告,把 `/* eslint-disable */` 放到文件顶部:\n\n```\n/* eslint-disable */\n\n// Disables all rules for the rest of the file\nalert('foo');\n```\n\n你也可以在整个文件禁用指定的规则:\n\n```\n/* eslint-disable no-alert */\n\n// Disables no-alert for the rest of the file\nalert('foo');\n```\n\n在指定行禁用所有规则:\n\n```\nalert('foo'); // eslint-disable-line\n\n// eslint-disable-next-line\nalert('foo');\n```\n\n在指定行禁用指定的规则:\n\n```\nalert('foo'); // eslint-disable-line no-alert\n\n// eslint-disable-next-line no-alert\nalert('foo');\n```\n\n指定行禁用多个规则:\n\n```\nalert('foo'); // eslint-disable-line no-alert, quotes, semi\n\n// eslint-disable-next-line no-alert, quotes, semi\nalert('foo');\n```\n\n注意:注释仅仅是禁用了一部分警告,告诉 ESlint 不要报告这部分代码违规。 ESlint 解析整个文件,所以禁用的代码仍然需要符合合法的 JavaScript 语法。\n\n## 添加共享的设置\nESlint 支持向配置文件中添加共享的配置。你能够添加 `settings` 对象到 ESLint 配置文件中,它将会提供给每一个将要执行的规则。这也许是有用的如果你添加了习惯的规则并想要它们能够访问相同的信息并轻松配置。\n\n在 JSON 中:\n\n```\n{\n \"settings\": {\n \"sharedData\": \"Hello\"\n }\n}\n```\n\n在 YAML 文件中:\n\n```\n---\n settings:\n sharedData: \"Hello\"\n```\n\n## 使用配置文件\n这有两种方式去使用配置文件。第一种是保存文件到你喜欢的地方,然后传递它的地址到 CLI 使用 `-c` 选项,例如:\n\n```\neslint -c myconfig.json myfiletotest.js\n```\n\n第二种方式是去使用配置文件通过 `.eslintrc.*` 或 `package.json` 文件。ESLint 将会自动在目录中寻找它们,从连续的父目录一路找到文件系统根目录。这个选项时有用的当你想要对项目的不同部分使用不同的配置,或者当你想要别的直接去使用 ESLint 而不需要记住它在配置文件中传递。\n\n两种方式,配置文件的设置都将会覆盖默认的配置。\n\n## 配置文件格式\nESLint 支持各种格式的配置文件:\n\n* **JavaScript** - 使用 `.eslintrc.js` 并导出一个包含你配置信息的对象。\n* **YAML** - 使用 `.eslintrc.yaml` 或 `.eslintrc.yml` 来定义配置结构。\n* **JSON** - 使用 `.eslintrc.json` 来定义配置结构。 ESLint's JSON 文件也支持 JavaScript 风格的注释。\n* **Deprecated** - 使用 `eslintrc`,过时的,可以是 JSON 或 YAML。\n* **package.json** - 创建一个 `eslintConfig` 属性在你的 `package.json`文件并在这里定义你的配置。\n\n如果有多种配置文件在同一个目录,ESLint将会使用一个。它们的优先级如下:\n\n1. `.eslintrc.js`\n2. `.eslintrc.yaml`\n3. `.eslintrc.yml`\n4. `.eslintrc.json`\n5. `.eslintrc`\n6. `package.json`\n\n## 配置及联和层次结构\n当使用 `.eslintrc.*` 和 `package.json` 文件来配置,你可以利用配置级联的优势。举例来说,假设你有下列的目录结构:\n\n```\nyour-project\n├── .eslintrc\n├── lib\n│ └── source.js\n└─┬ tests\n ├── .eslintrc\n └── test.js\n```\n\n配置级联将会使用最近的 `.eslintrc` 文件作为最高优先级,然后是任何父级目录的配置文件等。当你在项目中运行 ESLint ,所有 `lib/` 目录下的文件将会使用根目录下的 `.eslintrc` 文件作为它们的配置。如果 ESLint 进入 `test/` 目录,它将会使用 `your-project/tests/.eslintrc` 而不是 `your-project/.eslintrc` 。所以 `your-project/tests/test.js` 的检测是基于目录层次结构中的两个 `.eslintrc` 文件的组合的,近的拥有更高的优先级。这样的方式,你可以拥有项目级别的 ESLint 设置,并可以用目录层次的配置来覆盖它。\n\n相同的方式,在 `package.json` 文件中也可行。根目录中 `package.json` 的 `eslintConfig` 字段将在其所有子目录生效,但是在 tests 目录的 `.eslintrc` 文件将会覆盖所有冲突的配置。\n\n```\nyour-project\n├── package.json\n├── lib\n│ └── source.js\n└─┬ tests\n ├── .eslintrc\n └── test.js\n```\n\n如果在一个目录中,同时找到了 `.eslintrc` 和 `package.json` 文件,`eslintrc` 文件将有更高的优先级, `package.json` 文件将不被使用。\n\n注意:如果你又一个个人的配置文件在你的用户目录( `~/.eslintrc` ),它将会仅仅在没有别的配置文件没发现的情况下使用。它将会对你所有用户目录下的文件生效,包括第三方的代码,因此在运行 ESLint 很可能会产生问题。\n\n默认地, ESLint 将会在所有父目录直到根目录寻找配置文件。这将是有用的,如果你想要所有你的项目去跟随某个约定,但是有时候会导致意想不到的结果。限制 ESLint 在一个指定的项目,把 `\"root\": true` 加到 `package.json` 的 `eslintConfig` 字段或者 `.eslintrc.*` 文件,在你的根目录。 ESLint 将会停止寻找父目录当它找到了 `\"root\": true` 的配置。\n\n```\n{\n \"root\": true\n}\n```\nYAML 文件中:\n\n```\n---\n root: true\n```\n\n举例来说, 这个例子当中 `main.js` 将会使用 `lib/` 中的配置,而不会使用 `productA` 目录下的 `.eslintrc` 文件的配置,因为在 `lib/` 中的 `.eslintrc` 有 `\"root\": true` 的设置。\n\n```\nhome\n└── user\n ├── .eslintrc <- Always skipped if other configs present\n └── projectA\n ├── .eslintrc <- Not used\n └── lib\n ├── .eslintrc <- { \"root\": true }\n └── main.js\n```\n\n完整的配置层次,从高到低如下:\n\n1. 行内配置\n 1. `/*eslint-disable*/` and `/*eslint-enable*/`\n 2. `/*global*/`\n 3. `/*eslint*/`\n 4. `/*eslint-env*/`\n2. 命令行配置\n 1. `--global`\n 2. `--rule`\n 3. `--env`\n 4. `-c, --config`\n3. 项目级别配置\n 1. `.eslintrc.*` 或 `package.json` 文件\n 2. 祖先目录中寻找,除非有 `\"root\": true` 将不会向上寻找\n 3. 个人某人的配置在 `~/.eslintrc`\n\n## 扩展配置文件\n如果你想要扩展一个指定的配置文件,你可以使用 `extends` 属性,并制定路径。可以是相对的或是绝对的路径。\n\n配置能够被如下文件扩展:\n\n1. YAML 文件\n2. JSON 文件\n3. JS 文件\n4. 共享的配置包\n\n扩展配置提供了基础的规则,并可以覆盖。举例:\n\n```\n{\n \"extends\": \"./node_modules/coding-standard/.eslintrc\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": 1\n }\n}\n```\n\n配置也许也可以以数组的方式提供,后面的会覆盖前面的相同的规则的配置。举例:\n\n```\n{\n \"extends\": [\n \"./node_modules/coding-standard/eslintDefaults.js\",\n // Override eslintDefaults.js\n \"./node_modules/coding-standard/.eslintrc-es6\",\n // Override .eslintrc-es6\n \"./node_modules/coding-standard/.eslintrc-jsx\",\n ],\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n```\n\n扩展配置能够包涵它们自己的 `extends` ,导致循环的引用。\n\n你也可以使用共享的配置包。你需要使用 npm 去安装它们,例如:\n\n```\n{\n \"extends\": \"eslint-config-myrules\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n```\n\n在这个例子, `eslint-config-myrules` 包将会加载为一个对象并作为这个配置的父配置。\n\n注意:你可以省略 `eslint-config-` 前缀, ESLint 将会自动为你添加,和插件工作相似。\n\nESlint 也支持插件提供的扩展配置:\n\n```\n{\n \"extends\": \"plugin:eslint-plugin-myplugin/myConfig\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n```\n\n在这个例子, `eslint-plugin-myplugin` 包包含了名为 `default` 的配置。\n\n**十分重要**:使用插件中的配置时,必须要加上 `plugin:` 前缀来指明哈。但你可以可选地省略 `eslint-plugin` 前缀。\n\n注意:对于根目录或者其它父目录, `extends` 处理路径会用当前工作目录,而不是文件自身。\n\n## 配置文件中的注释\nJSON 和 YAML 配置文件都支持注释, `package.json` 不能包括注释。你可以使用 JAVAScript 风格的注释或 YAML 风格的注释, ESLint 将安全地忽略它们。这可以允许你的配置文件跟友好。举例:\n\n```\n{\n \"env\": {\n \"browser\": true\n },\n \"rules\": {\n // Override our default settings just for this directory\n \"eqeqeq\": \"warn\",\n \"strict\": \"off\"\n }\n}\n```\n\n## 指定需要检测的文件后缀\n当前指定后缀需要在命令行选项 `--ext` 后,添加用空格分开的后缀名列表。\n\n## 忽略文件或目录\n\n\n你可以告诉 ESLint 去忽略指定的文件或目录,通过一个 `.eslintignore` 文件在你的根目录。 `.eslintignore` 文件是一个普通文本文件,每一行定义了要被忽略的文件或目录。举例:下列表达式将会省略所有 JavaScript 文件:\n\n```\n**/*.js\n```\n\n当 ESLint 运行的时候,它会寻找当前工作目录的 `.eslintignore` 文件在它决定监测之前。如果找到了文件,这里面的配置将会生效。 `.eslintignore` 只会被使用一次,因此目录中其他的 `.eslintignore` 将不会被使用。\n\n* #好开头将会被认为是注释\n* 相对于 `.eslintignore` 文件路径或当前工作目录的路径\n* 忽略规则参照 `.gitignore` 规范\n* !用来取消前面的忽略的匹配\n\n`/node_modules/*` 和 `/bower_components/*` 将默认被忽略。\n\n举例,把下面的 `.eslintignore` 文件放倒工作目录下将会忽略`/node_modules/*` 和 `/bower_components/*` 目录,任何扩展名为 `.ts.js` 或 `.coffee.js` 可能被转换,任何在 `build/*` 目录除了 `build/index.js` 将被忽略:\n\n```\n# /node_modules/* and /bower_components/* ignored by default\n\n# Ignore built files except build/index.js\nbuild/*\n!build/index.js\n```\n\n## 使用替换的文件\n如果你喜欢去使用别的文件而不是 `.eslintignore` 来工作,你在命令行中可以指定 `--ignore-path` 选项。举例来说,你可以使用 `.jshintignore` ,因为两者的配置相同:\n\n```\neslint --ignore-path .jshintignore file.js\n```\n\n你也可以使用 `.gitignore` 文件:\n\n```\neslint --ignore-path .gitignore file.js\n```\n\n任何标准的 ignore 文件可以被使用。\n\n## 忽略文件警告\n当你 eslint 一个被忽略的文件或目录时,会发出警告,你可以使用 `--no-ignore` 来进行省略。\n","html":"<h2 id=\"eslint\">配置ESLint</h2>\n\n<p>ESLint 被设计为完全可配置的,这意味着你可以关闭任意规则,仅仅运行基础的句法检查,或混合和匹配捆绑的规则和你习惯的规则来最适合你的项目。这有两种主要的方式来配置 ESLint 。</p>\n\n<ol>\n<li>配置注释 - 直接把配置信息通过 JavaScript 注释的方式写入文件 </li>\n<li>配置文件 - 使用一个 JavaScript ,JSON or YAML 文件来具体说明整个文件夹和所有它的子文件夹的配置信息。它可以在一个 <code>.eslintrc.*</code> 文件或在 <code>package.json</code> 文件的 <code>eslintConfig</code> 字段,ESLint 将会自动寻找并读取它们,或者你可以通过命令行具体制定配置文件。</li>\n</ol>\n\n<p>有以下几块信息是可以被配置的:</p>\n\n<ul>\n<li>Environments - 你的脚本被设计运行在什么环境。每个环境将会带有一组预定义的全局变量。</li>\n<li>Globals - 你的脚本执行期间所需的额外的全局变量。</li>\n<li>Rules - 将打开的规则,以及它的错误级别。</li>\n</ul>\n\n<p>ESLint 所有这些选项使你你有了对你的代码细力度的控制力。</p>\n\n<h2 id=\"\">制定解析器选项</h2>\n\n<p>ESLint 允许你去指定你想要支持的 JavaScript 语言选项。默认,ESLint 支持 ES5 的句法。你可以通过覆盖解析器选项的设置去启用 ES6 和 ES7 甚至JSX的支持。</p>\n\n<p>请注意支持 JSX 句法不等同于支持 React 。React 应用了 ESLint 无法识别的更具体的语法。如果你在使用 React 并想要支持 React 语法,我们推荐你使用 <code>eslint-plugin-react</code> 。</p>\n\n<p>解析器选项在你的 <code>.eslintrc.*</code> 文件的 <code>parserOptions</code> 属性中被指定。这个可用的选项如下:</p>\n\n<ul>\n<li>ecmaVersion - 设置你想要使用的 ECMAScript 的具体版本,可以为3、5(默认)、6或者7。</li>\n<li>sourceType - 设置 <strong>\"script\"</strong> (默认),如果你的代码 ECMAScript 模块当中则使用 <strong>\"module\"</strong> 。</li>\n<li>ecmaFeatures - 一个指示你所想要使用的语言特性的对象:\n<ul><li>globalReturn - 允许 return 表达式在全局作用域当中</li>\n<li>impliedStrict - 开启严格模式(如果 ecmaVersion 大于等于5)</li>\n<li>jsx - 启用 JSX</li>\n<li>experimentalObjectRestSpread -启用对于实验性的对象剩余/展开参数的支持。(重要:这是一个实验特性,将来可能会出现显著的变化。建议你不要写依赖于这一功能的规则,除非你已经愿意去维护其改变时所引起的问题。)</li></ul></li>\n</ul>\n\n<p>这有一个例子 <code>.eslintrc.json</code> 文件:</p>\n\n<pre><code>{\n \"parserOptions\": {\n \"ecmaVersion\": 6,\n \"sourceType\": \"module\",\n \"ecmaFeatures\": {\n \"jsx\": true\n }\n },\n \"rules\": {\n \"semi\": 2\n }\n}\n</code></pre>\n\n<p>设置解析器选项帮助 ESLint 决定什么是一个解析错误。所有语言选项默认是 false 。</p>\n\n<h2 id=\"\">指定解析器</h2>\n\n<p>ESLint 默认使用 <code>Espree</code> 作为它的解析器。你可以在你的配置文件当中可选的指定一个不同的解析器,只要它满足以下的要求:</p>\n\n<ol>\n<li>它必须是一个本地安装的npm模块。 </li>\n<li>它必须有一个 Esprima 兼容接口(它必须导出一个 <code>parse()</code> 方法)。 </li>\n<li>它必须产出 Esprima 兼容的抽象语法树和表意的对象。</li>\n</ol>\n\n<p>注意甚至有了这些兼容性,我们不保证一个外部的解析器将和 ESLint 正确地工作,ESLint将不会解决这些由其他解析器不兼容造成的问题。</p>\n\n<p>你需要使用 <code>.eslintrc</code> 文件中的 <code>parser</code> 选项来指定一个npm模块作为你的解析器。例如,下面指定使用 Esprima 来代替 Espree :</p>\n\n<pre><code>{\n \"parser\": \"esprima\",\n \"rules\": {\n \"semi\": \"error\"\n }\n}\n</code></pre>\n\n<p>下列解析器是兼容 ESLint 的:\n* Esprima\n* Babel-ESLint - 一个 Babel 解析器的包装,使其兼容 ESLint 。</p>\n\n<p>注意当你使用一个习惯的解析器时, <code>parserOptions</code> 配置属性仍然是 ESLint 在非默认的ES5环境工作所必须的。解析器通过了所有的 <code>parserOptions</code> ,可以也可以不使用它们去决定启用的特性。</p>\n\n<h2 id=\"\">指定环境</h2>\n\n<p>一个环境预定义了全局变量。可用的环境如下:</p>\n\n<ul>\n<li>browser - 浏览器全局变量。</li>\n<li>node - Node.js 全局变量和 Node.js 作用域。</li>\n<li>commonjs - CommonJS 全局变量和 CommonJS 作用域(只有在使用 Browserify或WebPack产生的浏览器代码中使用)。</li>\n<li>shared-node-browser - Node and Browser公共的全局变量。</li>\n<li>es6 - 启用所有的 ES6 module 所需要的特性。</li>\n<li>worker - web workers 全局变量.</li>\n<li>amd - defines require() and define() as global variables as per the amd spec.</li>\n<li>mocha - 加入 Mocha 测试的所有全局变量。</li>\n<li>jasmine - 加入 Jasmine 测试的所有全局变量,针对1.3和2.0版本。</li>\n<li>jest - Jest 全局变量。</li>\n<li>phantomjs - PhantomJS 全局变量。</li>\n<li>protractor - Protractor 全局变量。</li>\n<li>qunit - QUnit 全局变量。</li>\n<li>jquery - jQuery 全局变量。</li>\n<li>prototypejs - Prototype.js 全局变量。</li>\n<li>shelljs - ShellJS 全局变量。</li>\n<li>meteor - Meteor 全局变量。</li>\n<li>mongo - MongoDB 全局变量。</li>\n<li>applescript - AppleScript 全局变量。</li>\n<li>nashorn - Java 8 Nashorn 引擎全局变量。</li>\n<li>serviceworker - Service Worker 全局变量。</li>\n<li>atomtest - Atom 测试 helper 变量。</li>\n<li>embertest - Ember 测试 helper 变量。</li>\n<li>webextensions - WebExtensions 变量。</li>\n<li>greasemonkey - GreaseMonkey 变量。</li>\n</ul>\n\n<p>这些环境不相互影响,所以你可以同时定义超过一个环境。</p>\n\n<p>Environments 能够在文件当中,在配置文件中或使用命令行的 <code>--env</code> 参数指定。</p>\n\n<p>在你的 JavaScript 中使用注释指定环境,使用下面的格式:</p>\n\n<pre><code>/*eslint-env node, mocha */\n</code></pre>\n\n<p>他启用了 Node.js 和 Mocha 的环境。</p>\n\n<p>在配置文件当中指定环境,使用 <code>env</code> 键并把你需要启用的环境的属性设为 <code>true</code> 。例如,下面例子启用了 brower 和 Node.js 环境:</p>\n\n<pre><code>{\n \"env\": {\n \"browser\": true,\n \"node\": true\n }\n}\n</code></pre>\n\n<p>或者在 <code>package.json</code> 文件</p>\n\n<pre><code>{\n \"name\": \"mypackage\",\n \"version\": \"0.0.1\",\n \"eslintConfig\": {\n \"env\": {\n \"browser\": true,\n \"node\": true\n }\n }\n}\n</code></pre>\n\n<p>在 YAML 文件中:</p>\n\n<pre><code>---\n env:\n browser: true\n node: true\n</code></pre>\n\n<p>如果你想去使用一个来自插件的环境,确保指定了插件名在 <code>plugins</code> 数组,然后使用不带前缀的插件名,其次是斜杠,再其次是环境名。举例来说:</p>\n\n<pre><code>{\n \"plugins\": [\"example\"],\n \"env\": {\n \"example/custom\": true\n }\n}\n</code></pre>\n\n<p>在一个 <code>package.json</code> 文件中</p>\n\n<pre><code>{\n \"name\": \"mypackage\",\n \"version\": \"0.0.1\",\n \"eslintConfig\": {\n \"plugins\": [\"example\"],\n \"env\": {\n \"example/custom\": true\n }\n }\n}\n</code></pre>\n\n<p>YAML 文件:</p>\n\n<pre><code>---\n plugins:\n - example\n env:\n example/custom: true\n</code></pre>\n\n<h2 id=\"\">指定全局变量</h2>\n\n<p>no-undef 规则将会警告将要访问的为定义的变量。如果你使用全局变量在一个文件中,它将是值得的去定义 globals 以至于 ESLint 将不会警告它们的使用。你可以定义全局变量使用文件中的注释或者配置文件。</p>\n\n<p>在你的 JavaScript 文件中指定全局变量,使用下面的格式:</p>\n\n<pre><code>/* global var1, var2 */\n</code></pre>\n\n<p>定义两个全局变量, <code>var1</code> 和 <code>var2</code> 。如果你想要去可选的制定这些全局变量不应当被修改(只读),你可以设置每个全局变量一个 false 标记:</p>\n\n<pre><code>/* global var1:false, var2:false */\n</code></pre>\n\n<p>在配置文件中配置全局变量,使用 <code>globals</code> 键并指出你想要使用的全局变量。设置全局变量为 <code>true</code> 来使其可以被覆盖或制定 <code>false</code> 使其只读。举例:</p>\n\n<pre><code>{\n \"globals\": {\n \"var1\": true,\n \"var2\": false\n }\n}\n</code></pre>\n\n<p>YAML中:</p>\n\n<pre><code>---\n globals:\n var1: true\n var2: false\n</code></pre>\n\n<p>这个例子允许 <code>var1</code> 可以在代码中覆盖,但 <code>var2</code> 不允许。</p>\n\n<h2 id=\"\">配置插件</h2>\n\n<p>ESLint 支持使用第三方的插件。在使用插件前,需要用 npm 将它安装。</p>\n\n<p>在配置文件中配置插件,使用 <code>plugins</code> 键,它包含一个插件名的列表。 <code>eslint-plugin-</code> 的前缀可以从插件名中省略。</p>\n\n<pre><code>{\n \"plugins\": [\n \"plugin1\",\n \"eslint-plugin-plugin2\"\n ]\n}\n</code></pre>\n\n<p>YAML中: </p>\n\n<pre><code>---\n plugins:\n - plugin1\n - eslint-plugin-plugin2\n</code></pre>\n\n<p>注意:一个全局安装的 ESLint 只能改使用全局安装的 ESLint 插件。本地安装的 ESLint 能够使用本地和全局的 ESLint 插件。</p>\n\n<h2 id=\"\">配置规则</h2>\n\n<p>ESlint 自带了大量的规则。你能够通过注释和配置文件的方式修改你项目中的规则。修改一个规则的设置,你必须设置 rule ID 为下列中的一个值:</p>\n\n<ul>\n<li><code>\"off\"</code> 或 <code>0</code> - 关闭规则</li>\n<li><code>\"warn\"</code> 或 <code>1</code> - 打开规则起提醒作用(不退出代码执行)</li>\n<li><code>\"error\"</code> 或 <code>2</code> - 打开规则起报错作用(将触发退出代码)</li>\n</ul>\n\n<p>在文件中使用注释配置,使用下面的格式:</p>\n\n<pre><code>/* eslint eqeqeq: \"off\", curly: \"error\" */\n</code></pre>\n\n<p>在这个例子中 <code>eqeqeq</code> 被关闭, <code>curly</code> 被打开 error 级别。你也可以使用等价的数字表示规则的级别:</p>\n\n<pre><code>/* eslint eqeqeq: 0, curly: 2 */\n</code></pre>\n\n<p>这个例子和上一个例子相同,只是它使用数字编号代替了字符串值。<code>eqeqeq</code> 被关闭, <code>curly</code> 被打开 error 级别。</p>\n\n<p>如果一个规则有可选的选项,你可以使用数组字面量设置它们,例如:</p>\n\n<pre><code>/* eslint quotes: [\"error\", \"double\"], curly: 2 */\n</code></pre>\n\n<p>这个注释为 <code>quotes</code> 规则指定了两个选项。数组的第一项总是严重的规则(数字或字符串)。</p>\n\n<p>在配置文件配置规则,使用 <code>rules</code> 键跟着一个 error 级别和任何选项你想要使用的。例如:</p>\n\n<pre><code>{\n \"rules\": {\n \"eqeqeq\": \"off\",\n \"curly\": \"error\",\n \"quotes\": [\"error\", \"double\"]\n }\n}\n</code></pre>\n\n<p>YAML 文件中:</p>\n\n<pre><code>---\nrules: \n eqeqeq: off\n curly: error\n quotes:\n - error\n - double\n</code></pre>\n\n<p>配置一个在插件中定义的规则,你必须为 rule ID 加上插件名作为前缀,以及 <code>/</code>。举例来说:</p>\n\n<pre><code>{\n \"plugins\": [\n \"plugin1\"\n ],\n \"rules\": {\n \"eqeqeq\": \"off\",\n \"curly\": \"error\",\n \"quotes\": [\"error\", \"double\"],\n \"plugin1/rule1\": \"error\"\n }\n}\n</code></pre>\n\n<p>YAML 文件中:</p>\n\n<pre><code>---\nplugins: \n - plugin1\nrules: \n eqeqeq: 0\n curly: error\n quotes:\n - error\n - \"double\"\n plugin1/rule1: error\n</code></pre>\n\n<p>在这个配置文件中,规则 <code>plugin1/rule1</code> 来自插件 <code>plugin1</code> 。你也能够使用如下格式配置注释的方式,例如:</p>\n\n<pre><code>/* eslint \"plugin1/rule1\": \"error\" */\n</code></pre>\n\n<p>注意:当指定来自插件的规则,确保省略 <code>eslint-plugin-</code> 。ESLint 只使用无前缀的名字来定位内部规则。</p>\n\n<h2 id=\"\">使用行内注释来禁用规则</h2>\n\n<p>使用如下的格式来临时地禁用文件中规则的警告:</p>\n\n<pre><code>/* eslint-disable */\n\n// Disables all rules between comments\nalert('foo');\n\n/* eslint-enable */\n</code></pre>\n\n<p>你也可以禁用或启用指定的规则:</p>\n\n<pre><code>/* eslint-disable no-alert, no-console */\n\n// Disables no-alert and no-console warnings between comments\nalert('foo'); \nconsole.log('bar');\n\n/* eslint-enable no-alert, no-console */\n</code></pre>\n\n<p>在整个文件中禁用规则警告,把 <code>/* eslint-disable */</code> 放到文件顶部:</p>\n\n<pre><code>/* eslint-disable */\n\n// Disables all rules for the rest of the file\nalert('foo'); \n</code></pre>\n\n<p>你也可以在整个文件禁用指定的规则:</p>\n\n<pre><code>/* eslint-disable no-alert */\n\n// Disables no-alert for the rest of the file\nalert('foo'); \n</code></pre>\n\n<p>在指定行禁用所有规则:</p>\n\n<pre><code>alert('foo'); // eslint-disable-line\n\n// eslint-disable-next-line\nalert('foo'); \n</code></pre>\n\n<p>在指定行禁用指定的规则:</p>\n\n<pre><code>alert('foo'); // eslint-disable-line no-alert\n\n// eslint-disable-next-line no-alert\nalert('foo'); \n</code></pre>\n\n<p>指定行禁用多个规则:</p>\n\n<pre><code>alert('foo'); // eslint-disable-line no-alert, quotes, semi\n\n// eslint-disable-next-line no-alert, quotes, semi\nalert('foo'); \n</code></pre>\n\n<p>注意:注释仅仅是禁用了一部分警告,告诉 ESlint 不要报告这部分代码违规。 ESlint 解析整个文件,所以禁用的代码仍然需要符合合法的 JavaScript 语法。</p>\n\n<h2 id=\"\">添加共享的设置</h2>\n\n<p>ESlint 支持向配置文件中添加共享的配置。你能够添加 <code>settings</code> 对象到 ESLint 配置文件中,它将会提供给每一个将要执行的规则。这也许是有用的如果你添加了习惯的规则并想要它们能够访问相同的信息并轻松配置。</p>\n\n<p>在 JSON 中:</p>\n\n<pre><code>{\n \"settings\": {\n \"sharedData\": \"Hello\"\n }\n}\n</code></pre>\n\n<p>在 YAML 文件中:</p>\n\n<pre><code>---\n settings:\n sharedData: \"Hello\"\n</code></pre>\n\n<h2 id=\"\">使用配置文件</h2>\n\n<p>这有两种方式去使用配置文件。第一种是保存文件到你喜欢的地方,然后传递它的地址到 CLI 使用 <code>-c</code> 选项,例如:</p>\n\n<pre><code>eslint -c myconfig.json myfiletotest.js \n</code></pre>\n\n<p>第二种方式是去使用配置文件通过 <code>.eslintrc.*</code> 或 <code>package.json</code> 文件。ESLint 将会自动在目录中寻找它们,从连续的父目录一路找到文件系统根目录。这个选项时有用的当你想要对项目的不同部分使用不同的配置,或者当你想要别的直接去使用 ESLint 而不需要记住它在配置文件中传递。</p>\n\n<p>两种方式,配置文件的设置都将会覆盖默认的配置。</p>\n\n<h2 id=\"\">配置文件格式</h2>\n\n<p>ESLint 支持各种格式的配置文件:</p>\n\n<ul>\n<li><strong>JavaScript</strong> - 使用 <code>.eslintrc.js</code> 并导出一个包含你配置信息的对象。</li>\n<li><strong>YAML</strong> - 使用 <code>.eslintrc.yaml</code> 或 <code>.eslintrc.yml</code> 来定义配置结构。</li>\n<li><strong>JSON</strong> - 使用 <code>.eslintrc.json</code> 来定义配置结构。 ESLint's JSON 文件也支持 JavaScript 风格的注释。</li>\n<li><strong>Deprecated</strong> - 使用 <code>eslintrc</code>,过时的,可以是 JSON 或 YAML。</li>\n<li><strong>package.json</strong> - 创建一个 <code>eslintConfig</code> 属性在你的 <code>package.json</code>文件并在这里定义你的配置。</li>\n</ul>\n\n<p>如果有多种配置文件在同一个目录,ESLint将会使用一个。它们的优先级如下:</p>\n\n<ol>\n<li><code>.eslintrc.js</code> </li>\n<li><code>.eslintrc.yaml</code> </li>\n<li><code>.eslintrc.yml</code> </li>\n<li><code>.eslintrc.json</code> </li>\n<li><code>.eslintrc</code> </li>\n<li><code>package.json</code></li>\n</ol>\n\n<h2 id=\"\">配置及联和层次结构</h2>\n\n<p>当使用 <code>.eslintrc.*</code> 和 <code>package.json</code> 文件来配置,你可以利用配置级联的优势。举例来说,假设你有下列的目录结构:</p>\n\n<pre><code>your-project \n├── .eslintrc\n├── lib\n│ └── source.js\n└─┬ tests\n ├── .eslintrc\n └── test.js\n</code></pre>\n\n<p>配置级联将会使用最近的 <code>.eslintrc</code> 文件作为最高优先级,然后是任何父级目录的配置文件等。当你在项目中运行 ESLint ,所有 <code>lib/</code> 目录下的文件将会使用根目录下的 <code>.eslintrc</code> 文件作为它们的配置。如果 ESLint 进入 <code>test/</code> 目录,它将会使用 <code>your-project/tests/.eslintrc</code> 而不是 <code>your-project/.eslintrc</code> 。所以 <code>your-project/tests/test.js</code> 的检测是基于目录层次结构中的两个 <code>.eslintrc</code> 文件的组合的,近的拥有更高的优先级。这样的方式,你可以拥有项目级别的 ESLint 设置,并可以用目录层次的配置来覆盖它。</p>\n\n<p>相同的方式,在 <code>package.json</code> 文件中也可行。根目录中 <code>package.json</code> 的 <code>eslintConfig</code> 字段将在其所有子目录生效,但是在 tests 目录的 <code>.eslintrc</code> 文件将会覆盖所有冲突的配置。</p>\n\n<pre><code>your-project \n├── package.json\n├── lib\n│ └── source.js\n└─┬ tests\n ├── .eslintrc\n └── test.js\n</code></pre>\n\n<p>如果在一个目录中,同时找到了 <code>.eslintrc</code> 和 <code>package.json</code> 文件,<code>eslintrc</code> 文件将有更高的优先级, <code>package.json</code> 文件将不被使用。</p>\n\n<p>注意:如果你又一个个人的配置文件在你的用户目录( <code>~/.eslintrc</code> ),它将会仅仅在没有别的配置文件没发现的情况下使用。它将会对你所有用户目录下的文件生效,包括第三方的代码,因此在运行 ESLint 很可能会产生问题。</p>\n\n<p>默认地, ESLint 将会在所有父目录直到根目录寻找配置文件。这将是有用的,如果你想要所有你的项目去跟随某个约定,但是有时候会导致意想不到的结果。限制 ESLint 在一个指定的项目,把 <code>\"root\": true</code> 加到 <code>package.json</code> 的 <code>eslintConfig</code> 字段或者 <code>.eslintrc.*</code> 文件,在你的根目录。 ESLint 将会停止寻找父目录当它找到了 <code>\"root\": true</code> 的配置。</p>\n\n<pre><code>{\n \"root\": true\n}\n</code></pre>\n\n<p>YAML 文件中:</p>\n\n<pre><code>---\n root: true\n</code></pre>\n\n<p>举例来说, 这个例子当中 <code>main.js</code> 将会使用 <code>lib/</code> 中的配置,而不会使用 <code>productA</code> 目录下的 <code>.eslintrc</code> 文件的配置,因为在 <code>lib/</code> 中的 <code>.eslintrc</code> 有 <code>\"root\": true</code> 的设置。</p>\n\n<pre><code>home \n└── user\n ├── .eslintrc <- Always skipped if other configs present\n └── projectA\n ├── .eslintrc <- Not used\n └── lib\n ├── .eslintrc <- { \"root\": true }\n └── main.js\n</code></pre>\n\n<p>完整的配置层次,从高到低如下:</p>\n\n<ol>\n<li>行内配置 <br />\n<ol><li><code>/*eslint-disable*/</code> and <code>/*eslint-enable*/</code></li>\n<li><code>/*global*/</code></li>\n<li><code>/*eslint*/</code></li>\n<li><code>/*eslint-env*/</code></li></ol></li>\n<li>命令行配置 <br />\n<ol><li><code>--global</code></li>\n<li><code>--rule</code></li>\n<li><code>--env</code></li>\n<li><code>-c, --config</code></li></ol></li>\n<li>项目级别配置 <br />\n<ol><li><code>.eslintrc.*</code> 或 <code>package.json</code> 文件</li>\n<li>祖先目录中寻找,除非有 <code>\"root\": true</code> 将不会向上寻找</li>\n<li>个人某人的配置在 <code>~/.eslintrc</code></li></ol></li>\n</ol>\n\n<h2 id=\"\">扩展配置文件</h2>\n\n<p>如果你想要扩展一个指定的配置文件,你可以使用 <code>extends</code> 属性,并制定路径。可以是相对的或是绝对的路径。</p>\n\n<p>配置能够被如下文件扩展:</p>\n\n<ol>\n<li>YAML 文件 </li>\n<li>JSON 文件 </li>\n<li>JS 文件 </li>\n<li>共享的配置包</li>\n</ol>\n\n<p>扩展配置提供了基础的规则,并可以覆盖。举例:</p>\n\n<pre><code>{\n \"extends\": \"./node_modules/coding-standard/.eslintrc\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": 1\n }\n}\n</code></pre>\n\n<p>配置也许也可以以数组的方式提供,后面的会覆盖前面的相同的规则的配置。举例:</p>\n\n<pre><code>{\n \"extends\": [\n \"./node_modules/coding-standard/eslintDefaults.js\",\n // Override eslintDefaults.js\n \"./node_modules/coding-standard/.eslintrc-es6\",\n // Override .eslintrc-es6\n \"./node_modules/coding-standard/.eslintrc-jsx\",\n ],\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n</code></pre>\n\n<p>扩展配置能够包涵它们自己的 <code>extends</code> ,导致循环的引用。</p>\n\n<p>你也可以使用共享的配置包。你需要使用 npm 去安装它们,例如:</p>\n\n<pre><code>{\n \"extends\": \"eslint-config-myrules\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n</code></pre>\n\n<p>在这个例子, <code>eslint-config-myrules</code> 包将会加载为一个对象并作为这个配置的父配置。</p>\n\n<p>注意:你可以省略 <code>eslint-config-</code> 前缀, ESLint 将会自动为你添加,和插件工作相似。</p>\n\n<p>ESlint 也支持插件提供的扩展配置:</p>\n\n<pre><code>{\n \"extends\": \"plugin:eslint-plugin-myplugin/myConfig\",\n\n \"rules\": {\n // Override any settings from the \"parent\" configuration\n \"eqeqeq\": \"warn\"\n }\n}\n</code></pre>\n\n<p>在这个例子, <code>eslint-plugin-myplugin</code> 包包含了名为 <code>default</code> 的配置。</p>\n\n<p><strong>十分重要</strong>:使用插件中的配置时,必须要加上 <code>plugin:</code> 前缀来指明哈。但你可以可选地省略 <code>eslint-plugin</code> 前缀。</p>\n\n<p>注意:对于根目录或者其它父目录, <code>extends</code> 处理路径会用当前工作目录,而不是文件自身。</p>\n\n<h2 id=\"\">配置文件中的注释</h2>\n\n<p>JSON 和 YAML 配置文件都支持注释, <code>package.json</code> 不能包括注释。你可以使用 JAVAScript 风格的注释或 YAML 风格的注释, ESLint 将安全地忽略它们。这可以允许你的配置文件跟友好。举例:</p>\n\n<pre><code>{\n \"env\": {\n \"browser\": true\n },\n \"rules\": {\n // Override our default settings just for this directory\n \"eqeqeq\": \"warn\",\n \"strict\": \"off\"\n }\n}\n</code></pre>\n\n<h2 id=\"\">指定需要检测的文件后缀</h2>\n\n<p>当前指定后缀需要在命令行选项 <code>--ext</code> 后,添加用空格分开的后缀名列表。</p>\n\n<h2 id=\"\">忽略文件或目录</h2>\n\n<p>你可以告诉 ESLint 去忽略指定的文件或目录,通过一个 <code>.eslintignore</code> 文件在你的根目录。 <code>.eslintignore</code> 文件是一个普通文本文件,每一行定义了要被忽略的文件或目录。举例:下列表达式将会省略所有 JavaScript 文件:</p>\n\n<pre><code>**/*.js\n</code></pre>\n\n<p>当 ESLint 运行的时候,它会寻找当前工作目录的 <code>.eslintignore</code> 文件在它决定监测之前。如果找到了文件,这里面的配置将会生效。 <code>.eslintignore</code> 只会被使用一次,因此目录中其他的 <code>.eslintignore</code> 将不会被使用。</p>\n\n<ul>\n<li>#好开头将会被认为是注释</li>\n<li>相对于 <code>.eslintignore</code> 文件路径或当前工作目录的路径</li>\n<li>忽略规则参照 <code>.gitignore</code> 规范</li>\n<li>!用来取消前面的忽略的匹配</li>\n</ul>\n\n<p><code>/node_modules/*</code> 和 <code>/bower_components/*</code> 将默认被忽略。</p>\n\n<p>举例,把下面的 <code>.eslintignore</code> 文件放倒工作目录下将会忽略<code>/node_modules/*</code> 和 <code>/bower_components/*</code> 目录,任何扩展名为 <code>.ts.js</code> 或 <code>.coffee.js</code> 可能被转换,任何在 <code>build/*</code> 目录除了 <code>build/index.js</code> 将被忽略:</p>\n\n<pre><code># /node_modules/* and /bower_components/* ignored by default\n\n# Ignore built files except build/index.js\nbuild/* \n!build/index.js\n</code></pre>\n\n<h2 id=\"\">使用替换的文件</h2>\n\n<p>如果你喜欢去使用别的文件而不是 <code>.eslintignore</code> 来工作,你在命令行中可以指定 <code>--ignore-path</code> 选项。举例来说,你可以使用 <code>.jshintignore</code> ,因为两者的配置相同:</p>\n\n<pre><code>eslint --ignore-path .jshintignore file.js \n</code></pre>\n\n<p>你也可以使用 <code>.gitignore</code> 文件:</p>\n\n<pre><code>eslint --ignore-path .gitignore file.js \n</code></pre>\n\n<p>任何标准的 ignore 文件可以被使用。</p>\n\n<h2 id=\"\">忽略文件警告</h2>\n\n<p>当你 eslint 一个被忽略的文件或目录时,会发出警告,你可以使用 <code>--no-ignore</code> 来进行省略。</p>","image":null,"featured":0,"page":0,"status":"published","language":"en_US","meta_title":null,"meta_description":null,"author_id":1,"created_at":1464345663531,"created_by":1,"updated_at":1464410772091,"updated_by":1,"published_at":1464348992506,"published_by":1}],"users":[{"id":1,"uuid":"f183c222-672a-47e1-80a4-561830ba1d27","name":"m2mbob","slug":"m2mbob","password":"$2a$10$Xcdj.QcZXVRWoWmvgQTC/.QvFXigb4CHjfLM0kE.44gNKy/j0Z6oq","email":"[email protected]","image":"/content/images/2016/05/113.jpeg","cover":null,"bio":null,"website":null,"location":null,"accessibility":null,"status":"active","language":"en_US","meta_title":null,"meta_description":null,"tour":null,"last_login":1464406644494,"created_at":1463567133080,"created_by":1,"updated_at":1464406644494,"updated_by":1},{"id":4,"uuid":"8f6b8eed-af31-427f-aed7-9c82eef40764","name":"laowei38ban","slug":"laowei38ban","password":"$2a$10$grTnZnHCNnkWw2MwVpwGZupmifHYKYXNk3CaLKGnWH7M7WhCCWsyu","email":"[email protected]","image":null,"cover":null,"bio":null,"website":null,"location":null,"accessibility":null,"status":"invited-pending","language":"en_US","meta_title":null,"meta_description":null,"tour":null,"last_login":null,"created_at":1463930876939,"created_by":1,"updated_at":1464594807734,"updated_by":4}],"roles":[{"id":1,"uuid":"a205663c-0051-448b-8d64-c083afc8cd1f","name":"Administrator","description":"Administrators","created_at":1463567128189,"created_by":1,"updated_at":1463567128189,"updated_by":1},{"id":2,"uuid":"f3c3f834-15cf-4992-b37e-9fc241cce9ea","name":"Editor","description":"Editors","created_at":1463567128217,"created_by":1,"updated_at":1463567128217,"updated_by":1},{"id":3,"uuid":"974b0d0e-2a8c-4c45-9932-dbb233bc9cc8","name":"Author","description":"Authors","created_at":1463567128243,"created_by":1,"updated_at":1463567128243,"updated_by":1},{"id":4,"uuid":"e1e437c2-a08b-4152-bb91-130ff9670e31","name":"Owner","description":"Blog Owner","created_at":1463567128271,"created_by":1,"updated_at":1463567128271,"updated_by":1}],"roles_users":[{"id":1,"role_id":4,"user_id":1},{"id":2,"role_id":3,"user_id":2},{"id":3,"role_id":3,"user_id":3},{"id":4,"role_id":3,"user_id":4}],"permissions":[{"id":1,"uuid":"17ffb52c-5e47-4520-bb3a-923eee539fae","name":"Export database","object_type":"db","action_type":"exportContent","object_id":null,"created_at":1463567128298,"created_by":1,"updated_at":1463567128298,"updated_by":1},{"id":2,"uuid":"0b603a34-66db-4290-9f1c-17411a32d5af","name":"Import database","object_type":"db","action_type":"importContent","object_id":null,"created_at":1463567128326,"created_by":1,"updated_at":1463567128326,"updated_by":1},{"id":3,"uuid":"63d14f73-132e-4504-9f3c-a5496e529604","name":"Delete all content","object_type":"db","action_type":"deleteAllContent","object_id":null,"created_at":1463567128351,"created_by":1,"updated_at":1463567128351,"updated_by":1},{"id":4,"uuid":"4b3cd8a9-e96e-45f1-8746-ba36e61d837b","name":"Send mail","object_type":"mail","action_type":"send","object_id":null,"created_at":1463567128379,"created_by":1,"updated_at":1463567128379,"updated_by":1},{"id":5,"uuid":"b3a9c3fe-26ef-4f19-895a-bb6b09cfa07a","name":"Browse notifications","object_type":"notification","action_type":"browse","object_id":null,"created_at":1463567128407,"created_by":1,"updated_at":1463567128407,"updated_by":1},{"id":6,"uuid":"7d1c64de-07c8-49e8-87cf-eef785bd3500","name":"Add notifications","object_type":"notification","action_type":"add","object_id":null,"created_at":1463567128431,"created_by":1,"updated_at":1463567128431,"updated_by":1},{"id":7,"uuid":"d490cd6d-e086-4e27-86f0-4a4638f020b0","name":"Delete notifications","object_type":"notification","action_type":"destroy","object_id":null,"created_at":1463567128456,"created_by":1,"updated_at":1463567128456,"updated_by":1},{"id":8,"uuid":"e00cf85a-7d10-4908-9952-164dbb7e76d5","name":"Browse posts","object_type":"post","action_type":"browse","object_id":null,"created_at":1463567128480,"created_by":1,"updated_at":1463567128480,"updated_by":1},{"id":9,"uuid":"388edf22-9724-4936-840b-4972018c83f5","name":"Read posts","object_type":"post","action_type":"read","object_id":null,"created_at":1463567128506,"created_by":1,"updated_at":1463567128506,"updated_by":1},{"id":10,"uuid":"8cafbddb-afdb-4ce8-82be-17dd7dab9b39","name":"Edit posts","object_type":"post","action_type":"edit","object_id":null,"created_at":1463567128534,"created_by":1,"updated_at":1463567128534,"updated_by":1},{"id":11,"uuid":"2f54798f-05bc-45b4-a477-0cae3a8c15fb","name":"Add posts","object_type":"post","action_type":"add","object_id":null,"created_at":1463567128556,"created_by":1,"updated_at":1463567128556,"updated_by":1},{"id":12,"uuid":"b85480a8-ff4d-4ed1-baad-595ea2452fca","name":"Delete posts","object_type":"post","action_type":"destroy","object_id":null,"created_at":1463567128578,"created_by":1,"updated_at":1463567128578,"updated_by":1},{"id":13,"uuid":"4760b85c-cc79-4ee4-87c1-643bc500136e","name":"Browse settings","object_type":"setting","action_type":"browse","object_id":null,"created_at":1463567128602,"created_by":1,"updated_at":1463567128602,"updated_by":1},{"id":14,"uuid":"b60aa8d7-8605-4c2e-84bb-35fd98b9e05b","name":"Read settings","object_type":"setting","action_type":"read","object_id":null,"created_at":1463567128631,"created_by":1,"updated_at":1463567128631,"updated_by":1},{"id":15,"uuid":"a7437212-afe7-4df4-9370-9e4cb8507d64","name":"Edit settings","object_type":"setting","action_type":"edit","object_id":null,"created_at":1463567128655,"created_by":1,"updated_at":1463567128655,"updated_by":1},{"id":16,"uuid":"c334e5b6-c398-4b0b-ad00-9b3c747aa564","name":"Generate slugs","object_type":"slug","action_type":"generate","object_id":null,"created_at":1463567128688,"created_by":1,"updated_at":1463567128688,"updated_by":1},{"id":17,"uuid":"3338699f-c4e5-41b8-9ca4-4d22be830633","name":"Browse tags","object_type":"tag","action_type":"browse","object_id":null,"created_at":1463567128719,"created_by":1,"updated_at":1463567128719,"updated_by":1},{"id":18,"uuid":"b58d136d-763d-4cfc-bcc3-ab32fdc2d4d1","name":"Read tags","object_type":"tag","action_type":"read","object_id":null,"created_at":1463567128746,"created_by":1,"updated_at":1463567128746,"updated_by":1},{"id":19,"uuid":"76384049-8ad7-4233-9259-f7b511018001","name":"Edit tags","object_type":"tag","action_type":"edit","object_id":null,"created_at":1463567128770,"created_by":1,"updated_at":1463567128770,"updated_by":1},{"id":20,"uuid":"2c117ad5-76ab-438a-9e2e-2a707d15b2fa","name":"Add tags","object_type":"tag","action_type":"add","object_id":null,"created_at":1463567128795,"created_by":1,"updated_at":1463567128795,"updated_by":1},{"id":21,"uuid":"94bf77cf-2356-47ba-be2b-6e51ff3b4e0b","name":"Delete tags","object_type":"tag","action_type":"destroy","object_id":null,"created_at":1463567128820,"created_by":1,"updated_at":1463567128820,"updated_by":1},{"id":22,"uuid":"6f3064f3-7109-4049-807b-0b5986a00077","name":"Browse themes","object_type":"theme","action_type":"browse","object_id":null,"created_at":1463567128848,"created_by":1,"updated_at":1463567128848,"updated_by":1},{"id":23,"uuid":"589fe891-4edb-4504-bcdd-443950122687","name":"Edit themes","object_type":"theme","action_type":"edit","object_id":null,"created_at":1463567128876,"created_by":1,"updated_at":1463567128876,"updated_by":1},{"id":24,"uuid":"91e1d531-9886-4cf5-ab90-868e851150ee","name":"Browse users","object_type":"user","action_type":"browse","object_id":null,"created_at":1463567128903,"created_by":1,"updated_at":1463567128903,"updated_by":1},{"id":25,"uuid":"f898d0b8-7a24-4da8-9ae0-d2d71082c0fe","name":"Read users","object_type":"user","action_type":"read","object_id":null,"created_at":1463567128926,"created_by":1,"updated_at":1463567128926,"updated_by":1},{"id":26,"uuid":"69769fb8-0707-41d9-a941-108e78458828","name":"Edit users","object_type":"user","action_type":"edit","object_id":null,"created_at":1463567128950,"created_by":1,"updated_at":1463567128950,"updated_by":1},{"id":27,"uuid":"f077887e-a6bb-4d7e-a5a2-669f2c709db7","name":"Add users","object_type":"user","action_type":"add","object_id":null,"created_at":1463567128976,"created_by":1,"updated_at":1463567128976,"updated_by":1},{"id":28,"uuid":"1a13365e-a47e-4355-92fd-5ca74fa7259e","name":"Delete users","object_type":"user","action_type":"destroy","object_id":null,"created_at":1463567129004,"created_by":1,"updated_at":1463567129004,"updated_by":1},{"id":29,"uuid":"d331b27f-cd04-43f2-8e13-4cc90a9fe017","name":"Assign a role","object_type":"role","action_type":"assign","object_id":null,"created_at":1463567129036,"created_by":1,"updated_at":1463567129036,"updated_by":1},{"id":30,"uuid":"d6a8f870-d4aa-4565-bbb9-08274700fcd7","name":"Browse roles","object_type":"role","action_type":"browse","object_id":null,"created_at":1463567129059,"created_by":1,"updated_at":1463567129059,"updated_by":1}],"permissions_users":[],"permissions_roles":[{"id":1,"role_id":1,"permission_id":1},{"id":2,"role_id":1,"permission_id":2},{"id":3,"role_id":1,"permission_id":3},{"id":4,"role_id":1,"permission_id":4},{"id":5,"role_id":1,"permission_id":5},{"id":6,"role_id":1,"permission_id":6},{"id":7,"role_id":1,"permission_id":7},{"id":8,"role_id":1,"permission_id":8},{"id":9,"role_id":1,"permission_id":9},{"id":10,"role_id":1,"permission_id":10},{"id":11,"role_id":1,"permission_id":11},{"id":12,"role_id":1,"permission_id":12},{"id":13,"role_id":1,"permission_id":13},{"id":14,"role_id":1,"permission_id":14},{"id":15,"role_id":1,"permission_id":15},{"id":16,"role_id":1,"permission_id":16},{"id":17,"role_id":1,"permission_id":17},{"id":18,"role_id":1,"permission_id":18},{"id":19,"role_id":1,"permission_id":19},{"id":20,"role_id":1,"permission_id":20},{"id":21,"role_id":1,"permission_id":21},{"id":22,"role_id":1,"permission_id":22},{"id":23,"role_id":1,"permission_id":23},{"id":24,"role_id":1,"permission_id":24},{"id":25,"role_id":1,"permission_id":25},{"id":26,"role_id":1,"permission_id":26},{"id":27,"role_id":1,"permission_id":27},{"id":28,"role_id":1,"permission_id":28},{"id":29,"role_id":1,"permission_id":29},{"id":30,"role_id":1,"permission_id":30},{"id":31,"role_id":2,"permission_id":8},{"id":32,"role_id":2,"permission_id":9},{"id":33,"role_id":2,"permission_id":10},{"id":34,"role_id":2,"permission_id":11},{"id":35,"role_id":2,"permission_id":12},{"id":36,"role_id":2,"permission_id":13},{"id":37,"role_id":2,"permission_id":14},{"id":38,"role_id":2,"permission_id":16},{"id":39,"role_id":2,"permission_id":17},{"id":40,"role_id":2,"permission_id":18},{"id":41,"role_id":2,"permission_id":19},{"id":42,"role_id":2,"permission_id":20},{"id":43,"role_id":2,"permission_id":21},{"id":44,"role_id":2,"permission_id":24},{"id":45,"role_id":2,"permission_id":25},{"id":46,"role_id":2,"permission_id":26},{"id":47,"role_id":2,"permission_id":27},{"id":48,"role_id":2,"permission_id":28},{"id":49,"role_id":2,"permission_id":29},{"id":50,"role_id":2,"permission_id":30},{"id":51,"role_id":3,"permission_id":8},{"id":52,"role_id":3,"permission_id":9},{"id":53,"role_id":3,"permission_id":11},{"id":54,"role_id":3,"permission_id":13},{"id":55,"role_id":3,"permission_id":14},{"id":56,"role_id":3,"permission_id":16},{"id":57,"role_id":3,"permission_id":17},{"id":58,"role_id":3,"permission_id":18},{"id":59,"role_id":3,"permission_id":20},{"id":60,"role_id":3,"permission_id":24},{"id":61,"role_id":3,"permission_id":25},{"id":62,"role_id":3,"permission_id":30}],"permissions_apps":[],"settings":[{"id":1,"uuid":"07767b0a-31a8-4f7c-9089-0cac6be45867","key":"databaseVersion","value":"004","type":"core","created_at":1463567133162,"created_by":1,"updated_at":1463567133162,"updated_by":1},{"id":2,"uuid":"64a07b8e-9ca6-4464-940a-985f4241f6e7","key":"dbHash","value":"e00711f4-02e7-4f60-a9c5-b870666a2a83","type":"core","created_at":1463567133162,"created_by":1,"updated_at":1463567133836,"updated_by":1},{"id":3,"uuid":"d57d0b4c-9dbf-4810-a010-651b42825bf5","key":"nextUpdateCheck","value":"1464679769","type":"core","created_at":1463567133163,"created_by":1,"updated_at":1464593367149,"updated_by":1},{"id":4,"uuid":"b43fd992-cc8f-4f1e-bc47-c060dfdcae3f","key":"displayUpdateNotification","value":"0.7.0","type":"core","created_at":1463567133163,"created_by":1,"updated_at":1464593367155,"updated_by":1},{"id":5,"uuid":"0b0d23f5-c9f3-4a41-9c47-ba9170f1cec5","key":"title","value":"m2mbob","type":"blog","created_at":1463567133163,"created_by":1,"updated_at":1463918461986,"updated_by":1},{"id":6,"uuid":"e53b4cef-36a8-4208-9605-9dd6062e7407","key":"description","value":"Thoughts, stories and ideas.","type":"blog","created_at":1463567133163,"created_by":1,"updated_at":1463918461991,"updated_by":1},{"id":7,"uuid":"adccbe11-7283-472b-b363-b517530d874c","key":"logo","value":"","type":"blog","created_at":1463567133163,"created_by":1,"updated_at":1463918461993,"updated_by":1},{"id":8,"uuid":"9ef9dbff-161f-45db-921e-4857f9d617b3","key":"cover","value":"","type":"blog","created_at":1463567133164,"created_by":1,"updated_at":1463918461994,"updated_by":1},{"id":9,"uuid":"c205e750-b7b4-4a65-be94-e33aa231e523","key":"defaultLang","value":"en_US","type":"blog","created_at":1463567133164,"created_by":1,"updated_at":1463918461996,"updated_by":1},{"id":10,"uuid":"d7917f90-456e-42d0-a6fe-429f84898f0b","key":"postsPerPage","value":"5","type":"blog","created_at":1463567133164,"created_by":1,"updated_at":1463918461998,"updated_by":1},{"id":11,"uuid":"66503e4a-acf0-4aca-8dbc-0e36ae39bcdd","key":"forceI18n","value":"true","type":"blog","created_at":1463567133165,"created_by":1,"updated_at":1463918461999,"updated_by":1},{"id":12,"uuid":"8755c9a1-7e8c-42c6-a665-df37701f6072","key":"permalinks","value":"/:slug/","type":"blog","created_at":1463567133165,"created_by":1,"updated_at":1463918462001,"updated_by":1},{"id":13,"uuid":"1b0a112b-d8b5-47b6-8b13-56c323eaa83e","key":"ghost_head","value":"","type":"blog","created_at":1463567133165,"created_by":1,"updated_at":1463918462035,"updated_by":1},{"id":14,"uuid":"9675e29f-a962-49a0-ad3a-f15533d0f7dc","key":"ghost_foot","value":"","type":"blog","created_at":1463567133165,"created_by":1,"updated_at":1463918462037,"updated_by":1},{"id":15,"uuid":"6d4ab5d5-75d4-4b1e-b5ec-6435f411cb3a","key":"labs","value":"{}","type":"blog","created_at":1463567133165,"created_by":1,"updated_at":1463918462039,"updated_by":1},{"id":16,"uuid":"a10d0aed-69e5-4de0-899c-8ad0fbc6c955","key":"navigation","value":"[{\"label\":\"Home\",\"url\":\"http://m2mbob.cn:1314/\"}]","type":"blog","created_at":1463567133166,"created_by":1,"updated_at":1463918462041,"updated_by":1},{"id":17,"uuid":"821e540b-22d6-49b5-acb5-bc963b77100f","key":"activeApps","value":"[]","type":"app","created_at":1463567133166,"created_by":1,"updated_at":1463567133166,"updated_by":1},{"id":18,"uuid":"2a154f41-dcc1-4035-bbe9-886d2f715d8e","key":"installedApps","value":"[]","type":"app","created_at":1463567133167,"created_by":1,"updated_at":1464594667722,"updated_by":1},{"id":19,"uuid":"96f6c4a2-30d4-4490-968d-449261420d65","key":"isPrivate","value":"false","type":"private","created_at":1463567133167,"created_by":1,"updated_at":1463918462043,"updated_by":1},{"id":20,"uuid":"90857a68-2fe1-4798-9654-88a635a54ddb","key":"password","value":"null","type":"private","created_at":1463567133167,"created_by":1,"updated_at":1463918462044,"updated_by":1},{"id":21,"uuid":"fcd59843-2747-411c-8ab4-7e97a1c9c3b4","key":"activeTheme","value":"casper","type":"theme","created_at":1463567133166,"created_by":1,"updated_at":1463918462033,"updated_by":1}],"tags":[{"id":1,"uuid":"ecb77cf1-1be2-443a-b555-f1c1fa8992fb","name":"get-started","slug":"get-started","description":"get-started","image":"","hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463567128109,"created_by":1,"updated_at":1463754330921,"updated_by":1},{"id":2,"uuid":"f73b4d4f-12cc-498c-a159-be13b472fec7","name":"redux源码分析系列","slug":"redux","description":"","image":"/content/images/2016/05/687474703a2f2f692e696d6775722e636f6d2f4a65567164514d2e706e67-1.png","hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463754046804,"created_by":1,"updated_at":1463817817169,"updated_by":1},{"id":3,"uuid":"2ce8db62-0a14-47c4-b1b8-1e3b920c420a","name":"life","slug":"life","description":"关于生活","image":"/content/images/2016/05/u-1687420627-4175839764-fm-21-gp-0.jpg","hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463817797112,"created_by":1,"updated_at":1463817887321,"updated_by":1},{"id":4,"uuid":"495550a6-a385-4ff4-8e4f-afb9870f94fa","name":"乱七八糟","slug":"digression","description":"杂谈","image":"/content/images/2016/05/u-1468361829-4039309630-fm-116-gp-0.jpg","hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463834283409,"created_by":1,"updated_at":1463834926309,"updated_by":1},{"id":5,"uuid":"4723a273-0582-4a37-842d-c771a73f85f8","name":"mongodb","slug":"mongodb","description":"","image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463838088406,"created_by":1,"updated_at":1463838094311,"updated_by":1},{"id":6,"uuid":"31ada047-4501-406d-917f-488e23b03f36","name":"mac","slug":"mac","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463838131596,"created_by":1,"updated_at":1463838131596,"updated_by":1},{"id":7,"uuid":"91b7d980-5ce6-4340-aaf1-9a6b5dc80667","name":"koa","slug":"koa","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463838270749,"created_by":1,"updated_at":1463838270749,"updated_by":1},{"id":8,"uuid":"be14e3b0-fb8f-4924-81b5-0924b220508c","name":"nodejs","slug":"nodejs","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1463838276529,"created_by":1,"updated_at":1463838283586,"updated_by":1},{"id":9,"uuid":"c332f075-6919-4dd1-9b6e-cdd1b93e86db","name":"react","slug":"react","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1464247836082,"created_by":1,"updated_at":1464247836082,"updated_by":1},{"id":10,"uuid":"5d8a3fba-d4a7-4e50-856f-2b3034b30d5d","name":"git","slug":"git","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1464335179221,"created_by":1,"updated_at":1464335179221,"updated_by":1},{"id":11,"uuid":"3dc60c76-7ce0-44e2-93eb-da3879afc085","name":"eslint","slug":"eslint","description":null,"image":null,"hidden":0,"parent_id":null,"meta_title":null,"meta_description":null,"created_at":1464346513640,"created_by":1,"updated_at":1464346513640,"updated_by":1}],"posts_tags":[{"id":1,"post_id":1,"tag_id":1,"sort_order":0},{"id":2,"post_id":2,"tag_id":2,"sort_order":0},{"id":3,"post_id":3,"tag_id":4,"sort_order":0},{"id":4,"post_id":3,"tag_id":6,"sort_order":1},{"id":5,"post_id":4,"tag_id":5,"sort_order":0},{"id":6,"post_id":4,"tag_id":6,"sort_order":1},{"id":7,"post_id":5,"tag_id":7,"sort_order":0},{"id":8,"post_id":5,"tag_id":8,"sort_order":1},{"id":9,"post_id":6,"tag_id":4,"sort_order":0},{"id":10,"post_id":9,"tag_id":4,"sort_order":0},{"id":11,"post_id":8,"tag_id":9,"sort_order":0},{"id":12,"post_id":10,"tag_id":10,"sort_order":0},{"id":13,"post_id":11,"tag_id":11,"sort_order":0}],"apps":[],"app_settings":[],"app_fields":[],"client_trusted_domains":[]}}]}