[基础系列] 如何更好的组织 Angular2 文件结构

当我的文章写到最后时,我发现了在Github里面已经有个非常专业的Angular2样板项目angular2-webpack-starter,他完全包括我想要的东西甚至很多我并未考虑的,比如:单元测试、热替换等。所以我删除我的文章,只保留一些我认为有必要声明的理论知识;转而对angular2-webpack-starter的简单翻译事宜。

一、写在前面

angular2-webpack-starter已经有完整的解决方案,而且非常优秀。但在此之前我会解释一些理论问题。

1、模块规范

模块是一个极为重要的概念,别人写的功能代码你可以直接拿过来用;但,如果你的代码没有按指定的规范来写,那怎么可能做到代码相互使用呢?虽然 ES6 已经有模块的概念,但目前整体Javascript发展来看还需要一段时间。

目前最常用的有CommonJS、AMD、CMD。这三者的主要区别在于,从加载模块的角度出发:

CommonJS
比较适合服务端,因为当我们使用 require('math') 来加载一个模块时,由于模块文件在服务端都是存在本地硬盘上,所以非常快的加载进来。而如果我们把这一行代码放在客户端里面,我们就会遇到一个问题 异步加载,因此才会有AMD规范这一说。

AMD
AMD为的就是解决CommonJS在前端异步加载的不足,当然国产的CMD也是如此,只不过二者存在加载顺序上的区别,不过现在已经没有区别了,因为AMD也改为跟CMD相同原理的加载模式。

SystemJS
万能的加载器,她的定位包括ES6代码,当然既然是万能就少不了:CSS、图片。

三者的规范都是为了解决一些模块加载问题,那么选用什么规范更合理呢?这取决于你的需求,合理需求选用合理的规范。

2、我的选择?

我个人比较偏爱CommonJS,因为我们大部分项目都是单页应用,换句话说CommonJS先天性不足,并不会对我们有什么影响。当然相比较其它规范,有着更多的优势:

  • CommonJS更容易被流行的打包工具所接受,比如:Webpack、Browserify
  • CommonJS比SystemJS更容易
  • CommonJS是node.js格式,允许组件更容易在服务端渲染
  • CommonJS服务端和前端共用代码
  • CommonJS生成的文档可以省20%的空间

二、细说angular2-webpack-starter

angular2-webpack-starter是使用Webpack来构建针对Angular2和TypeScript的样板项目,还包括E2E和Karma单元测试,他列举几项使用样板项目的理由:

  • 它是构建Angular2文件组织的最佳实践。
  • 基于Webpack编译TypeScript。
  • 自动化单元测试。
  • 热替换。
  • 使用Material Design。

1、快速启动

首先要确保 node版本4.0 以上。

# 从git克隆一下最新版本
git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git

# 切换至项目根目录
cd angular2-webpack-starter

# 先添加一些全局库,这样下次使用时不需要再重新获取 
# 在安装webpack时,我出现了 AttributeError: ‘MSVSProject’ object has no attribute ‘iteritems’ 异常
# 后来我更改为: npm install webpack -g 既然成功了。
# 如有其它异常见:http://asdfblog.com/npm-install-errors.html(欢迎提交更多异常和解决方案)
cnpm install typings webpack-dev-server rimraf webpack -g

# 使用cnpm(淘宝NPM 镜像)安装组件
cnpm install

# 启动
# 如果收到 `Cannot find name 'Promise'.` 异常时,表明未正确安装ts定义
# 重新运行:npm run typings -- install
npm start

# 获取启动一个带有热替换的服务
npm run server:dev:hmr

最后在浏览器访问:http://0.0.0.0:3000 或 http://localhost:3000,效果如下:

test

2、文件结构

angular2-webpack-starter使用组件风格来管理文件,这很符合Angular2的发展新标准,这样有利于代码可维性和行为逻辑封装。一个组件的基本组成包括:组件类、样式、模板文件、单元测试等。具体结构如下:

angular2-webpack-starter/
 ├──config/                    * 配置文件夹
 |   ├──helpers.js             * 配置辅助类
 |   ├──spec-bundle.js         * 测试文件所需要的额外配置
 |   ├──karma.conf.js          * karma 配置文件(单元测试)
 |   ├──protractor.conf.js     * protractor 配置文件(端对端测试)
 │   ├──webpack.common.js      * webpack 开发、产品、测试模式通用配置文件 
 │   ├──webpack.dev.js         * webpack 开发模式配置文件 
 │   ├──webpack.prod.js        * webpack 产品模式配置文件 
 │   └──webpack.test.js        * webpack 测试模式配置文件
 │
 ├──src/                       * 程序源代码
 |   ├──main.browser.ts        * webpack的entry入口
 |   ├──index.html             * index.html模板文件 
 |   ├──polyfills.ts           * polyfills 文件(提供支持ES6特性)
 |   ├──vendor.ts              * 第三方组件(目的为webpack能够正常打包)
 |   ├──custom-typings.d.ts    * 自定义ts定义,ts编译时非常严格
 │   ├──app/                   * APP应用源文件
 │   │   ├──app.spec.ts        * 组件app.ts的单元测试
 │   │   ├──app.e2e.ts         * 端对端的测试文件 
 │   │   └──app.ts             * App.ts 组件入口
 │   │
 │   └──assets/                * 静态文件
 │       ├──icon/              * icon文件 
 │       ├──service-worker.js  * 忽略
 │       ├──robots.txt         * 相关搜索引擎
 │       └──human.txt          * 见:humanstxt.org
 │
 ├──nitrous.json               * 一个逆天的构建在线测试站(需要费用)
 ├──tslint.json                * typescript lint 配置文件
 ├──typedoc.json               * typescript 文档生成配置
 ├──tsconfig.json              * typescript 编译配置文件
 ├──typings.json               * ts定义配置文件
 └──package.json               * npm配置文件

