# 基本内容

这里简单介绍BrightJS框架的基本形态和使用方式

## 点路径

BrightJS在资源路径的写法上统一使用点路径而不使用`\`，所以请确保被使用的文件名中不带有`.`（不带后缀），不然会导致资源引用错误。

## 资源管理

尽量将静态资源管理托管给BrightJS去处理，BrightJS会确保资源使用的高效性，同时保证写法的简洁。

BrightJS使用`packet`模块来进行资源的管理，BrightJS是一个带有头部注解的javascript文件，头部注解标识出资源依赖的相关信息，在运行时BrightJS根据所使用的BrightJS来进行资源的加载和区别使用。如果开启BrightJS静态缓存，BrightJS便会根据资源的状态选择是否从缓存中获取资源并加以使用。BrightJS内建资源的增量更新能力，以及应用发布规范，托管静态资源管理于BrightJS将会省去处理大量复杂又繁琐工作的时间和精力。

BrightJS的资源管理只需要一个`basePath`属性，用于规定资源查找的项目目录，而且仅该目录下的所有资源则为BrightJS管理的资源。由于BrightJS是一种模块化开发解决方案，所以目录的组织结构应该尽量保持独立，并将所有模块使用的资源放入其中，可以不需要计较文件夹的深度以避免模块名称相同的问题（这与java的包管理机制很类似，可以创建类似`com.companyname.module`这样的包）这样在引入第三方或者进行团队开发时可以直接引入或者直接去除而不必进行再次处理，以免出现问题。

## packet

packet是一个带有头部注解的javascript文件，运行时类似基于AMD或者CMD的module，但是packet比前者更为强大。packet的代码是在闭包中运行的。

### 头注解：

    /*!
     * @packet test;
     * @css test.style.main;
     * @template test.todolist:newname;
     * @image test.image[jpg]
     */
    code...

> 头注解是放在文件头部的注释及注解写法，一个文件只能有一个头注解，其他的注解写法都会被忽略

### 内置注解类型

- `@packet` 该注解标识该packet的packet名，它往往是packet的第一个书写注解，它同时也是必须写的唯一注解，packet名称是文件路径+文件名（不带后缀）的点路径形式。packet中的代码是在闭包中运行的。
- `@usestrict` true或者false，用于规定该包内的代码是否按照严格模式运行，默认以非严格模式运行。
- `@css` 引入css文件，css路径为点路径。
- `@template` 引入模板文件，template路径为点路径。
- `@js` 引入js文件，js路径为点路径。被引入的代码直接在window下运行，其与直接引入页面的方式没有差别。
- `@json` 引入json文件，json路径为点路径。
- `@text` 引入text文件，text路径为点路径。
- `@require` 引入packet文件，packet路径为点路径。被引入的文件会立即被加载并执行。
- `@include` 引入packet文件，packet路径为点路径。被引入的文件会在实际使用时被加载，而不是在packet代码执行前被加载。
- `@html` 引入html文件，html路径为点路径。
- `@image` 引入image文件，image路径为点路径，同时还必须指明文件的后缀`@image test.image[png]`如果不指明，默认为`.png`。

> 内置注解是BrightJS预置的注解类型

### 短包名

在任意packet文件里可以通过短包名来书写packet名称。packet名称根据不同的目录结构而造成名称过长的问题，进而引入短包名来解决这样的书写过长问题。

- `@`+尾名（包名最后一个`.`后面的字符,例如`test.mobi.test2`的短包名为`test2`）指代该包名，例如`"@name.module"`,如果尾名出现重复可以指代一个新名称，如`test.mobi.test2:newname`这样尾名便是`newname`
- `@`指代当前包包名，例如`"@.module"`

### 获取资源

在运行时可以通过`module`对象获取相关资源，具体详见`packetInfo`对象

### 代码发布形式

packet内的代码是在闭包中运行的，所以任何的有效代码都可以被执行，在BrightJS环境内，packet内的代码可以按照以下任何方式编写。

- `Module()`可以在packet内只定义Module
- `Option()`可以在packet内只定义Option
- `jQuery Plugin`可以按照jQuery Plugin类似写法发布组件
- `module.exports`可以按照AMD&CMD方式发布组件
- `Plugin()`一种jQuery Plugin类似功能的简写方式
- `Method()`一种jQuery Plugin（全局方式）类似功能的简写方式
- `other`可以混合使用上面的形式

> 虽然可以在packet内书写多种形式的代码，但建议只在一个packet内编写一种代码发布形式的代码。

## 模板

BrightJS内置一个小型模板引擎，并为内置框架提供模板支持。

- 支持原生javascript语法
- 支持宏（自定义标签）

### 内置宏

- `<@include data='' template=''>`用于引入其他模板

### 模板文件

模板文件为一个`.html`的文件，一个文件中可以编写多个可用模板，并用`<!--[templateName]-->`分割，`<!--[templateName]-->`用于标识其下模板代码的名称，并默认以该模板文件的点路径作为其命名空间。

## 内建框架

BrightJS的内建框架是朴素的，它只是面向对象的。BrightJS内建框架只有两种数据类型，一种为`Module`，一种为`Option`，Module相当于类，Option相当于类的实例。

Module是面向对象的，所以它支持继承等标准面向对象的特性，这将极大的增强代码的复用和可拓展的能力。从整体上看，内建框架只是使用简单的组合模式进行Module的组织，同时Module提供大量的内建方法，这些方法可以简化开发时的基础问题，使开发者更专注于业务逻辑本身。Module虽然是朴素的，但是它仍然具备前端开发中的一些先进理念的特性，比如MVVM等，只是这样的特性并非是BrightJS设计的核心思考。

Option代表着Module的一个实例，也就是说Option对象可以初始化Module。Option并非单纯的初始化配置，它支持继承，它同时具备在运行时修改Module行为的能力，所以如果认为Module是相对稳定的数据结构的话，Option则是面对处理与业务息息相关的问题而存在的。很多时候，并非需要创建过多的Module，而只需要创建Option便可以对Module进行业务化的改造。这极大的简化开发时的困难程度。

所以使用内建框架首先会抽象出基本的类型（Module）并加以实现，并在具体业务环境下使用Option来进行局部改造，从而实现整个应用。Module是相对稳定的，具备可复用的能力，Option是与业务息息相关的，它是不稳定的。

## css相关

由于BrightJS是模块化开发的，而且模块间可以相互组合使用，所以如果css定义过于松散就会导致模块在相互组合时造成错乱而且给后期维护带来压力。所以BrightJS建议css的定义应该按照模块化方式进行。

- 使用less或者sass编写模块化样式
- css依赖的资源放到css同级目录

## 应用部署及更新策略

BrightJS的部署和更新策略需要借助BrightBuilder构建工具来完成。BrightJS在构建工具处理后会生成中间文件（开发者无需关注这些文件），这些文件是经过合并压缩后的中间产物，这些文件会在首次运行应用时被加载一次。后续应用一旦升级也不会重载这些文件，而只会加载被修改的文件。

BrightJS在每次构建后都会生成一个新的文件包（以及一个资源表），而不是覆盖原有文件包，BrightJS的文件版本管理更新策略不是采用文件hash命名的方式进行，而是使用新文件包增量更新策略。在客户端看来，更多的依赖于缓存，并且更加资源配置的不同，哪里修改便重载哪里。服务器部署和更新或者回滚则只需要拷贝构建文件包，并修改承载页面的资源表便可以。

> 传统的缓存策略一般使用文件hash来作为文件名，当文件修改其hash随之变动，文件名也随之改变，同时也就生成了一个新文件，新文件不会覆盖原文件，这样在更新或者版本后退时都带来好处。BrightJS不使用hash作为文件名，而是整体生成部署包和资源表来实现。静态资源如果托管于BrightJS处理，BrightJS在使用资源时会根据资源表来校验版本，如果有版本变动则从新的部署包中获取资源，如果版本没有变化，则直接从缓存中获取。BrightJS会将部分资源缓存于localStorage中，所以部分资源的使用甚至会省去http请求。

### 资源的更新策略

BrightJS对不同的资源类型进行特殊处理，而并非统一对待，所以可以根据具体情况对资源进行有效的优化管理。

- BrightJS:增量更新，更新的粒度取决于BrightJS的划分粒度。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- template:增量更新，更新的粒度取决于BrightJS的划分粒度。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- css:增量更新，更新的粒度取决于BrightJS的划分粒度。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- css依赖的资源：css依赖的资源随着css的变化而变化，即css依赖的资源的变动会引起css文件的变动，而BrightJS只会关注css的变动。
- javascript：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从缓存中获取。
- json：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- html：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- text：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从localStorage中获取，而不发送http请求。
- image：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从缓存中获取。
- 其他资源：全量更新，文件修改则完整加载新文件。如果版本未变动则直接从缓存中获取。

> BrightBuilder会根据项目构建配置文件对项目packet目录进行扫描，将依赖从文件中解析出来，并对这样的资源进行处理。解析出来的文件包括css，packet，template等，而这些css，packet和template将被合并压缩为一个单一文件。这个文件在程序首次载入（或者用户删除本地存储）时立即被载入解析，并写入客户端localStorage（如果可以），以提高程序的响应速度，此后一旦某些文件发生改变（根据所需资源的资源版本配置进行判断）将重新获取新的文件（BrightJS采取多目录文件定位而非文件hash定位方式，每次版本变动都会生成新的文件目录）以实现文件的增量更新，如果未发生版本变动则从localStorage中直接获取以使用。

> 以上策略需要服务器可以开启永久缓存。服务器需要保存上线过的全部包，或者设置版本重构前端再删除。