<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Nodejs on kamuszhou&#39;s blog</title>
    <link>https://ykyi.net/tags/nodejs/</link>
    <description>Recent content in Nodejs on kamuszhou&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Mon, 20 Dec 2021 05:18:33 +0000</lastBuildDate>
    <atom:link href="https://ykyi.net/tags/nodejs/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>adonisjs5的Ioc机制初探</title>
      <link>https://ykyi.net/?p=1733/</link>
      <pubDate>Mon, 20 Dec 2021 05:18:33 +0000</pubDate>
      <guid>https://ykyi.net/?p=1733/</guid>
      <description>&lt;h2 id=&#34;什么是ioc&#34;&gt;什么是Ioc&lt;/h2&gt;
&lt;p&gt;Ioc(Inversion of Control)是一种设计模式.它指的是使用某对象/资源的代码,不负责该对象的依赖对象的创建和维护,而交给一个专门的容器来负责.这样,怎么创建对象的控制权就转移到了这个专门的容器,即实现了所谓的控制反转.Ioc用来降低对象之间由依赖关系产生的耦合.（按照软件工程理论,依赖算是最弱的一种耦合了.依赖 &amp;lt; 关联 &amp;lt; 聚合 &amp;lt; 组合&amp;lt; 继承）我感觉,Ioc算是一个升级版的工厂模式,它管理了大量的工厂函数和对应的资源名称.可以把创建资源/对象的依赖写在Ioc里面.&lt;/p&gt;
&lt;h2 id=&#34;adonisjs5中的ioc&#34;&gt;adonisjs5中的Ioc&lt;/h2&gt;
&lt;p&gt;我感觉有点奇怪,adonisjs5的官方文档中没有专门提及Ioc. &lt;a href=&#34;https://docs.adonisjs.com/guides/introduction&#34;&gt;https://docs.adonisjs.com/guides/introduction&lt;/a&gt;{.wp-editor-md-post-content-link} 但在adonisjs4.x &lt;a href=&#34;https://legacy.adonisjs.com/docs/4.1/ioc-container&#34;&gt;https://legacy.adonisjs.com/docs/4.1/ioc-container&lt;/a&gt;{.wp-editor-md-post-content-link} 的官方文档中却有单独的一节来讲Ioc.以至于,我第一次读完adonis5的文档后,对Ioc竟然没什么印象.而Ioc却是adonis最为重要的概念.anyway~,看看adonis的源代码怎么处理Ioc吧.&lt;/p&gt;
&lt;h3 id=&#34;注册ioc&#34;&gt;注册Ioc&lt;/h3&gt;
&lt;p&gt;在adonisjs的代码中搜索一下,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;find node_modules/@adonisjs -iname &#34;*ioc*&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;很容易发现adonisjs实现Ioc的代码在node_modules/@adonisjs/fold/build/src/Ioc/这个目录中.目录名就是Ioc,毫不掩饰自己的目的.&lt;br&gt;
逛一逛Ioc这个目录下的js文件,发现最重要的是index.js 和 binBindings.js这两个文件.其中index.js中有一个类就叫Ioc, 而注册到Ioc中的资源被放在Bindings.js文件中Bindings类中.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-javascript &#34;&gt;    /**
     * Define a binding
     */
    register(binding, callback, singleton) {
        this.list.set(binding, { callback, singleton });
        return this;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Binding类中的register函数非常显眼.显然注册一个资源到Ioc的代码会走到这里.在这里下断点,调起调试器.发现register函数的三个参数的含义是： binding即资源的的namespace,通过调试器发现注册的第一个资源的namespace是“Adonis/Core/Application”；callback相当于创建这种资源的工厂函数,调用它即生产出一个对应的对象；而singleton则是一个boolean值,指示该种资源是不是一个单件.看看栈的上一个frame,是Ioc类的singleton()函数.看来,“Adonis/Core/Application”这个资源是通过Ioc.singleton()创建的.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-javascript &#34;&gt;    /**
     * Same as the [[bind]] method, but registers a singleton only. Singleton&#39;s callback
     * is invoked only for the first time and then the cached value is used
     */
    singleton(binding, callback) {
        helpers_2.ensureIsFunction(callback, &#39;&#34;ioc.singleton&#34; expect 2nd argument to be a function&#39;);
        this.bindings.register(binding, callback, true);
        return this;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ioc.singleton()函数注释告诉我们.single()函数跟bind()函数一样,只不过是注册一个单件,单件的callback工厂函数仅调用一次.第一次创建会把资源cache起来,而后直接返回cache.这个cache即Bindings类中的list成员.虽然名字是list,但却是一个Map.映射namespace到对象/资源.&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Prettier,Husky和lint-staged，在提交javascript代码前自动格式化代码</title>
      <link>https://ykyi.net/?p=1615/</link>
      <pubDate>Sun, 24 Nov 2019 08:58:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=1615/</guid>
      <description>&lt;h3 id=&#34;目标&#34;&gt;目标&lt;/h3&gt;
&lt;p&gt;为防止提交不合格的代码排版到仓库中，我们希望在提交前格式化代码，使之符合项目的代码格式规范，而且尽可能保证逻辑正确。即目标有两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对git staged的代码强行格式化，使符合规范。对于没有被staged的代码或文件，将完全忽略。&lt;/li&gt;
&lt;li&gt;跑单元测试。只有通过了单元测试才能提交代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;安装依赖&#34;&gt;安装依赖&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ npm install --save-dev husky lint-staged
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先安装husky和lint-staged。注间在安装husky之前需要确保工程目录已经是一个合法的git仓库。因为，安装husky时需要给git仓库安装预提交钩子(precommit hook)。&lt;br&gt;
Lint-staged提供了一个关键的功能，它能找到所有被git staged的文件，而不是工程下面所有的文件，然后通过管道交给Prettier做格式化。&lt;/p&gt;
&lt;h3 id=&#34;修改npm脚本&#34;&gt;修改npm脚本&lt;/h3&gt;
&lt;p&gt;对npm script做如下改动：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;  &#34;scripts&#34;: {
    &#34;precommit&#34;: &#34;lint-staged&#34;
  },
  &#34;lint-staged&#34;: {
    &#34;*.{js,jsx,json}&#34;: [&#34;prettier --write&#34;, &#34;git add&#34;]
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;scripts.precommit由Husky处理，它会依照配置在把代码正式提交到仓库前运行lint-staged(当然我们也可以配置其他命令）。&lt;br&gt;
Lint-staged再找到属于它自己的配置部分，即lint-staged键下面的配置。&lt;br&gt;
在此例中，所有staged状态的，且扩展名是.js, .jsx, 和.json文件都会自动交由Prettier做格式化，然后再提交。&lt;/p&gt;
&lt;h1 id=&#34;为何一定要用lint-staged&#34;&gt;为何一定要用lint-staged&lt;/h1&gt;
&lt;p&gt;You might wonder why we don’t just use Husky to run a few npm scripts.&lt;br&gt;
你可以会疑惑，为什么一定要罗里罗嗦地用lint-staged，用Husky直接调用npm脚本不更简单么。&lt;br&gt;
这是因为我们用lint-staged拿到staged状态的文件，而不是所有的文件。&lt;br&gt;
你的node工程文件中可能已经有如下做代码格式化的脚本&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;&#34;format&#34;: &#34;prettier --write &#39;**/*.{js,jsx}&#39;&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可能会因此如下配置&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;&#34;lint-staged&#34;: {
  &#34;*.{js,jsx,json}&#34;: [&#34;npm run format&#34;, &#34;git add&#34;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是这样配置的话，就没有必要用lint-staged了。因为，这样的配置会把prettier应用到所有匹配.js,.jsx.json的文件上，而不是仅staged状态的文件。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