app/home/ 相当于一个页面的组件都包括在该文件夹下,同时文件夹又嵌套着页面所需要的其他组件,构建一个完整的ng2网站是由若干组件组合而成,一个页面可以被细分出不同子组件,整体组件的结构图跟一个树结构一样。

3、入门指南

在【1、快速启动】已经做了很多注释以及可能发生的QA,不再赘述。重点来看angular2-webpack-starter提供的一些运行指令。

其它运行指令

编译文件

# 编译开发版本
npm run build:dev
# 编译生产环境版本
npm run build:prod

编译成功后会在根目录下生成一个 dist 文件夹。

热替换模式

npm run server:dev:hmr

意味者进入开发模式后,你可以打开 http://localhost:3000,当你修改ts文件时会自动重新编译,并以热替换的形式变更页面效果。(非常赞喔,特别是安装ssd硬盘的,响应更佳!)

监听和编译

npm run watch

意味者进入开发模式后,你可以打开 http://localhost:3000,当你修改ts文件时会自动重新编译。

运行测试

npm run test

运行并监听测试

npm run watch:test

运行端对端测试

npm run watch:test

4、自定义类型定义(TS)

当使用第三方模块时还需要包含模块的类型定义,可以尝试使用 typings install node --save 来安装TS定义。但是并不是所有模块都已经在TS中已经有注册相应的类型定义文件。那么,我们只能自己来写这些TS定义信息(这也是没有办法TS编译器在编译过程中严格规定所有类型都需要有明确的定义),例如:

declare module "my-module" {
  export function doesSomething(value: string): string;
}

或者,可以定义一个全局的 any 类型变量,例:

declare var assert: any;

总结

angular2-webpack-starter是一个非常棒的样板项目,你可以直接在此基础上做产品开发,即便自己建也未必能够这么周到;同时项目已经被Star:2415可见有多么热门。

angular2-webpack-starter常见问题清单已经有很多可能发生的问题并已经给出了具体解决方案,但凡在使用过程有问题也可以去提交issues。

之前一直在群里(QQ群:485843913)经常会提出Angular2环境搭建问题,特别是拿官网的快速入门做为敲门砖,但是官网的示例在现实生产环境中一点也不合格;我相信angular2-webpack-starter是最简单解决我们生产环境下所有问题的最佳样板项目了。读懂她,才算真正才能开始入门Angualr2吧。

12 Comments

  1. 请问 如何在这里面使用 npm 下载的 booststrap 就只使用css 字体 图片什么的
    不在 index.html 直接link 怎么使用啊

    • asdf

      2016年6月12日 at 18:18

      首先得明确一点,css是必须引用的,但有一些看起来不需要引用这取决于打包方式,比如像webpack可以直接将css打包到js脚本当中,这样看起来就像是没有在引用CSS一样。

  2. styles: [
    require(‘bootstrap/dist/css/bootstrap.css’)
    ],

    本人菜鸟一只 这样css 是导入进来了 可是 样式里面 引用的图片 却没有跟进来 这个如何解决啊 难道 我要把 node_modules /boot..也跟着一起上传么?
    有没有简便的方法

    • asdf

      2016年6月13日 at 17:53

      在Angular2中就会有一个绝对和相对路径问题,其中index.html里面的来设置查找资源文件开始位置。那么CSS中引用的资源路径是取决于css处在的位置,而一般我们是把CSS直接打包到JS中,所以一般我们会在src文件夹下建一个assets的目录专门来存放我们的资源文件。

      这样CSS在引用资源时,路径统一由assets开头,这样就不会有什么路径问题。

      而对于第三方组件的一些资源文件,像bootstrap应该很好处理,修改他的资源路径变量值,再把资源复制到assets里面,大概就是这样子。(或写一个打包脚本,交由打包脚本来执行)

  3. 还有一个问题是 版本1里面 不建议使用 jquery
    那版本2里面也不建议使用jquery吗?
    那如果想要用 grid 或者 日期插件什么的 应该怎么做

    • asdf

      2016年6月13日 at 17:54

      Angular2在Github里面已经有非常多的插件了,你要的这些都能够找得到。

  4. 谢谢你

  5. 为什么不能提问了

  6. new HtmlWebpackPlugin
    // Webpack生成了一些js和css文件。 虽然我们可以手动把它们插入到index.html中,但那样既枯燥又容易出错。 Webpack可以通过HtmlWebpackPlugin自动为我们注入那些script和link标签。

  7. 插件使用publicPath和filename设置, 来向index.html中插入适当的script和link标签。
    template: src/index.html

  8. 一直都不明白 如何在程序中 写 才会往index.html 中插入 link

  9. 问题已解决

发表评论

Your email address will not be published.

*

© 2017 卡片机色彩 沪ICP备13032872号-3

Theme by cipchk

to top