Managing and using dependencies in Dart is a joy. That is rather the point of coding in Dart. Doing the same in JavaScript is an adventure. But it is an adventure that is improving. One of the ways in which it is the Bower project, which is, I suppose, one of the reasons that the Polymer project has adopted Bower for managing its own dependencies.
Tonight, I would like to explore using Bower to manage a custom Polymer. I would also like to see if I can get Bower to install a third party library like Underscore.js for use inside my Polymer. I know full well how I would go about doing this in the Dart port of Polymer, but am a little fuzzy on the JavaScript details.
I get started with
bower init
:$ bower init [?] name: underscore_example [?] version: 0.0.0 [?] description: Mucking around with Polymer dependencies [?] main file: [?] keywords: [?] authors: Chris StromNext, I install Polymer, adding it to the list of dependencies in the generated[?] license: MIT [?] homepage: https://github.com/eee-c/polymer-patterns [?] set currently installed components as dependencies? Yes [?] add commonly ignored files to ignore list? Yes [?] would you like to mark this package as private which prevents it from being accidentally published to the registry? Yes { name: 'underscore_example', version: '0.0.0', homepage: 'https://github.com/eee-c/polymer-patterns', authors: [ 'Chris Strom ' ], description: 'Mucking around with Polymer dependencies', license: 'MIT', private: true, ignore: [ '**/.*', 'node_modules', 'bower_components', 'test', 'tests' ] } [?] Looks good? Yes
bower.json
file:bower install --save Polymer/polymer bower polymer#* cached git://github.com/Polymer/polymer.git#0.1.1 bower polymer#* validate 0.1.1 against git://github.com/Polymer/polymer.git#* bower platform#0.1.1 cached git://github.com/Polymer/platform.git#0.1.1 bower platform#0.1.1 validate 0.1.1 against git://github.com/Polymer/platform.git#0.1.1 bower polymer#~0.1.1 install polymer#0.1.1 bower platform#0.1.1 install platform#0.1.1 polymer#0.1.1 bower_components/polymer └── platform#0.1.1 platform#0.1.1 bower_components/platformFinally, I add my other dependency, Underscore.js:
$ bower install --save underscore ... bower underscore#~1.5.2 install underscore#1.5.2 underscore#1.5.2 bower_components/underscoreAt this point, I have the generated
bower.json
plus my new dependencies (which were saved by the --save
option to bower install
above):{ "name": "underscore_example", // ... "dependencies": { "polymer": "Polymer/polymer#~0.1.1", "underscore": "~1.5.2" } }The dependencies are installed and ready to use:
tree -d -L 1 bower_components bower_components ├── platform ├── polymer └── underscore 3 directoriesBut my guess is that I do not want to check anything under the
bower_components
directory into source control. The entire contents can be recreated on another developer's machine or in a deployment environment with bower install
. So my next step is to add bower_components
to my dot-gitignore file:$ echo bower_components >> .gitignore $ cat .gitignore node_modules bower_componentsNow that I have the JavaScript that I want to use, let's use it. I start with the application code that goes in the main web page. The Polymer documentation starts with the Polymer itself, but I find it easiest to have the page page ready. My
index.html
:<!DOCTYPE html> <html lang="en"> <head> <title>Working with Underscore.js</title> <!-- 1. Load Polymer before any code that touches the DOM. --> <script src="bower_components/platform/platform.js"></script> <!-- 2. Load component(s) --> <link rel="import" href="scripts/hello-you.html"> </head> <body> <div class="container"> <hello-you></hello-you> </div> </body> </html>And now, my
<hello-you>
Polymer. I have been using a simple Polymer for illustration that binds an <input>
value to a variable that is also bound in the Polymer title. I also have a feelingLucky()
method that randomly changes the title's color:<link rel="import" href="../bower_components/polymer/polymer.html"> <polymer-element name="hello-you"> <template> <h2>{{hello}} {{your_name}}</h2> <p> <input value="{{your_name}}"> <input type=submit value="{{done}}!" on-click="{{feelingLucky}}"> </p> <!-- ... --> </template> <script> Polymer('hello-you', { your_name: '', // ... feelingLucky: function() { // Change the H2's color here... } }); </script> </polymer-element>I am not doing anything new in the code tonight. What is different is the
<link>
import on the first line—I am pulling the Polymer baseclass definition from the Bower installation. With my application already pulling this Polymer in from scripts/hello-you.html
, I have a working Polymer built from bower components:But how do I best go about using my Underscore.js dependency? Say, for instance, I want to debounce the “Done!” button that triggers the
feelingLucky()
method. I am unsure where best to pull in the Underscore.js library. No matter where I do so, I am pulling the library into global scope—this is JavaScript, after all. I will worry about where best to place the <script>
tag that imports Underscore another day. For now, I get the library added via a <script>
tag with an Underscore.js src
attribute just above the <script>
tag that defines the Polymer:<link rel="import" href="../bower_components/polymer/polymer.html"> <polymer-element name="hello-you"> <template> <!-- ... --> </template> <script src="../bower_components/underscore/underscore.js"></script> <script> Polymer('hello-you', { your_name: '', // ... feelingLucky: _.debounce( function() { // Change the H2's color here... }, 750, true ) }); </script> </polymer-element>And that works like a charm. If I click the “Done!” button, my
feelingLucky()
method does indeed change the Polymer's title color right away (the true
3rd parameter to _.debounce()
calls the function immediately rather than waiting for the bounce to expire). If I try to double-click, then the color only changes once. If I wait a little less than a second before clicking a second time, I can see the title change colors multiple times.I note here that, thanks to Underscore's respect for the sanctity of
this
, I can continue to refer to this
inside the anonymous function as if this
represents the current object. That is, I can still treat it like a method, which is nice.That is a good stopping point for tonight. Bower may not be Dart Pub, but it is pretty darn nice. I still need to take a closer look at where best to place the Underscore.js
<script>
tag. I should also look into the best application structure—in particular, should my Polymer expect to find the bower_component
directory one directory above it or can I find a more general solution? I also need to decide how best to deploy this code—especially how best to use a library like Underscore which is available on lovely CDNs.Good questions all. For tomorrow.
Day #981
I get this error when installing polymer on windows pc. " bower ENOGIT git is not installed or not in the path
ReplyDelete