使用Yeoman和Polymer创建Web应用

Yeoman-polymer-教程

  Allo’Allo’。大多数人都很清楚高效的Web应用开发有多重要。在你进行某些乏味的项目开发时,你会因为各种令你头痛的事情而感到焦虑、烦躁,比如寻找项目模板、配置项目基础架构、开发环境、测试环境以及后续的项目优化和压缩。这种枯燥乏味如流水线般的事情,偶尔一次还好,但如果周而复始的进行类似的项目,你的脑袋不会炸掉才怪!

  幸运的是,有一些先进的前端工具能帮我们自动化完成这些事情,让我们远离乏味的流水线工作,将更多的精力放在核心功能编码上面。本文会向你展示如何使用Yeoman和Polymer高效完成这些任务,Yeoman用来自动化创建Web应用工作流,而Polymer则是由加盟Google的原Palm webOS开发团队打造的一个前端库,其基于Shadow DOM、Custom Elements、MDV等最新浏览器特性,使用Web Components来填充和装饰Web应用。

您还可以参考以下前端技术相关文章:
使用CSS3开启GPU硬件加速提升网站动画渲染性能
人人网首页拖拽上传详解(HTML5 Drag&Drop、FileReader API、formdata)
关于HTML 5 canvas 的基础教程
精选15个国外CSS框架

本文翻译自英文原文《Building Web Apps With Yeoman And Polymer》,由于英文原文内容很多API和方法已更新,所以彬GO在这里翻译的同时做了较大幅度改动和更新,如有错误欢迎指正;)

声明:
本文涉及的一部分API到目前仍未完全标准化且未来可能会略有变动。在使用这些实验性API前请谨慎评估你的开发项目。

yeoman

注意:如果你之前从未了解过Web Components,建议你先去读一读他们提供的关于Web平台特性的文档。其会指导你如何使用基于Custom Elements, Shadow DOM, HTML Imports等特性的的Polymer。如果你英文不太好,也可以看看这篇文章《自定义元素–为你的HTML代码定义新元素》。

彬Go:下文中会多次提到”元素(element)”这个词,大家看到时可能会与自己概念里的元素(html标签)有些冲突,因为这里提到的有些元素是可以独立成文件来引用的,实际这就是Polymer的理念——一切皆组件,希望通过各种自定义元素(组件)来组成一个完整的Web应用,所以在下文中,如果你看到”元素”但无法理解,可以尝试将其理解为”组件”。

yeoman-banner-wide

Yeoman的三大成员:Yo、Grunt和Bower

Yeoman就是那个头戴礼帽装备三大武器帮你解决开发效率的人:

  • yo : 为你完成项目系统框架和基础结构搭建工作的”脚手架”工具,它就是用来解决我之前提到的那些枯燥乏味流水线工作的工具,也可以算是项目架构生成器。
  • grunt:用来创建、预览和测试你的项目,这里要感谢Yeoman团队和grunt-contrib的合作策划。
  • bower:类似于Node.js的项目脚本依赖管理,这样你就不必再手动下载和管理你项目的脚本文件了。

你仅仅需要输入一两行命令,Yeoman就能帮你搞定项目的整体框架模板的搭建任务(或个别需要配置的模块),编译你的Sass代码,压缩与合并你的CSSJavaScriptHTML以及图片,然后在当前项目目录帮你架设一个简单的Web服务以便随时通过浏览器访问,他甚至还能执行单元测试或更多你想不到的任务。

你可以通过npm(Node.js打包模块)安装超过570种生成器,有很多都是开源的,其中最有名的生成器包括generator-angular, generator-backbonegenerator-ember

yeoman-yo-grunt-bower-教程

如果安装过新版Node.js,在命令行输入并执行以下命令来安装yo

npm install -g yo

如果你还没有安装grunt和bower,也需要一起安装

npm install -g grunt-cli bower

就这么简单,现在你可以直接在命令行执行Yo、Grunt和Bower,下面是执行yo的输出:

yeoman-yo-grunt-bower-教程

选择”Install a genarator”之后,会询问你需要安装什么生成器,假如你希望创建一个常规的Web应用,可以输入”generator-webapp”并回车:

然后选择对应的生成器回车即可开始安装。

还有另一种方法安装生成器,就在在命令行直接输入:

npm install -g generator-webapp

注意:如果你想了解如何使用Yeoman创建基于类似Backbone.js这类框架的Web应用,你可以看看《Building Apps With The Yeoman Workflow

Polymer生成器

像我之前提到的,Polymer就是用来为支持Web Components的现代浏览器填充和装饰的前端库。

yeoman-yo-grunt-bower-教程

