Creating Sencha Cmd 包(Packages)

Sencha Cmd 包含了一个 Sencha 包管理器.即使你不愿意发布你的包,包仍然有很多用处.这个向导包含了创建包的过程和发布.关于包的使用详情,请参考 Sencha Cmd 包(Packages).

生成包

在我们能生成一个新包前,我们必须要先为它建立一个存储位置: 一个 工作区. 在这个例子中我们会要用 Ext JS 来生成这个包,因此我们从这个命令开始:

sencha -sdk /path/to/ext-n.n.n generate workspace /path/to/workspace

现在我们浏览这个新的工作区然后生成这个包:

cd /path/to/workspace
sencha generate package foo

包剖析

上面的步骤产生了一个包含了很多常用的文件的基础包.你能删除其中的大多数文件,但重要的是要完整的保留 ".sencha" 文件夹.

sencha generate package 生成包的结构如下:

packages/
    local/
        foo/                        # Top-level folder for the package
            .sencha/
                package/
                    sencha.cfg      # Sencha Cmd configuration for this package
                    build-impl.xml  # Generated build script for package
                    plugin.xml      # Sencha Cmd plugin for this package
                    codegen.json    # Data to support 3-way merge in code generator
            classic/                # Classic toolkit-specific src code
            examples/               # Example applications demonstrating the package
            licenses/               # License agreement
            modern/                 # Modern toolkit-specific src code
            overrides/              # Folder for automatically activated overrides
            resources/              # Static resources (typically has images folder)
            sass/                   # Container for styling code
                etc/                # General, non-component oriented styling
                example/            # - internal use
                src/                # Style rules named by component
                var/                # Variables and mixins named by component
            src/                    # Folder for normal JavaScript code
            build.xml               # Build script (called by `sencha package build`)
            package.json            # Package descriptor
            Readme.md               # High-level information about this package

上面的内容相当广泛,一个包最必要的部分是 "package.json"".sencha/package/sencha.cfg".

"package.json" 文件包含了包的描述. 下面这个例子来自于 "theme-neptune" 包:

{
    "name": "theme-neptune",
    "type": "theme",
    "creator": "Sencha",
    "summary": "Ext JS Neptune Theme",
    "detailedDescription": "The Neptune Theme provides a clean, modern style for Ext JS",
    "version": "n.n.n",
    "compatVersion": "n.n.n",
    "format": "1",
    "extend": "theme-neutral"
}

creator 属性是你要用来设置包的作者什么的. 这个内容没有检验,但它必须和你在我们后面会讨论到的你本地包库中的名字一致.

在应用中集成包

大多数包的目的是被集成到一个应用中 (最终) . 为完成这个功能, 在 sencha app build 运行过程中,Sencha Cmd 组织需要包的各个片段到应用中.

严格来说这个具体是怎么完成的依赖于包的类型.

包类型

不同的包有着不同的角色. Sencha Cmd 支持以下几种类型的包:

  • code - 由应用或其它包使用的任意一个代码包.这些包通是通用的并且在使用一个 require 语句来选择时被包含进来..
  • theme - 用于应用主题的包.主题包的特别之处是在一次构建中只一个类型为 theme 包通许被设为“active(激活)”.在 app.json 文件中的 theme 属性来选定主题.主题能够从其它的主题包中通过使用 extend 来继承其中的样式和资源.
  • locale - 这种包类型在一个在其路径中包含theme.name的一个标准包中已被放弃.例子参见 Ext JS locale package.

包的源代码

"src" 文件夹是用于存放一个例如定制化组件或其它有用的代码的类的地方.这些代码包含在 classpath 中,可以用于通过 require 要求的应用和其它包来使用.

这是你最可能放置你的 JavaScript 代码的地方. 放在这个文件夹下的类必须遵循 对编译器友好的代码原则.

样式

"sass" 文件夹包含三个设计用于处理不同方面的样式编译的子文件夹.

  • "sass/etc" - 不直接与 JavaScript类有关系的代码
  • "sass/var" - 变量定义 (反映 JavaScript 类层次)
  • "sass/src" - 混和的和规则 (反映 JavaScript 类层次)

