embercli
翻译自https://ember-cli.com/,embercli 文档。
本文原文地址:
https://ember-cli.com/user-guide/#asset-compilation
https://ember-cli.com/user-guide/#managing-dependencies
资源编译
原始资源
- public/assetsvs- app/styles
想要添加图片、字体或者其他资源,直接把他们放在 public/assets 文件夹。比如,把 logo.png 放到 public/assets/images,你可以在模板里面引用它 assets/images/logo.png,或者在样式表里面引用 url('/assets/images/logo.png')。
Ember-CLI 的这个功能来自 broccoli-asset-rev。请仔细检查所有的选项和使用说明。
JS 转换
Ember-cli 会自动转换未来版本的 JS (ES6/ES2015, ES2016 and beyond)到标准的 ES5 JS,通过 Babel JS 和 ember-cli-babel 插件,让每个浏览器都可以运行。
默认的配置可以处理大部分项目的需要,但是你可以提供配置来禁用某些指定的转换,比如你的 app 只在确认能跑 ES6 的浏览器运行,或者约定开启转换某些暂时默认没开的试验性特性。
你可以在 ember-cli-build.js 里配置 babel 的运行选项。比如,这样可以禁用 ES6/2015 特性:
| 1 | // ember-cli-build.js | 
这些选项转发自 Babel。Ember-cli 现在用 Babel 5.X,你可以查看这个完整的文档all available transformations ,还有选项 options。
升级到 Babel 6 的工作正在进行中。你可以查看进度track the progress and help。
混淆/最小化
编译的 CSS 文件被 broccoli-clean-css 或 broccoli-csso 最小化。你可以传递最小化指定参数给他们,通过你的 ember-cli-build 传递minifyCSS:options 对象。生产环境最小化默认会打开,可以用 minifyCSS:enabled 开关关闭。
相似地,JS 文件在生产环境默认用 broccoli-uglify-js 最小化。你可以在 ember-cli-build 通过 minifyJS:options 传递定制化参数给最小化器。开关 JS 最小化,只需要加一个布尔参数 minifyJS:enabled。
举个例子,关掉 CSS 和 JS 的最小化功能,ember-cli-build.js:
| 1 | // ember-cli-build.js | 
不需要最小化的例外
去除 dist/assets 里不需要最小化的资源,可以传递参数给 broccoli-uglify-sourcemap ,比如这样:
| 1 | // ember-cli-build.js | 
这样会让 vendor.js 的文件不被最小化。
Source Maps
Ember CLI 支持制作一个 source maps 给你的合并或最小化的 JS 文件。
Source maps 被 sourcemaps 选项指定配置,默认是不打开的。传递 sourcemaps: {enabled: true} 参数给你的 EmberApp 构造器,会打开 source maps。使用 extensions 选项来添加其他的格式,比如coffeescript 和 CSS:{extensions: ['js', 'css', 'coffee']}。JS 现在开箱即用,CSS 目前不支持。其他的格式(Sass, Coffee, etc)取决于他们自己的插件。
默认 ember-cli-build.js:
| 1 | import EmberApp from 'ember-cli/lib/broccoli/ember-app'; | 
样式表
Ember CLI 开箱即用朴素的 CSS。你可以添加你的样式到 app/styles/app.css,它会自动编译成 assets/application-name.css。
比如,添加 bootstrap 到你的工程,你需要这么干:
| 1 | bower install bootstrap --save | 
在 ember-cli-build.js 加这段:
| 1 | app.import('bower_components/bootstrap/dist/css/bootstrap.css'); | 
这会告诉 Broccoli 我们想要把这个文件合并到 vendor.css。
要用 CSS 预处理器,你要添加合适的插件 Broccoli。当使用一个预处理器的时候,Broccoli 可以被编辑成在 app/styles 文件夹查找一个app.less, app.scss, app.sass,
或 app.styl 清单文件。清单文件应该引入所有其他的样式表。
所有处理之后的样式表会被编译成一个文件 assets/application-name.css。
如果你想改变这个行为,或者想编译成多个输出,你可以调整输出配置。(参见后面的文档)
CSS
朴素 CSS 直接用 app.css:
- 在 app.css里写你的样式,或者把你的 CSS 放到不同样式文件,然后在app.css通过@import引入。
- CSS @import语句 (e.g.@import 'typography.css';) 必须是合法的 CSS,意味着@import语句 必须 在其他规则之前,所以它们必须放在app.css的顶部。
为了处理你的引入文件,用文件对应的内容替换它们,在 ember-cli-build.js 添加:
| 1 | // ember-cli-build.js | 
会造成如下的改变:
- 构建生成环境,@import语句被对应文件的正文替换,然后最小化,合并到一个 CSS 文件dist/assets/yourappname-FINGERPRINT_GOES_HERE.css。
- 任何独立的 CSS 文件也可以构建,最小化到 dist/assets/,假如你需要单独用这个样式表。
- 相关路径会被改变
例如 app.css ,使用了合法的 @import:
| 1 | /* @imports must appear at top of stylesheet to be valid CSS */ | 
CSS 预处理器
为了用后面的预处理器,你需要做的就是安装合适的 NPM 模块。各自文件会被挑选,自动化处理。
LESS
为了启用 LESS,你需要加 ember-cli-less 到你的 NPM 模块里。
| 1 | ember install ember-cli-less | 
SCSS/SASS
为了启用 SCSS/SASS,你需要加 ember-cli-sass 插件到你的工程 (配置默认允许 .scss, .sass ).
| 1 | ember install ember-cli-sass | 
你可以配置你的 ember-cli-build.js 使用 .sass:
| 1 | // ember-cli-build.js | 
Compass
想用 Compass,用 NPM 安装 ember-cli-compass-compiler 插件。
| 1 | ember install ember-cli-compass-compiler | 
Stylus
为了使用 Stylus,你需要加 ember-cli-stylus 到你的 NPM 模块:
| 1 | ember install ember-cli-stylus | 
CoffeeScript
为了用 CoffeeScript,你需要加 ember-cli-coffeescript 到你的 NPM 模块里:
| 1 | ember install ember-cli-coffeescript | 
package.json 的改动应该纳入源码版本控制。CoffeeScript 可以在你的源码和测试里面用,只需要用 .coffee 扩展名就好。我们推荐使用版本 >= 1.16.0 的 ember-cli-coffeescript 来避免用 import 和 export 语句。
注意:早期的编译器版本就明确支持 CoffeeScript,但是现在这个支持被删除了。
EmberScript
为了用 EmberScript,你需要加 broccoli-ember-script 到你的 NPM 模块里:
| 1 | npm install broccoli-ember-script --save-dev | 
注意:ES6 模块转译器不直接支持 Emberscript,要使用 ` 字符,和上面 CoffeeScript的例子差不多。
Emblem
要用 Emblem,跑这个命令:
| 1 | ember install ember-cli-emblem | 
如果你用早期版本的 broccoli-emblem-compiler 插件,你需要选择 ember-cli-emblem。早期版本的 broccoli-emblem-compiler 直接编译成 JS 而不是 Handlebars,因此和现在新版的 HTMLBars 不兼容。
指纹和 CDN URLs
指纹使用这个插件 broccoli-asset-rev
(默认已经包含)。
在生产环境(e.g. ember build --environment=production),这个插件会自动化算你的js, css, png, jpg, gif 资源的指纹,添加一个 md5 checksum 到他们的文件名结尾
(e.g. assets/yourapp-9c2cbd818d09a4a742406c6cb8219b3b.js)。另外,你的 html, js, css 文件会被重写成新名字。这里有很多参数你可以传递给EmberApp,通过改 ember-cli-build.js 定制你的行为:
- enabled- 默认:- app.env === 'production'- Boolean. 为真的时候启用指纹算法。生产环境默认为True
- exclude- 默认:- []- 一个字符串数组。如果一个文件名被包含,它不会被计算指纹。
- ignore- 默认:- []- 一个字符串数组。如果一个文件名被包含,它的内容不会被计算指纹。
- extensions- 默认:- ['js', 'css', 'png', 'jpg', 'gif', 'map']- 需要添加 MD5 checksum 的文件类型。
- prepend- 默认:- ''- 预先在所有资源添加。加 CDN urls 的时候很方便,比如- https://subdomain.cloudfront.net/
- replaceExtensions- 默认:- ['html', 'css', 'js']- 需要用带 checksum 文件名替换的文件类型。
- customHash- 指定了值的时候,追加到指纹文件名而不用 MD5。用- null可以取代 hash,在用- prepend的时候非常有用。
作为一个例子,这个 ember-cli-build 会给除了 fonts/169929 文件夹的所有资源文件都加上一个云前端域名。
| 1 | // ember-cli-build.js | 
最终的结果:
| 1 | <script src="assets/appname.js"> | 
会变成
| 1 | <script src="https://subdomain.cloudfront.net/assets/appname-342b0f87ea609e6d349c7925d86bd597.js"> | 
在 ember-cli-build.js 里你可以禁用指纹算法:
| 1 | // ember-cli-build.js | 
或者直接删除你 package.json 的 EmberApp 和  broccoli-asset-rev。
应用配置
你 ember-cli-build.js 里的应用配置会被存在 dist/index.html 一个特殊的 meta tag里。
meta tag的例子
| 1 | <meta name="user/config/environment" content="%7B%22modulePre.your.config"> | 
这个 meta tag 要求你的 ember 应用正常运行。如果你希望这个 tag 是你编译 js 文件的一部分,你可能需要在 ember-cli-build.js 里用 storeConfigInMeta 标记。
| 1 | // ember-cli-build.js | 
编辑输出路径
编译文件会输出到下面的路径:
| 资源 | 输出文件 | 
|---|---|
| app/index.html | /index.html | 
| app/*.js | /assets/application-name.js | 
| app/styles/app.css | /assets/application-name.css | 
| 其他在 app/styles的 CSS 文件 | 同样的文件到 /assets | 
| 用 app.import()引入的 JS 文件 | /assets/vendor.js | 
| 用 app.import()引入的 CSS 文件 | /assets/vendor.css | 
想要改变这些路径,指定 outputPaths 配置选项。默认的选项:
| 1 | // ember-cli-build.js | 
你可以改变这些路径,但是确保更新在 app.outputPaths.app.html 里的路径,它默认是 index.html 和 tests/index.html。如果没改对,你的 app 无法正常的识别资源文件。
| 1 | // ember-cli-build.js | 
outputPaths.app.css选项用了一个 kv 对。key 是输入文件,value 是输出路径。注意,我们不需要包括扩展名,因为每个预处理器有不同的扩展名。
使用 CSS 预处理器的时候,只有 app/styles/app.scss (or .less etc) 被编译了。如果你需要处理多个文件,你需要加另一个 key:
| 1 | // ember-cli-build.js | 
集成
当 ember 是在另一个项目内的时候,你可能只有一个特定路由的时候想要加载 ember。如果你提前加载了 ember 的 JS 文件,你需要禁用 autoRun:
| 1 | // ember-cli-build.js | 
手动跑Ember:require("app-name/app")["default"].create({/* app settings */});
子资源完整性
子资源完整性 SRI integrity 计算由插件 ember-cli-sri 完成(默认被包含。
子资源完整性是一个安全性概念,用来检查 JS 和样式用了 CDN 之后是不是有正确的内容。
为什么
添加这个到你的应用是问了防止 CDNs 被劫持,从而改变你的 JS 或者 CSS。
- JavaScript DDoS 预防
- 防治不够信任的服务器的被污染代码
定制
定制 SRI 器:ember-cli-sri
依赖管理
NPM 和 Bower 配置
Ember CLI 支持 NPM 和 Bower 管理依赖。
一个 Ember CLI 生成的项目只有 NPM 依赖,你会发现 package.json 文件在你的工程根目录,没有 bower.json。
为了用 Bower,你需要用 bower init 来创建 bower.json 文件。
NPM 的 package.json 加上 Bower 的 bower.json 允许你声明你的依赖。改变你的依赖需要管理这俩文件,而不是手动的装包。
执行 npm install 会一键安装 package.json 里的依赖。同样的,执行 bower install 会一键安装 bower.json 里的依赖。
Ember CLI 默认配置了 git 忽略你的 bower_components 和node_modules 文件夹。
Ember CLI 监控 bower.json 的改变,因此会重新加载你的应用,如果你通过 bower install <dependencies> --save装了新东西。如果你通过 npm install <dependencies> --save装东西,需要重启。
通过官方文档可以了解更多:
注意,一般装东西用 ember install 是最容易的,它会保存所有的依赖到正确的文件,然后运行需要的步骤。
编译资源
Ember CLI 用 Broccoli 。
资源清单在工程根目录的 ember-cli-build.js(不是默认的ember-cli-build.js).
为了加一个资源,在你调用 app.toTree() 之前指定依赖的资源到你的 ember-cli-build.js。你只能引入在 bower_components 或者 vendor 目录里的资源。以下示例场景说明了这是如何工作的。
Javascript 资源
标准 Non-AMD 资源
首先,提供资料路径,作为唯一的参数
| 1 | app.import('bower_components/moment/moment.js'); | 
文档指定的包,通常是全局变量。这个例子里:
| 1 | import Ember from 'ember'; | 
注意: 不要忘了 ESLint,加 /* global MY_GLOBAL */ 到你的模块,或者在 .eslintrc.js 的 globals 部分里定义。
另一种选择是你可以生成一个 ES6 shim,让库可以通过 import 引入。
首先,生成这个shim:
| 1 | ember generate vendor-shim moment | 
然后,提供 vendor 资源路径:
| 1 | app.import('vendor/shims/moment.js'); | 
最后,使用这个包,添加合适的 import 语句:
| 1 | import moment from 'moment'; | 
标准 AMD 资源
提供资源路径作为第一个参数,模块和导出列表作为第二个:
| 1 | app.import('bower_components/ic-ajax/dist/named-amd/main.js'); | 
引入资源。比如,ic-ajax, 使用的时候 ic.ajax.raw:
| 1 | import { raw as icAjaxRaw } from 'ic-ajax'; | 
标准匿名 AMD 资源
提供资源路径作为第一个参数,目标模块作为第二个:
| 1 | app.import('bower_components/ic-ajax/dist/amd/main.js', { | 
为了用资源而导入。比如,ic-ajax, 使用的时候 ic.ajax.raw:
| 1 | import { raw as icAjaxRaw } from 'ic-ajax'; | 
环境指定资源
如果你在不同的环境需要用不同的资源,指定一个对象作为第一个参数。对象的 key 应该是环境的名字,value 是应该使用的资源文件。
| 1 | app.import({ | 
如果你需要引入一个资源,在某个环境,但是其他环境不想引入它,你可以用 app.import,然后用 if 把它包起来。
| 1 | if (app.env === 'development') { | 
定制内置资源文件
这是不标准的方式,但是因为你可能需要用全部的handlebar版本,甚至在生产环境也是,所以支持这种方式。
你应该提供一个简单的路径给你的 EmberApp 构造器:
| 1 | var app = new EmberApp({ | 
另一种选择是,如果你想避免内置资源自动加载到 vendor.js,你可以把这个值设为 false:
| 1 | var app = new EmberApp({ | 
注意: 跑你的程序需要某些内置资源的依赖。如果你用上面的方法去指定排除某些东西,你应该用其他方法再重新引入。
资源文件黑白名单
你可以限制哪些依赖运行或者不允许被导入到你的 Ember 应用,通过 EmberApp 的构造器选项。
| 1 | var app = new EmberApp({ | 
测试 Assets
你在跑测试的时候也许有其他的库(例如 qunit-bdd or sinon)。
| 1 | // ember-cli-build.js | 
注意:
- 确保你传递 { type: 'test' }作为app.import的第二个参数。这可以确保你的库被编译成test-support.js文件。
样式
静态 CSS
资源文件作为第一个参数:
| 1 | app.import('bower_components/foundation/css/foundation.css'); | 
所有这样添加的的样式资源会被合并成一个文件 /assets/vendor.css。
动态样式 (SCSS, LESS, etc)
自动生成的树通过实例化提供了可用的动态样式文件。例子如下(在 app/styles/app.scss 里):
| 1 | @import "bower_components/foundation/scss/normalize.scss"; | 
其他资源
使用 app.import()
所有的其他资源,如字体图片,可用被 import() 引入。默认他们会被拷贝到 dist/ 文件夹。
| 1 | app.import('bower_components/font-awesome/fonts/fontawesome-webfont.ttf'); | 
这个例子会创建一个字体在 dist/font-awesome/fonts/fontawesome-webfont.ttf。
你可以选择告诉 import() 把文件放到一个不同的地方。这个例子是把文件拷贝到 dist/assets/fontawesome-webfont.ttf。
| 1 | app.import('bower_components/font-awesome/fonts/fontawesome-webfont.ttf', { | 
如果你需要在其他资源之前加载某个依赖,你可以设置 prepend 属性为 true 在 import() 的第二格参数。这会预加载依赖到生成目录而不是按默认行为追加。
| 1 | app.import('bower_components/es5-shim/es5-shim.js', { | 
如果你需要某个资源加载到某个特定文件。你可以提供一个 outputFile 选项给你的导入:
| 1 | // ember-cli-build.js | 
作为结果,两个资源会按它们的制定顺序合并成一个到 dist/assets/additional-script.js。
主要: outputFile 只能被 javascript 和 css 文件使用。
使用 broccoli-funnel
有了 broccoli-funnel,部分 bower 安装的包可以被用作 as-is 资源。首先确认 Broccoli 包已经装好。
| 1 | npm install broccoli-funnel --save-dev | 
添加这个引用到 ember-cli-build.js 的头部:
| 1 | var Funnel = require('broccoli-funnel'); | 
在 ember-cli-build.js 里,我们把资源从一个 bower 依赖和主程树合并:
| 1 | module.exports = function(defaults) { | 
在上面的例子,这些资源从叫做 a-lovely-webfont 的虚构 bower 依赖调用,现在可以在 /assets/fonts/ 里找到,可能被关联到 index.html。像这样:
| 1 | <link rel="stylesheet" href="assets/fonts/lovelyfont_bold/stylesheet.css"> | 
你可以把这些资源从最终的输出移除,用相似的方式。比如,在输出中排除所有的 .gitkeep 文件:
| 1 | // 又一次,添加这个引用到 `ember-cli-build.js` 的头部 | 
注意: broccoli-static-compiler 已经废弃了。使用 broccoli-funnel。