generator-polymer是可以帮助你使用Yeoman架起Polymer应用的新生成器。你可以通过命令行轻松创建以及自定义Polymer元素(自定义元素),还可以使用HTML Imports导入这些自定义元素。这种生成Web应用模板的方式会为你节省很多时间。

我们可以通过上面讲过的两种方法的任意一种来安装Polymer,下面是命令行安装Polymer生成器:

npm install generator-polymer -g

OK,现在你的项目已经支持Web Components了!

我们刚刚安装的生成器有一些特性你可能会用到:

  • polymer:element 用来创建新的特定的Polymer元素,如:yo polymer:element carousel
  • polymer:app 用来为你架设初始index.html。Gruntfile.js包含项目创建配置。它还为你项目样式使用Sass Bootstrap提供一些设置项。

开始创建一个Polymer应用:

我们要使用一些自定义Polymer元素和我们的新生成器创建一个简易的博客。

yeoman-yo-grunt-bower-教程

>> Blog Demo 预览 <<(使用了Google服务,如无法预览,则需翻墙)

首先,在命令行创建一个新目录并进入这个目录:

yeoman-yo-grunt-bower-教程

现在可以通过下面命令启动Polymer:

yo polymer

它会询问你是否希望包含Twitter Bootstrap,如果你希望,按回车键即可.
这是通过Bower依赖的最新版本Polymer为我们项目工作流架设的index.html、目录结构和Grunt任务。现在你可以悠闲地喝杯咖啡等待应用初始化完毕^_^

OK,初始化完毕之后,命令行执行”grunt server”,然后就可以在浏览器看到如下样子:

yeoman-yo-grunt-bower-教程

注意:如果执行”grunt server”时有报错,请先检查是否已安装compass和sass,已安装compass和sass却报错”897 permission denied”类似问题,可能是因为compass和sass版本问题导致,可以命令行卸载并安装较早版本即可解决:

gem uninstall sass
gem uninstall compass
gem install compass --pre
gem install sass --pre

服务支持实时更新,意思就是你可以在编辑器中编码,然后浏览器会在你保存的同时自动刷新页面。这会让你实时的看到网页的变化,而不用苦逼的不停手动刷新页面。

下面,我们来创建一个展示博客文章的新Polymer元素。

yo polymer:element post

yeoman-yo-grunt-bower-教程

Yeoman会询问你一些诸如是否希望包含constructor或使用HTML import将post元素导入index.html的问题,现在只需要统统回答No即可(即不勾选复选框),而在第三个问题空格跳过。

注意:如果你在第二个问题回答”Yes”,生成器便会导入post.html并将其包含在index.html中。它还会声明以便在页面load时渲染这个元素。

yo polymer:element post

[?] Would you like to include constructor=''? No

[?] Import to your index.html using HTML imports? No

[?] Import local elements into this one? (e.g 'a.html b.html' or leave blank)

   create app/elements/post.html

这个新创建的Polymer元素已经命名为post.html,在/elements目录中。

<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 Docs创建的任何数据表。

下面是安装步骤
1. 用你的浏览器(建议使用Chrome)打开这个Google Docs数据表,它包含如下文章数据样本:

  • ID
  • Title
  • Author
  • Content
  • Date
  • Keywords
  • E-mail
  • Slug
  • link

2. 点击菜单栏”文件“按钮,然后选择”制作副本”来创建你自己的数据表副本。你可以在你有空时免费编辑内容、添加或删除post。

3. 再次点击菜单栏”文件“按钮并选择”发布到网络

4. 点击”开始发布

5. 在”获取已发布数据的链接“下面,有一长串链接,你需要找到URL中参数Key的值对应的字符串像这样:https://docs.google.com/spreadsheet/pub?key=0Ao_bIaw69jI1dHhmVkU1dnpfMHdOMXJjTDFIbnFxbmc&output=html
找出的Key是:0Ao_bIaw69jI1dHhmVkU1dnpfMHdOMXJjTDFIbnFxbmc

6. 将你的Key值字符串粘贴到下面链接中替换”your-key-gose-here“:
https://spreadsheets.google.com/feeds/list/your-key-goes-here/od6/public/values?alt=json-in-script&callback=,
粘贴完的链接是这样:
https://spreadsheets.google.com/feeds/list/0Ao_bIaw69jI1dHhmVkU1dnpfMHdOMXJjTDFIbnFxbmc/od6/public/values?alt=json-in-script

7. 用浏览器打开这个链接看看你博客内容的JSON数据。把URL留作记录然后花点时间看一看这些数据,以后你需要反复的在屏幕上显示这些数据。

在浏览器上输出的这些JSON可能会让你看第一眼就怵头再看下去,不过别担心,咱只对post相关的数据感兴趣。

