如何发布一个package到npm

以下面的一个简单需求为例来发布一个package到npm:访问github地址查看源码

发布一个say-hello-world的package到npm; 这个package的功能是提供一个sayHelloWorld的方法。

注意:因为say-hello-world package已经发布到npm了,所以大家在跟随文档操作的时候需要换个名字。

  • 第一步:
    在项目的根目录下创建一个名字为node_modules的目录,此目录用来放置所有的node模块

  • 第二步:
    在node_modules目录下名字say-hello-world目录;

  • 第三步:
    say-hello-world目录下新建两个文件:

    • index.js

      function sayHelloWorld() {
        console.log("Hello world !");
      }
      module.exports = sayHelloWorld;
      
    • package.json

      {
        "name": "say-hello-world", // package的名称
        "author": "yourname <me@hello.com> (http://hello.com)", // 作者的相关信息
        "version": "0.0.1", // 版本号(semantic version)
        "main": "index" // 入口文件,当在其他文件中require('say-hello-world')时,将会加载index.js
      }
      
    • 发布say-hello-world包到npm
      • 首先要注册一个npm账号(如果没有的话)
      • 注册完后,在命令窗口运行npm adduser(登陆npm),会提示你输入用户名和密码;
      • 登陆成功后,在say-hello-world目录下执行命令npm publish(发布package)
      • 发布成功后就可以登陆到npm官网去看自己发布的package。

到这里,我们已经成功发布了say-hello-world包到npm,接下来我们来尝试使用一下say-hello-world包

  1. 先新建一个空的目录test;然后在命令行中切换到test目录;
  2. 然后执行npm install say-hello-world命令;
  3. 执行成功后在test目录下看到多了一个node_modules的目录,在node_modules目录中就可以看到我们刚才发布的say-hello-worldpackage;
  4. 然后再test目录下新建一个hello-world.js来测试一下sayHelloWorld()方法,hello-world.js中的内容如下:
    var sayHelloWorld = require('say-hello-world');
    sayHelloWorld();
    
  5. 在命令行中进入test目录,然后执行node hello-world.js,就会在看到输出:Hello world !.

如何更新发布到npm的package?(以刚才发布的say-hello-world为例)

当我们对say-hello-world做了改动就需要更新到npm.

  • 进入到say-hello-world目录, 对index.js做一些修改(做为要更新的内容)
  • 然后再命令行执行npm version patch, 此命令会把package.jsonversion更新到0.02
  • 然后执行npm publish就可以更新到npm了

理解进程和线程

  • 进程

    • 进程是一个“执行中的程序”;比如我们在系统中安装QQ和浏览器,也就是说我们安装了两个程序;当我们打开了QQ程序,这时CPU就会开启一个进程来运行QQ程序;当然如果我们又打开了浏览器,CPU又会再开启一个进程来运行浏览器;
    • 一个应用程序就是一个进程
    • CPU没开启一个进程就会给这个进程分配一块内存。
    • 进程之间是相互独立的,内存是不共享的。
  • 线程

    • 通常在一个进程中可以包含若干个线程。比如在QQ应用程序中,我们可以边视频边语音,也就有两个线程,一个是视频的线程,一个是语音的线程。
    • 进程是一个容器,线程是此容器中的工作单位。
    • 线程是CPU的基本调度单位。多线程是CPU对线程的频繁切换调用现实的伪多线程。
    • 同一个进程中的多个线程是内存共享的。
  • 线程与进程的区别

    • 地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
    • 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
    • 调度和切换:线程上下文切换比进程上下文切换要快得多。
  • 系统、进程、线程的关系图

Angular之$compile函数的使用

  • Angular之$compile函数的使用

    在用Angular写一些比较复杂的功能的时候,难免会遇到这样的需求:需要懂动态的往页面中插入一些元素,而且这些元素还需要跟scope中的的某些值绑定。

    比如要将一个div动态的插入到body中,如下:

    scope.attr = "hello";
    $("body").append('<div ng-bind="attr"></div>');
    

    但是如果只是上面这么写的话,不管你scope.attr怎么变化, div的html都不会有变化。那么怎么才能让它们绑定到一起的呢?这就要用到$compile函数了。

  • $compile函数的作用
    $compile函数可以将一段html字符串或者DOM元素跟scope编译绑定到一起。

  • $compile函数如何使用

    $compile(element)(scope);
    //element可以是一段html字符串,也可以是DOM元素;return值为编译完后的DOM元素
    
  • 用$compile完成上面的需求

    scope.attr = "hello";
    var html = $compile('<div ng-bind="attr"></div>')(scope);
    $("body").append(html);
    scope.$digest();//遍历scope
    

Angular之required和ng-required的区别

  • required和ng-required的作用

    当提交的表单时,通常都会做一些表单验证,当然也避免不了空值的检测。在angular里可以给input,select等设置required属性来对表单进行验证,不用自己再花时间去写验证。

  • 例如我们需要验证name名为myFrom下的userName文本框是否为空,我们可以给文本框设置required属性,然后通过myForm.userName.$error.required来获取验证结果。

    <form name="myForm">
      User name: <input type="text" name="userName" required>
      <span class="error" ng-show="myForm.userName.$error.required">Required!</span>
    </form>
    
  • 也可以设置ng-required来进行验证设置,ng-required跟required的区别是前者可以通过设置一些表达式来判断是否需要验证。

    <javascript>
      scope.userName = {name: 'zhangsan', validate: true}
    </javascript>
    <form name="myForm">
      User name: <input type="text" name="userName" ng-required="userName.validate">
      <span class="error" ng-show="myForm.userName.$error.required">Required!</span>
    </form>