My Dart library, Hipster MVC, was accepted into Dart Pub today as an official package. To celebrate, I am going to try to use it, in Dart Comics, the original application from which it was extracted.
After reviewing the options on the
pub
command, it seems that I want to pub install
in my web site's public/scripts
directory. For that I need a pubspec.yaml
file that includes hipster_mvc
as a dependency:name: scripts dependencies: hipster_mvc: anyThe
pub install
command will not work without a name in there. Since this is just the scripts
directory, I use the name "scripts". This seems like the kind of thing that could be optional in an application directory. The "any" value in the pubspec indicates that I am OK with any version (i.e. the latest version) of hipster_mvc.Anyhow,
pub install
works now, though it berates me a bit:➜ scripts git:(M1) ✗ ~/local/dart/dart-sdk/bin/pub install Resolving dependencies... Downloading hipster_mvc 0.1.0 from hosted... Warning: Package "scripts" is using a deprecated layout. See http://www.dartlang.org/docs/pub-package-manager/package-layout.html for details. Dependencies installed!I will worry about the warning later. For now, I note that
pub install
left behind a lock file containing the current version of hipster_mvc and any associated dependencies:➜ scripts git:(M1) ✗ cat pubspec.lock {"packages":{"hipster_mvc":{"version":"0.1.0","source":"hosted","description":"hipster_mvc"}}}I am used to this approach with bundler from the Ruby world. Since this is an application, I will check this lock file into Git so that anyone else working with the code will be running the same versions of hipster_mvc that I am using.
I also note that the package is not actually installed in
public/scripts/packages
. Rather, pub install
has created a symlink to the cache directory:➜ scripts git:(M1) ✗ tree packages packages └── hipster_mvc -> /home/chris/.pub-cache/hosted/pub.dartlang.org/hipster_mvc-0.1.0/lib 1 directory, 0 filesPresumably this is so that I do not have to re-download my huge hipster_mvc library again.
With that, I fire up my Dart Comics app in Dartium and find... the following errors in the Console:
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3000/scripts/packages/hipster_mvc/lib/hipster_sync.dart Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3000/scripts/packages/hipster_mvc/lib/hipster_view.dart Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3000/scripts/packages/hipster_mvc/lib/hipster_collection.dart Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:3000/scripts/packages/hipster_mvc/lib/hipster_model.dartI added the
lib
in that path to conform to the pub standards. And indeed that path is in my hipster_mvc repository:➜ hipster-mvc git:(master) tree -I docs . ├── lib │ ├── hipster_collection.dart │ ├── hipster_history.dart │ ├── hipster_model.dart │ ├── hipster_router.dart │ ├── hipster_sync.dart │ └── hipster_view.dart ├── pubspec.yaml └── README.asciidoc 1 directory, 8 filesBut it is not in the package pulled from Dart Pub:
➜ scripts git:(M1) ✗ tree packages/hipster_mvc packages/hipster_mvc ├── hipster_collection.dart ├── hipster_history.dart ├── hipster_model.dart ├── hipster_router.dart ├── hipster_sync.dart └── hipster_view.dart 0 directories, 6 filesFrom a library developer's perspective, I find the difference confusing. From an application developer's perspective, I appreciate the lack of the extra
lib
in the path. All of my import statements then become:// ... #import('package:hipster_mvc/hipster_sync.dart'); main() { HipsterSync.sync = localSync; // ... } // ...With that, I again have my Dart Comics application running. Now with hipster_mvc installed from Dart Pub:
A consequence of the
lib
vs. no-lib
difference is that I cannot simply swap out my pub package for my local repository:➜ scripts git:(M1) ✗ cd packages ➜ packages git:(M1) ✗ mv hipster_mvc hipster_mvc.pub ➜ packages git:(M1) ✗ ln -s ~/repos/hipster-mvcIf I reload the application, I again get 404s for my library—this time because they all reside under the
lib
path:GET http://localhost:3000/scripts/packages/hipster_mvc/hipster_sync.dart 404 (Not Found) localhost:20 GET http://localhost:3000/scripts/packages/hipster_mvc/hipster_collection.dart 404 (Not Found) localhost:20 GET http://localhost:3000/scripts/packages/hipster_mvc/hipster_view.dart 404 (Not Found) localhost:20 GET http://localhost:3000/scripts/packages/hipster_mvc/hipster_model.dart 404 (Not Found) localhost:20I could symlink the
lib
directory from the local repository of hipster_mvc:➜ packages git:(M1) ✗ rm hipster-mvc ➜ packages git:(M1) ✗ ln -s ~/repos/hipster-mvc/lib hipster_mvcNow, if I reload, the application works again and I can try out changes in hipster_mvc before committing them to GitHub.
Pub does support git sources. So I can try the following instead of pulling down the official hipster_mvc package:
name: scripts dependencies: hipster_mvc: git: git://github.com/eee-c/hipster-mvc.gitIf I run
pub install
with that pubspec.yaml, I find that pub has made a copy of the git repository and symlinked to its lib
directory:➜ scripts git:(M1) ✗ ls -l packages total 4 lrwxrwxrwx 1 chris chris 83 Oct 30 23:31 hipster_mvc -> /home/chris/.pub-cache/git/hipster_mvc-e0a4aab8d6fe782f81c2c9abc83906d5fb92e190/libSo it seems that I was not too far off base manually symlinking to my local repository's
lib
directory. And, if I manually symlink like that, I do not have to alter the pubspec.yaml or the pubspec.lock and potentially impact other contributors.All things considered, Dart Pub is nothing short of amazing. It is not a revolutionary package manager as it is very familiar. But it does have the potential to revolutionize client-side development. Easy installs, a formal mechanism to ensure that everyone has the same package versions without having to check any package code into source code, dependency resolution, easy development of local copies—all make for a very exciting time to be a web developer.
Day #560
No comments:
Post a Comment