Google数据表API输出你博客数据表中每段数据域都有一个特殊前缀 post.gsx$ 。例如: post.gsx$title.$tpost.gsx$author.$tpost.gsx$content.$t 以此类推。当我们反复查看输出的JSON的每一行,我们就可以通过锁定这些前缀字段来快速获取相应数据。

现在你可以开始为你之前新架起的post元素绑定来自Google数据表的数据了。在这我要介绍一下属性post,它可以读取post的title、author、content和其它我们之前创建的数据字段。selected属性(以后会经常用到)用来显示用户导航到相应链接对应的post。

<polymer-element name="polymer-post" 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('polymer-post', {

      created: function() { },

      enteredView: function() { },

      leftView: function() { },

      attributeChanged: function(attrName, oldVal, newVal) { }

    });

  </script>

</polymer-element>

下面,我们来通过下面的命令创建一个blog元素,它会包含post集合和你博客的布局信息:

yo polymer:element blog

[?] Would you like to include constructor=''? No

[?] Import to your index.html using HTML imports? Yes

[?] Import local elements into this one? (e.g "a.html b.html" or leave blank) post.html

[?] Import installed Bower elements? (e.g "polymer-ajax" or leave blank)

这时我们使用HTML imports来将blog导入到index.html以便让它在页面中展示。在第三个选项,我们指定其为post.html。

我们先是创建了一个新的元素文件(blog.html)并把它添加到/elements目录,现在将post.html导入并放到template标签中:

<link rel="import" href="post.html">

<polymer-element name="polymer-blog"  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('polymer-blog', {

      //applyAuthorStyles: true,

      //resetStyleInheritance: true,

      created: function() { },

      enteredView: function() { },

      leftView: function() { },

      attributeChanged: function(attrName, oldVal, newVal) { }

    });

  </script>

</polymer-element>

像我们要求blog元素通过HTML imports导入到我们的index.html一样(这是一种在HTML文档中复用某HTML文档的方式),我们还要核查一下它是否正确的添加到文章标签中:

<!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" style="width:90%">

                <polymer-blog></polymer-blog>

            </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 clone版本库获取适配器,也可以通过执行bower install polymer-elements利用Bower来安装polymer-elements:

yeoman-yo-grunt-bower-教程

安装好后,你就可以像导入你的post.html元素一样将它导入到blog.html页面中:

<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">

下面,我们将之前准备好的那段Google数据表的URL插入,并在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>

提示:如果在这里你卡住了或不记得url了,你可以临时先使用我的数据表,然后继续后面的教程,链接:https://spreadsheets.google.com/feeds/list/0Ao_bIaw69jI1dHhmVkU1dnpfMHdOMXJjTDFIbnFxbmc/od6/public/values?alt=json-in-script

在这里,我们可以添加template来遍历输出post链接列表:

<!-- 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内容设置post-element,像下面那样传递post变量。需要注意的是,我们通过传递post属性来表示单个数据表行,然后selected属性填写route

<!-- Post content -->

<template repeat="{{post in posts.feed.entry}}">

  <post-element post="{{post}}" selected="{{route}}"></post-element>

</template>

其中template中repeat属性是用来绑定post集合中每一个元素的。

现在博客应该能显示成这样了:

yeoman-yo-grunt-bower-教程

下面,我们需要使用一个名叫Flatiron diractor的库,它可以检测到URL hash值得变化,并绑定到之前填写的selected属性中的{{route}}变量。

我们可以通过git clone来获取Flatiron-director库,在bower-components目录下执行以下命令:

git clone https://github.com/PolymerLabs/flatiron-director.git

下面我们就能通过<flatiron-director route="{{route}}" autoHash></flatiron-director>引用它,指定一个需要绑定的属性值route,我们就能在url hash值变化时实时获取到。

下面是之前所有代码变动汇总:

yeoman-yo-grunt-bower-教程

Blog基本完工!
yeoman-yo-grunt-bower-教程
查看Demo

8错!我们现在已经通过Yeoman使用两个Polymer元素架起了一个能读取JSON数据的简易博客了~

在很短的时间内,我们在没有进行网站项目架构、服务器架设、编写模板代码和手动下载依赖文件的情况下,就完成了一个基于Web组件的简易博客系统,屌炸天了,有木有!

优化你的网站

Yeoman还包含了一个名叫Grunt的开源项目,对于Grunt,相比有一部分前端朋友有所耳闻或已经在自己的项目中使用了。Grunt可以高效的帮你完成网站优化的工作,比如代码检查、图片及代码的压缩、缩写、合并等任务。grunt可以注册默认的多项任务:

grunt.registerTask('default', [
    'jshint',
    'test',
    'build'
]);

jshint可以按你的配置要求检查你项目中所有JavaScript文件,想了解更详细的JSHint配置,可以参考它的文档

test任务可以执行一些你创建的单元测试,也可以引用一些测试框架,推荐Mocha

