# Van在生产环境中的使用
## 发布到npm服务器
NPM是随同NodeJS一起安装的包管理工具，能解决NodeJS代码部署上的很多问题，常见的使用场景有以下几种：

允许用户从NPM服务器下载别人编写的第三方包到本地使用。
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

我们使用npm上传包到npm服务器：
``` javascript
npm publish
```
(图)
上传成功后，用户就可以通过 npm install 的方式引入Vanjs的包：
``` javascript
npm install vanjs --save-dev
```
或者直接在package.json中声明对Vanjs的引用：
``` javascript
"devDependencies": {
  vanjs: "^0.0.6"
}
```
## 单文件组件
在Vanjs项目中，我们使用 Van.component 来定义全局组件，紧接着用 component.newInstance() 获得组件的实例。
这种方式在很多中小规模的项目中运作的很好，在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中，或者你的前端完全由 JavaScript 驱动的时候，下面这些缺点将变得非常明显：

全局定义(Global definitions) 强制要求每个 component 中的命名不得重复
字符串模板(String templates) 缺乏语法高亮，在 HTML 有多行的时候，需要用到丑陋的 \
没有构建步骤(No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器，如 Pug (formerly Jade) 和 Babel

文件扩展名为 .js 的 single-file components(单文件组件) 为以上所有问题提供了解决方法，并且还可以使用 Webpack 或 Browserify 等构建工具。

这是一个名为Bird.js的单文件组件：
``` javascript
import Van from 'vanjs/src';

var Bird = Van.component({
  name: 'Bird',
  data: {
    x: 100,
    y: 100,
    vx: 0,
    vy: 0,
    radius: 10
  },
  render: function() {
    this.$ctx.beginPath();
    this.$ctx.strokeStyle = this.color;
    this.$ctx.fillStyle = this.color;
    this.$ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
    if (this.data.fill) {
      this.$ctx.fill();
    } else {
      this.$ctx.stroke();
    }
  },
  handlers: {
    'clicks': function() {
      this.vy = -200;
    }
  }
});

export default Bird;
```
我们可以在其他组件中使用这个组件：
``` javascript
import Van from 'vanjs/src';
import Bird from './component/bird.js';

var van = new Van({
  // 省略部分代码...
  components: [
    Bird.newInstance(),
  ],
  area: function() {
    return true;
  },
  listener: {
    click: [function() {
      this.$dispatch("clicks",{});
    }],
  }
});
```
通过使用单文件组件，我们可以将一个组件单独放置于一个js文件中，然后在其他组件中使用模块化系统来引入该组件。配合科学合理的目录设置和组件层级划分，我们可以更加清晰地描述组件之间的层级关系和依赖关系，便于整个项目的开发和维护。