在"sass/var""sass/src"目录下的文件夹和文件组织成实现的 JavaScript 类的镜像. 这种对应关系允许 Sencha Cmd 包含应用所需要的文件.在这些文件夹下面的不符合这一原则的文件将不会被包含, 因这这一过程会将 JavaScript类层次结构映射到文件系统并且不会扫描这些文件夹.

名致的对应关系由"package.json"文件中的namespace属性来宝义:

{
    "name": "MyPkg",
    ...

    "sass": {
        "namespace": "MyPkg",
        ...
}

当映射一个需要的 JavaScript 类的类名到对应的 .scss 文件时,命名空间开始起作用. 例如,上面给出的类 MyPkg.foo.Barnamespace (命名空间) , Sencha Cmd 移除 “MyPkg.” 然后在 "sass/var" 中查找一个 “foo/Bar.js” 的相对路径和"sass/src" 文件夹.

注意: 尽管 Fashion 不是对Sass的实现, 这个关于 “sass” 的配置为了兼容缘故仍然保留.

包的资源

"resources" 文件夹是用于存放包需要的静态资源的地方. 当应用使用这个包时,它们会拷贝这些资源到自己的由包名命名的"resources"文件夹的子目录中.在这个例子中, "resources/foo". 如果你使用的是theme-background-image 方法,CSS文件的相对路径将被自动修动.

覆写

这个"overrides" 文件夹是一个为你的包提供强制覆写的专门目的, 因此这的名字是这个. 由于放在这个目录下的代码会自动被包含到你使用这个包的任一应用,这种机制必须要小心使用.

Ext JS Neptune 主题使用这一机制来修改各个组件的某些缺省配置. Locale (本地)包使用这个机制来在各个组件原型上来注入他们自己的文本或者提供事务的本地化特定的逻辑例如日期格式等.

包的版本

包有一个描述其当前版本号码的 version 属性.另外,这个当前版本 (在 version 属性中的), 通过使用compatVersion属性包能够标识出向后兼容的情况.

当解决版本的需求时,这些版本信息可以用到.一个包的版本发布必须有一个更新的版本号码.这意味着由Sencha提供的版本号码赋予的意义可以帮助你:

x.y.z.b

x = Major release number (large, impacting changes and features)
y = Minor release number (new functionality but few if any breaking changes)
z = Patch release number (bug fix / maintenance release - goal of 100% compatible)
b = Build number (assigned by build system)

version 属性典型的是维护最易. compatVersion, 而是,一个关于用户能转换升级和不需要代码修改程序的一个特意说明.

包的要求

包可以包含其它包,同样应用也可以包含包. 方法是,你可以添加 requires 列表:

{
    "name": "bar",
    "type": "code",
    "creator": "anonymous",
    "summary": "Short summary",
    "detailedDescription": "Long description of package",
    "version": "1.0.0",
    "compatVersion": "1.0.0",
    "format": "1",
    "local": true,
    "requires": [
        'ext-easy-button'
    ]
}

注意: 当使用版本约束作为包作者,重要的是要注意一个应用所有必须的包要使用一个普通的版本.如果你特别强调约束,这个过程会在为所有需要的包找到一个双方都同意的版本时失败.

包的继承

包继承的概念是专门针对主题的. 这是被继承包的内容批量进入衍生包的最重要的方法.:

  • 被继承包的 "resources" 文件夹将复制到 "build" 输出目录的 "resources" 文件夹.
  • 基础包的 overrides 会自动在衍生包的构建输出目录会自动包含.

构建包

发布一个包,你需要使用下面的命令构建:

sencha package build

这个命令在包内产生一个叫做 "build"的文件夹. 这个是当它们运行在 "开发模式"时应用需要的文件 (没有被编译的).

它同时也会在你的工作区的 "build"文件夹中产生一个 "foo.pkg" 的文件. 这个文件由于下述原因没有放在包的 "build"文件夹中:

  • 它是你的包文件夹的一个压缩文件.
  • 它不是这个包用户需要的.

这个 "foo.pkg" 文件用于将这个包加到你的本地库中.参见下节.

框架

你需要手动在你的 "package.json"文件中添加包的框架名称.

"framework": "ext"

主题

你需要手动在你的 "package.json"文件中添加包的主题. 这个值应是用来生成 CSS 文件的主师包的名字.

"theme": "theme-triton"

本地库

本地库是在Sencha Cmd 包(Packages)中引进的, 但当你要发布你写的包时还有更多的东西需要了解.

结构

Sencha Cmd 生成的本地包象下面这样:

.sencha/
    repo/
        sencha.cfg                  # Sencha Cmd configuration for the repo
        plugin.xml                  # Plugin for repository hooks
        private-key.json            # Private key for repo

        remotes/                    # Storage for remote repositories
            remoteName/             # Name given at `sencha repo add`
                catalog.json        # Last catalog from this remote

        trust/                      # Unused in this release
            <somename>.cert.json    # Copy of `cert.json` (a public key)

pkgs/
    catalog.json                    # Catalog of all packages in this repo
    cert.json                       # Public key for this repo

    Foo/
        catalog.json                # Catalog for all versions of Foo package
        cert.json                   # Public key for creator of Foo package

        1.0/                        # Folder containing version 1.0
            Foo.pkg                 # Zip file of package
            package.json            # Extracted package descriptor
        1.1/
            ...

    Bar/
        ...

作者标识

当 Sencha Cmd 生成默认的本地包时,它不需要你提供任何类型的标识.因为它的作用是作为缓存,这是好的,但做为包的作者你要将你的名字放进你发布的包中.在你能发布包前,你要用一个标识来初始化你的本地库:

sencha package repo init -name "My Company" -email "support@mycompany.com"

完成这个后,你的名字和电子邮件地址会通过一个新 public/private 密钥对 记录进本地库中.

注意: 这个 name 参数必须和你在 "package.json"文件中设置的 createor 属性的值相同.

Public/Private 密钥

你的名字,电子邮件和公共密钥存储在"pkgs/cert.json" 文件中. 这个文件会自动加到你开发的包来来标识你是这个包的作者.

显然给了它名字,你的私有密钥是不愿意和别人分享.它是存储在你本地库的一个叫做 ".sencha/repo/private-key.json"文件中.

你可能要备份这两个文件,因为在未来的版本中它们将发挥重要的作用.

内容

"pkgs" 文件夹是所有包存储的地方.这些可以是你要开发的包或者是你要下载的包.

当你添加包 ".pkg" 文件时,这些包会被拷贝到 "pkgs" 目录树中.

库钩子

".sencha/repo/plugin.xml" 文件是你以提供 "hooks"到库里动作例如象 sencha package add 命令一样的 Ant 脚本. 更多关于这个的详情,参考这个生成文件中的注释.

添加包

当你从构建中有了 ".pkg" 文件,假定你在你的本地库设置了你的标识名称和你在"package.json"文件中的 creator 属性设置的一致,你能运行下面的命令:

sencha package add foo.pkg

Sencha Cmd 会使用你的私有密钥产生这个 ".pkg"文件中的一个哈希值并将它加入你定义好的 ".pkg"文件中,然后会将这个文件拷贝到你的本地库.

现在这个包进了本地库,如果其它的开发者将你的库作为远程库加入了的话,它们就能 "require" 这个包.

这个要求的过程 Sencha 添加你的 ".pkg"到 Sencha 包库仍然等待定稿,但你能通过检查Sencha Market 来更新.

建立一个包库主机

"pkgs" 文件夹的结构是和远程库要求一样的结构.其他人要求这个你开发的包时他们需要做的是添加一个远程包库:

sencha package repo add my-company http://my.company.com/packages

这是,假定你将 "pkgs"文件夹内容按上面的 HTTP URL 发布到了主机上.通过 HTTP GET 访问这样一个静态文件服务器或通过CDN没有什么要求就能工作.

Last updated