grunt.registerTask('test', [
    'clean:server',
    'createDefaultTemplate',
    'jst',
    'compass',
    'connect:test',
    'mocha'
]);

由于我们的这个博客比较简易,所以就不做测试任务了,你感兴趣的话可以自己尝试一下。还有以下其他的事情需要我们的build进程来处理,下面我们来看看Gruntfile.js文件中如何定义grunt build任务:

grunt.registerTask('build', [
    'clean:dist',    // 清理掉 .tmp/ 和 dist/ 文件夹
    'compass:dist',  // 编译Sass
    'useminPrepare', // 在HTML中寻找 <!-- special blocks -->
    'imagemin',      // 优化图片
    'htmlmin',       // 压缩html文件
    'concat',        // 合并你的js和css文件
    'cssmin',        // 压缩css文件
    'uglify',        // 压缩你的js文件
    'copy',          // 从 .tmp/ 和 app/ 复制文件到 dist/
    'usemin'         // 更新html中引用的文件
]);

执行 grunt build 命令即可开始grunt的一系列优化、压缩、合并等工作,在此期间你只要坐在那发呆,等待它把所有任务搞定即可~

yeoman-yo-grunt-bower-教程

yeoman-yo-grunt-bower-教程

搞定!Grunt会把所有优化压缩后的文件存到dist目录内,这个目录就是你网站的发布目录,可以目录中的文件全部部署到服务器端,就可以访问了。如果在服务器端无法访问,请用FireBug类似工具查看是否有文件访问404,如果有,说明Grunt配置有误,修改配置文件中的文件映射即可~如遇其他问题可在此留言~

如果你对于这篇教程中的一些知识点还是似懂非懂,导致无法顺利完成这个实例,你也可以下载我的这个博客实例的源码稍作研究。https://github.com/skar9363/yeoman_polymer_blog.

注意:大多数用户运行Yeoman、Grunt和Bower时遇到的问题都是因为没有足够的管理员权限,请确认你是按照安装建议那样按步骤安装的Node.js和NPM。

通过Bower单独安装Polymer

如果你希望项目开始阶段只安装Polymer,可以直接使用Bower单独安装它:

bower install polymer

这样就会把Polymer添加到你的bower_components目录。然后你就可以把它手动引用到你的项目页面中了~

总结

  现在Yeoman还是一个新兴的工具,但我们可以看到它未来的无限可能,其结合了 Yo、Grunt 和 Bower 等工具,组成了一个完整的工具集合,提供各种 Web 应用开发中所需的实用功能。

  Yeoman 的最大优势在于它整合了各种流行的实用工具,提供了一站式的解决方案,使得 Web 应用开发中的很多方面变得简单。Yeoman 使得开发人员可以专注于应用本身的实现,而不用在搭建应用的基础结构、进行任务构建和其他辅助任务上花费过多的时间和精力。Yeoman 同时也把一些好的最佳实践自动地引入到项目的开发中。比如当需要在应用中使用第三方的 JavaScript 库时,一般的做法是直接到库的网站上进行下载。而 Yeoman 中基于 Bower 进行依赖管理的做法则是更好的实践方式。Yeoman和Grunt的合作也使得我们受益,Grunt无疑能自动化的帮我们大幅提升网站性能。这一切优势,难道不能吸引你在自己的Web项目中尝试使用Yeoman么~

  Yeoman目前在国内还没有太多人了解,相关资料也寥寥无几,彬Go希望能通过这篇教程让中国更多的前端同行了解并喜欢上Yeoman,甚至在项目中使用它,但愿明年这个时候,搜索关键词”Yeoman”的中文结果不会像今天这样屈指可数。

  如果你对Yeoman感兴趣,并且有任何疑问,欢迎留言,一起探讨^_^

留意更新

订阅彬Go以查看HTML5最新资源、教程。

转载声明:
原载:彬Go——关注前端开发 & Web UI设计
本文链接:http://blog.bingo929.com/yeoman-grunt-bower-polymer-web-components-javascript-create-web-app.html如需转载必须以链接形式注明原载或原文地址,谢谢合作

53 Comments

发表评论

  • 增达网
    2017-05-14

    受教了!呵呵!

  • 增达网QQ-33092290
    2017-03-20

    真是时光荏苒!

  • 匿名
    2016-12-01

    Just leave a comment

  • 匿名
    2016-11-06

    银泰

  • 匿名
    2016-08-30

    jjjj

  • QQ853691133
    2016-08-11

    博客不错,嘎嘎!

  • 420797280
    2016-06-17

    年中快乐!

  • WilliamNum
    2016-06-16

    wow, awesome post.Really looking forward to read more. Awesome. Mauck

  • 78352566
    2016-04-19

    看看!

  • py
    2016-04-14

    不错 学习了