使用 Yeoman 和 Polymer 构建 Web 应用程序:使用现代工具构建您的 Web 应用程序
介绍
任何编写 Web 应用程序的人都知道保持自己的工作效率是多么重要。 当您不得不担心繁琐的任务(例如找到合适的样板文件、设置开发和测试工作流程以及缩小和压缩所有源代码)时,这是一个挑战。
幸运的是,现代前端工具可以帮助实现大部分自动化,让您专注于编写出色的应用程序。 本文将向您展示如何使用 Yeoman ,这是一个用于 Web 应用程序的工具工作流,用于简化使用 Polymer 开发应用程序的 polyfills 和 sugar 库 创建应用程序的过程,Polymer 是一个用于使用Web 组件 。
注意: 如果您是 Web 组件的新手,我建议您阅读 的精彩文档 有关它们提供的 Web 平台功能 。 有关如何通过 Polymer 使用它们的指南可用于 自定义元素 、 Shadow DOM 、 HTML 导入 等。
认识 Yo、Grunt 和 Bower
Yeoman 是一位戴帽子的人,拥有三种提高工作效率的工具:
- yo 是一个脚手架工具,它提供特定于框架的脚手架生态系统,称为生成器,可用于执行我之前提到的一些繁琐任务。
- 策划的任务的帮助, grunt 得益于 Yeoman 团队和 grunt-contrib 用于构建、预览和测试您的项目。
- bower 用于依赖管理,让你不再需要手动下载和管理你的脚本。
只需一两个命令,Yeoman 就可以为您的应用程序(或像模型这样的单独部分)编写样板代码,编译您的 Sass,最小化和连接您的 CSS、JS、HTML 和图像,并在您的当前目录中启动一个简单的 Web 服务器。 它还可以运行您的单元测试等等。
您可以从 npm( Node Packaged Modules )安装生成器,现在有超过 220 个生成器 可用,其中许多是由开源社区编写的。 流行的生成器包括 generator-angular 、 generator-backbone 和 generator-ember 。
安装最新版本的 Node.js 后,前往最近的终端并运行:
$ npm install -g yo
而已! 您现在拥有 Yo、Grunt 和 Bower,并且可以直接从命令行运行它们。 这是运行的输出 yo
:
如果您想开始使用常规的新 Web 应用程序,您现在可以安装 generator-webapp
通过 npm install -g generator-webapp
.
注意: 如果您有兴趣阅读更多有关如何使用 Yeoman 使用其他框架(如 Backbone)编写完整应用程序的信息,您可能会对 使用 Yeoman 工作流构建应用程序 感兴趣。
聚合物发生器
正如我之前提到的,Polymer 是一个 polyfill 和 sugar 库,它支持在现代浏览器中使用 Web 组件。 该项目允许开发人员使用未来平台构建应用程序,并告知 W3C 可以进一步改进飞行规范的地方。
generator-polymer 是一种新的生成器,可帮助您使用 Yeoman 构建 Polymer 应用程序,让您通过命令行轻松创建和自定义 Polymer(自定义)元素,并使用 HTML Imports 导入它们。 通过为您编写样板代码,这可以节省您的时间。
接下来,通过运行安装 Polymer 的生成器:
$ npm install generator-polymer -g
而已。 现在您的应用程序拥有 Web Component 的超能力!
我们新安装的生成器有一些您可以访问的特定位:
polymer:element
用于构建新的单个 Polymer 元素。 例如:yo polymer:element carousel
polymer:app
用于搭建初始 index.html 的脚手架,这是一个 Gruntfile.js,其中包含项目的构建时配置以及 Grunt 任务和为项目推荐的文件夹结构。 它还将为您提供为项目样式使用 Sass Bootstrap 的选项。
让我们构建一个 Polymer 应用程序
我们将使用一些自定义的 Polymer 元素和我们的新生成器来构建一个简单的博客。
首先,转到终端,创建一个新目录并使用 cd 进入它:
mkdir my-new-project && cd $_
您现在可以通过运行以下命令来启动您的 Polymer 应用程序:
$ yo polymer
它还会询问您是否要包含 Twitter Bootstrap。 决定后,只需按 Enter。
这会从 Bower 获取最新版本的 Polymer,并为您的工作流程构建 index.html、目录结构和 Grunt 任务。 为什么不在我们等待应用程序完成准备时喝杯咖啡呢?
好的,接下来我们可以运行 grunt server
预览应用程序的外观:
服务器支持 LiveReload,这意味着您可以启动文本编辑器,编辑自定义元素,浏览器将在保存时重新加载。 这使您可以很好地实时查看应用程序的当前状态。
接下来,让我们创建一个新的 Polymer 元素来表示博客文章。
$ yo polymer:element post
Yeoman 问了我们几个问题,比如我们是想包含构造函数还是使用 HTML Import 来包含 post 元素 index.html
. 让我们暂时对前两个选项说“否”,将第三个选项留空。
注意: 如果我们对第二个问题回答“是”,生成器将导入 post.html 并将其包含在 index.html 中。 它还声明了 <post-element> 以便元素在页面加载时呈现。
$ yo polymer:element post
[?] Would you like to include constructor=''? No
[?] Import to your index.html using HTML imports? No
[?] Import other elements into this one? (e.g 'another_element.html' or leave blank)
create app/elements/post.html
这将创建一个新的 Polymer 元素 /elements
名为 post.html 的目录:
<polymer-element name="post-element" attributes="">
<template>
<style>
@host { :scope {display: block;} }
</style>
<span>I'm <b>post-element</b>. This is my Shadow DOM.</span>
</template>
<script>
Polymer('post-element', {
//applyAuthorStyles: true,
//resetStyleInheritance: true,
created: function() { },
enteredView: function() { },
leftView: function() { },
attributeChanged: function(attrName, oldVal, newVal) { }
});
</script>
</polymer-element>
它包含:
使用真实的数据源
我们的博客需要一个地方来撰写和阅读新帖子。 为了演示如何使用真实的数据服务,我们将使用 Google Apps Spreadsheets API 。 这使我们能够轻松读取使用 Google 文档创建的任何电子表格的内容。
让我们设置一下:
在您的浏览器中(对于这些步骤,推荐使用 Chrome)打开 此 Google 文档电子表格。 它包含以下字段下的示例发布数据:
- ID
- 标题
- 作者
- 内容
- 日期
- 关键字
- 电子邮件(作者)
- Slug(用于您帖子的 slug URL)
转到“ 文件 ”菜单并选择 “制作副本 ”以创建您自己的电子表格副本。 您可以随意编辑内容,添加或删除帖子。
转到“ 文件 再次 ”菜单并选择“发布到网络” 。
点击 开始发布
在 获取已发布数据的链接下 ,从最后一个文本框中复制提供的 URL 的 关键 部分。 它看起来像这样: https ://docs.google.com/spreadsheet/ccc?key=0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc
粘贴 将密钥 到以下 URL 中,其中显示 your-key-goes-here : https ://spreadsheets.google.com/feeds/list/your-key-goes-here/od6/public/values?alt=json-在脚本&回调= 。 使用上述密钥的示例可能类似于 https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc/od6/public/values?alt=json-in-script 。
您可以将该 URL 粘贴到您的浏览器中并导航到它以查看您的博客内容的 JSON 版本。 记下 URL,然后花一点时间查看此数据的格式,因为您需要对其进行迭代以便稍后在屏幕上显示它。
浏览器中的 JSON 输出可能看起来有点令人生畏,但别担心! 我们真的只对您帖子的数据感兴趣。
Google Spreadsheets API 输出博客电子表格中的每个字段都带有特殊前缀 post.gsx$
. 例如: post.gsx$title.$t
, post.gsx$author.$t
, post.gsx$content.$t
等等。 当我们遍历 JSON 输出中的每个“行”时,我们将引用这些字段以获取每个帖子的相关值。
您现在可以编辑新构建的 post 元素,以 绑定 将部分标记 到电子表格中的数据。 为此,我们引入一个属性 post
,它将读取我们之前创建的帖子标题、作者、内容和其他字段。 这 selected
属性(我们将在稍后填充)用于仅在用户导航到正确的 slug 时显示帖子。
<polymer-element name="post-element" attributes="post selected">
<template>
<style>
@host { :scope {display: block;} }
</style>
<div class="col-lg-4">
<template if="{{post.gsx$slug.$t === selected}}">
<h2>
<a href="#{{post.gsx$slug.$t}}">
{{post.gsx$title.$t }}
</a>
</h2>
<p>By {{post.gsx$author.$t}}</p>
<p>{{post.gsx$content.$t}}</p>
<p>Published on: {{post.gsx$date.$t}}</p>
<small>Keywords: {{post.gsx$keywords.$t}}</small>
</template>
</div>
</template>
<script>
Polymer('post-element', {
created: function() { },
enteredView: function() { },
leftView: function() { },
attributeChanged: function(attrName, oldVal, newVal) { }
});
</script>
</polymer-element>
接下来,让我们通过运行创建一个博客元素,其中包含帖子集合和博客布局 yo polymer:element blog
.
$ yo polymer:element blog
[?] Would you like to include constructor=''? No
[?] Import to your index.html using HTML imports? Yes
[?] Import other elements into this one? (e.g 'another_element.html' or leave blank) post.html
create app/elements/blog.html
这次我们使用 HTML 导入将博客导入到 index.html 中,因为我们希望它出现在页面中。 对于第三个提示,我们指定 post.html
作为我们想要包含的元素。
和以前一样,创建一个新的元素文件 (blog.html) 并添加到 /elements,这次导入 post.html 并包含 在模板标签内:
<link rel="import" href="post.html">
<polymer-element name="blog-element" attributes="">
<template>
<style>
@host { :scope {display: block;} }
</style>
<span>I'm <b>blog-element</b>. This is my Shadow DOM.</span>
<post-element></post-element>
</template>
<script>
Polymer('blog-element', {
//applyAuthorStyles: true,
//resetStyleInheritance: true,
created: function() { },
enteredView: function() { },
leftView: function() { },
attributeChanged: function(attrName, oldVal, newVal) { }
});
</script>
</polymer-element>
当我们要求使用 HTML 导入 (一种在其他 HTML 文档中包含和重用 HTML 文档的方法)将 blog 元素导入到我们的索引中时,我们还可以验证它是否已正确添加到文档中 <head>
:
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="styles/main.css">
<!-- build:js scripts/vendor/modernizr.js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
<!-- Place your HTML imports here -->
<link rel="import" href="elements/blog.html">
</head>
<body>
<div class="container">
<div class="hero-unit">
<blog-element></blog-element>
</div>
</div>
<script>
document.addEventListener('WebComponentsReady', function() {
// Perform some behaviour
});
</script>
<!-- build:js scripts/vendor.js -->
<script src="bower_components/polymer/polymer.min.js"></script>
<!-- endbuild -->
</body>
</html>
极好的。
使用 Bower 添加依赖项
接下来,让我们编辑我们的元素以使用 Polymer JSONP 实用程序元素读取 posts.json。 您可以通过 git 克隆存储库或安装来获取适配器 polymer-elements
通过 Bower 运行 bower install polymer-elements
.
一旦你有了这个实用程序,你需要将它作为导入包含在你的 blog.html 元素中:
<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">
接下来,包括它的标签并提供 url
到我们之前的博客文章电子表格中,添加 &callback=
到最后:
<polymer-jsonp auto url="https://spreadsheets.google.com/feeds/list/your-key-value/od6/public/values?alt=json-in-script&callback=" response="{{posts}}"></polymer-jsonp>
注意: 如果您发现自己卡住了,请随时使用我的电子表格 https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc/od6/public/values?alt=json-in-script 作为您的 URL 的值您可以继续本教程。
有了这个,我们现在可以添加模板来迭代我们的电子表格,一旦它被读入。第一个输出一个目录,一个帖子的链接标题指向它的 slug。
<!-- Table of contents -->
<ul>
<template repeat="{{post in posts.feed.entry}}">
<li><a href="#{{post.gsx$slug.$t}}">{{post.gsx$title.$t}}</a></li>
</template>
</ul>
第二个呈现一个实例 post-element
对于找到的每个条目,将帖子内容相应地传递给它。 请注意,我们正在通过 post
表示单个电子表格行和一个帖子内容的属性 selected
我们将用路由填充的属性。
<!-- Post content -->
<template repeat="{{post in posts.feed.entry}}">
<post-element post="{{post}}" selected="{{route}}"></post-element>
</template>
这 repeat
您在我们的模板中看到的属性会为我们帖子的数组集合中的每个元素创建并维护一个带有 {{ bindings }} 的实例(当提供时)。
现在,为了让我们填充当前的 {{route}},我们将作弊并使用一个名为 Flatiron director 的库,它会在 URL 哈希更改时绑定到 {{route}}。
值得庆幸的是 一个Polymer 元素 ( more-elements ,我们可以获取 包的一部分)。 复制到 /elements 目录后,我们可以使用 <flatiron-director route="{{route}}" autoHash></flatiron-director>
, 指定 route
作为我们希望绑定的属性,并告诉它自动读取任何哈希更改的值 (autoHash)。
把所有东西放在一起我们现在得到:
<link rel="import" href="post.html">
<link rel="import" href="polymer-jsonp/polymer-jsonp.html">
<link rel="import" href="flatiron-director/flatiron-director.html">
<polymer-element name="blog-element" attributes="">
<template>
<style>
@host { :scope {display: block;} }
</style>
<div class="row">
<h1><a href="/#">My Polymer Blog</a></h1>
<flatiron-director route="{{route}}" autoHash></flatiron-director>
<h2>Posts</h2>
<!-- Table of contents -->
<ul>
<template repeat="{{post in posts.feed.entry}}">
<li><a href="#{{post.gsx$slug.$t}}">{{post.gsx$title.$t}}</a></li>
</template>
</ul>
<!-- Post content -->
<template repeat="{{post in posts.feed.entry}}">
<post-element post="{{post}}" selected="{{route}}"></post-element>
</template>
</div>
<polymer-jsonp auto url="https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdHVQUGd2M2Q0MEZnRms3c3dDQWQ3V1E/od6/public/values?alt=json-in-script&callback=" response="{{posts}}"></polymer-jsonp>
</template>
<script>
Polymer('blog-element', {
created: function() {},
enteredView: function() { },
leftView: function() { },
attributeChanged: function(attrName, oldVal, newVal) { }
});
</script>
</polymer-element>
哇! 我们现在有一个简单的博客,它从 JSON 读取数据并使用两个由 Yeoman 搭建的 Polymer 元素。
使用第 3 方元素
围绕 Web Components 的元素生态系统最近一直在发展,像 customelements.io 这样的组件库网站开始出现。 通过查看社区创建的元素,我找到了一个用于获取 Gravatar 配置文件 的元素,我们实际上也可以获取并将其添加到我们的博客站点。
将 gravatar 元素源复制到您的 /elements
目录,通过 post.html 中的 HTML 导入将其包含,然后添加 到您的模板,将电子表格中的电子邮件字段作为用户名的来源传递。 繁荣!
<link rel="import" href="gravatar-element/src/gravatar.html">
<polymer-element name="post-element" attributes="post selected">
<template>
<style>
@host { :scope {display: block;} }
</style>
<div class="col-lg-4">
<template if="{{post.gsx$slug.$t === selected}}">
<h2><a href="#{{post.gsx$slug.$t}}">{{post.gsx$title.$t}}</a></h2>
<p>By {{post.gsx$author.$t}}</p>
<gravatar-element username="{{post.gsx$email.$t}}" size="100"></gravatar-element>
<p>{{post.gsx$content.$t}}</p>
<p>{{post.gsx$date.$t}}</p>
<small>Keywords: {{post.gsx$keywords.$t}}</small>
</template>
</div>
</template>
<script>
Polymer('post-element', {
created: function() { },
enteredView: function() { },
leftView: function() { },
attributeChanged: function(attrName, oldVal, newVal) { }
});
</script>
</polymer-element>
让我们来看看这给了我们什么:
美丽的!
在相对较短的时间内,我们创建了一个由多个 Web 组件组成的简单应用程序,而无需担心编写样板代码、手动下载依赖项或设置本地服务器或构建工作流。
优化您的应用程序
的开源项目 Yeoman 工作流包括另一个名为Grunt - 一个任务运行器,可以运行许多特定于构建的任务(在 Gruntfile 中定义)以生成应用程序的优化版本。 跑步 grunt
自己会执行一个 default
生成器为 linting、测试和构建设置的任务:
grunt.registerTask('default', [
'jshint',
'test',
'build'
]);
这 jshint
上面的任务将与您核实 .jshintrc
文件以了解您的偏好,然后针对项目中的所有 JavaScript 文件运行它。 要使用 JSHint 全面了解您的选项,请查看 文档 。
这 test
任务看起来有点像这样,可以为我们推荐的开箱即用的测试框架 Mocha 创建和提供您的应用程序。 它还将为您执行测试:
grunt.registerTask('test', [
'clean:server',
'createDefaultTemplate',
'jst',
'compass',
'connect:test',
'mocha'
]);
由于我们的应用程序在这种情况下相当简单,我们将把编写测试作为一个单独的练习留给您。 我们还需要一些其他的东西来让我们的构建过程处理,所以让我们来看看 grunt build
我们定义的任务 Gruntfile.js
会做:
grunt.registerTask('build', [
'clean:dist', // Clears out your .tmp/ and dist/ folders
'compass:dist', // Compiles your Sassiness
'useminPrepare', // Looks for <!-- special blocks --> in your HTML
'imagemin', // Optimizes your images!
'htmlmin', // Minifies your HTML files
'concat', // Task used to concatenate your JS and CSS
'cssmin', // Minifies your CSS files
'uglify', // Task used to minify your JS
'copy', // Copies files from .tmp/ and app/ into dist/
'usemin' // Updates the references in your HTML with the new files
]);
跑 grunt build
并且应该构建您的应用程序的生产就绪版本,以供您发布。 让我们试试看。
如果您遇到困难,可以使用预构建版本的 polymer-blog 查看 https://github.com/addyosmani/polymer-blog 。
注意: 用户在使用 Yeoman、Grunt 和 Bower 时遇到的最常见问题与没有足够的管理员权限有关。 请确保您已遵循 推荐 的 Node 和 NPM 安装步骤。
我们还有什么存货?
Web Components 仍处于进化状态,围绕它们的工具也是如此。
我们目前正在研究如何通过 Vulcanize (Polymer 项目的一个工具)等项目连接他们的 HTML 导入以提高加载性能,以及组件的生态系统如何与 Bower 这样的包管理器一起工作。
当我们对这些问题有更好的答案时,我们会通知您,但未来还有许多激动人心的时刻。
使用 Bower 独立安装 Polymer
如果您更喜欢 Polymer 更轻便的启动,您可以通过运行以下命令直接从 Bower 独立安装它:
bower install polymer
这会将它添加到您的 bower_components 目录中。 然后您可以在您的应用程序索引中手动引用它并引领未来。
你怎么看?
现在您知道了如何使用 Web 组件和 Yeoman 构建 Polymer 应用程序的脚手架。 如果您对生成器有任何反馈,请在评论中告诉我们,或者提交错误或发布到 Yeoman 问题跟踪器 。 我们很想知道您是否希望看到生成器做得更好,因为只有通过您的使用和反馈,我们才能改进。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Web 开发人员的文本压缩
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论