| OLD | NEW |
| (Empty) |
| 1 --- | |
| 2 title: "Package layout conventions" | |
| 3 --- | |
| 4 | |
| 5 1. [The basics](#the-basics) | |
| 6 1. [README](#readme) | |
| 7 1. [Public libraries](#public-libraries) | |
| 8 1. [Public assets](#public-assets) | |
| 9 1. [Implementation files](#implementation-files) | |
| 10 1. [Web files](#web-files) | |
| 11 1. [Command-line apps](#command-line-apps) | |
| 12 1. [Tests and benchmarks](#tests-and-benchmarks) | |
| 13 1. [Documentation](#documentation) | |
| 14 1. [Examples](#examples) | |
| 15 1. [Internal tools and scripts](#internal-tools-and-scripts) | |
| 16 {:.toc} | |
| 17 | |
| 18 Part of a healthy code ecosystem is consistent conventions. When we all do the | |
| 19 same thing the same way, it makes it easier for us to learn our way around | |
| 20 each other's work. It also makes it easier to write tools that can automatically | |
| 21 do stuff for us. | |
| 22 | |
| 23 When you build a Pub package, we have a set of conventions we encourage you to | |
| 24 follow. They describe how you organize the files and directories within your | |
| 25 package, and how to name things. You don't have to have every single thing | |
| 26 these guidelines specify. If your package doesn't have binaries, it doesn't | |
| 27 need a directory for them. But if it does, you'll make everyone's life easier | |
| 28 if you call it `bin`. | |
| 29 | |
| 30 To give you a picture of the whole enchilada, here's what a complete package | |
| 31 (conveniently named `enchilada`) that uses every corner of these guidelines | |
| 32 would look like: | |
| 33 | |
| 34 enchilada/ | |
| 35 pubspec.yaml | |
| 36 pubspec.lock * | |
| 37 README.md | |
| 38 LICENSE | |
| 39 asset/ | |
| 40 guacamole.css | |
| 41 benchmark/ | |
| 42 make_lunch.dart | |
| 43 packages/ ** | |
| 44 bin/ | |
| 45 enchilada | |
| 46 packages/ ** | |
| 47 doc/ | |
| 48 getting_started.md | |
| 49 example/ | |
| 50 lunch.dart | |
| 51 packages/ ** | |
| 52 lib/ | |
| 53 enchilada.dart | |
| 54 tortilla.dart | |
| 55 src/ | |
| 56 beans.dart | |
| 57 queso.dart | |
| 58 packages/ ** | |
| 59 test/ | |
| 60 enchilada_test.dart | |
| 61 tortilla_test.dart | |
| 62 packages/ ** | |
| 63 tool/ | |
| 64 generate_docs.dart | |
| 65 web/ | |
| 66 index.html | |
| 67 main.dart | |
| 68 style.css | |
| 69 | |
| 70 \* The `pubspec.lock` will only be in source control if the package is an | |
| 71 [application package](glossary.html#application-package). | |
| 72 | |
| 73 \** The `packages` directories will exist locally after you've run | |
| 74 `pub get`, but won't be checked into source control. | |
| 75 | |
| 76 ## The basics | |
| 77 | |
| 78 enchilada/ | |
| 79 pubspec.yaml | |
| 80 pubspec.lock | |
| 81 | |
| 82 <div class="learn-more"> | |
| 83 <a href="/doc/pubspec.html"> | |
| 84 Learn more about pubspecs → | |
| 85 </a> | |
| 86 </div> | |
| 87 | |
| 88 Every package will have a [**pubspec**](pubspec.html), a file named | |
| 89 `pubspec.yaml`, in the root directory of the package. That's what *makes* it a | |
| 90 package. | |
| 91 | |
| 92 Once you've run [`pub get`](pub-get.html) or [`pub | |
| 93 upgrade`](pub-upgrade.html) on the package, you will also have a **lockfile**, | |
| 94 named `pubspec.lock`. If your package is an [application | |
| 95 package](glossary.html#application-package), this will be checked into source | |
| 96 control. Otherwise, it won't be. | |
| 97 | |
| 98 enchilada/ | |
| 99 packages/ | |
| 100 ... | |
| 101 | |
| 102 Running pub will also generate a `packages` directory. You will *not* check | |
| 103 this into source control, and you won't need to worry too much about its | |
| 104 contents. Consider it pub magic, but not scary magic. | |
| 105 | |
| 106 The open source community has a few other files that commonly appear at the top | |
| 107 level of a project: `LICENSE`, `AUTHORS`, etc. If you use any of those, they can | |
| 108 go in the top level of the package too. | |
| 109 | |
| 110 ## README | |
| 111 | |
| 112 enchilada/ | |
| 113 README.md | |
| 114 | |
| 115 One file that's very common in open source is a README file that | |
| 116 describes the project. This is especially important in pub. When you upload | |
| 117 to [pub.dartlang.org](/), your README will be shown on the page for your | |
| 118 package. This is the perfect place to introduce people to your code. | |
| 119 | |
| 120 If your README ends in `.md`, `.markdown`, or `.mdown`, it will be parsed as | |
| 121 [Markdown][] so you can make it as fancy as you like. | |
| 122 | |
| 123 [markdown]: http://daringfireball.net/projects/markdown/ | |
| 124 | |
| 125 ## Public libraries | |
| 126 | |
| 127 enchilada/ | |
| 128 lib/ | |
| 129 enchilada.dart | |
| 130 tortilla.dart | |
| 131 | |
| 132 Many packages are [*library packages*](glossary.html#library-package): they | |
| 133 define Dart libraries that other packages can import and use. These public Dart | |
| 134 library files go inside a directory called `lib`. | |
| 135 | |
| 136 Most packages define a single library that users can import. In that case, | |
| 137 its name should usually be the same as the name of the package, like | |
| 138 `enchilada.dart` in the example here. But you can also define other libraries | |
| 139 with whatever names make sense for your package. | |
| 140 | |
| 141 When you do, users can import these libraries using the name of the package and | |
| 142 the library file, like so: | |
| 143 | |
| 144 {% highlight dart %} | |
| 145 import "package:enchilada/enchilada.dart"; | |
| 146 import "package:enchilada/tortilla.dart"; | |
| 147 {% endhighlight %} | |
| 148 | |
| 149 If you feel the need to organize your public libraries, you can also create | |
| 150 subdirectories inside `lib`. If you do that, users will specify that path when | |
| 151 they import it. Say you have a file hierarchy like this: | |
| 152 | |
| 153 enchilada/ | |
| 154 lib/ | |
| 155 some/ | |
| 156 path/ | |
| 157 olives.dart | |
| 158 | |
| 159 Users will import `olives.dart` like: | |
| 160 | |
| 161 {% highlight dart %} | |
| 162 import "package:enchilada/some/path/olives.dart"; | |
| 163 {% endhighlight %} | |
| 164 | |
| 165 Note that only *libraries* should be in `lib`. *Entrypoints*—Dart scripts | |
| 166 with a `main()` function—cannot go in `lib`. If you place a Dart script | |
| 167 inside `lib`, you will discover that any `package:` imports it contains don't | |
| 168 resolve. Instead, your entrypoints should go in the appropriate | |
| 169 [entrypoint directory](glossary.html#entrypoint-directory). | |
| 170 | |
| 171 ## Public assets | |
| 172 | |
| 173 enchilada/ | |
| 174 asset/ | |
| 175 guacamole.css | |
| 176 | |
| 177 While most library packages exist to let you reuse Dart code, you can also | |
| 178 reuse other kinds of content. For example, a package for something like | |
| 179 [Bootstrap](http://getbootstrap.com/) might include a number of CSS files for | |
| 180 consumers of the package to use. | |
| 181 | |
| 182 These go in a top-level directory named `asset`. You can put any kind of file | |
| 183 in there and organize it with subdirectories however you like. It's effectively | |
| 184 a `lib` directory for stuff that isn't Dart code. | |
| 185 | |
| 186 Users can reference another package's assets using URLs that contain | |
| 187 `assets/<package>/<path>` where `<package>` is the name of the package | |
| 188 containing the asset and `<path>` is the relative path to the asset within that | |
| 189 package's `asset` directory. | |
| 190 | |
| 191 <aside class="alert alert-warning"> | |
| 192 | |
| 193 <p>The mechanics of referencing assets are still being implemented. URLs that | |
| 194 contain <tt>assets/</tt> are handled by <a href="pub-serve.html"><tt>pub | |
| 195 serve</tt></a>.</p> | |
| 196 | |
| 197 <p>The <a href="pub-build.html"><tt>pub build</tt></a> command also copies | |
| 198 assets to an <tt>assets</tt> directory, but this will <em>only</em> be in the | |
| 199 root directory of the output, so you must make sure that your <tt>assets/</tt> | |
| 200 URL correctly resolves to that directory and not a subdirectory.</p> | |
| 201 | |
| 202 <p>We don't currently have a solution for referencing assets in command-line | |
| 203 Dart applications.</p> | |
| 204 | |
| 205 </aside> | |
| 206 | |
| 207 Note that `assets` is plural in the URL. This is a bit like the split between | |
| 208 `lib` and `packages`. The former is the name of the *directory in the package*, | |
| 209 the latter is the *name you use to reference it*. | |
| 210 | |
| 211 For example, let's say your package wanted to use enchilada's `guacamole.css` | |
| 212 styles. In an HTML file in your package, you can add: | |
| 213 | |
| 214 {% highlight html %} | |
| 215 <link href="assets/enchilada/guacamole.css" rel="stylesheet"> | |
| 216 {% endhighlight %} | |
| 217 | |
| 218 When you run your application using [`pub serve`](pub-serve.html), or build it | |
| 219 to something deployable using [`pub build`](pub-build.html), Pub will copy over | |
| 220 any referenced assets that your package depends on. | |
| 221 | |
| 222 ## Implementation files | |
| 223 | |
| 224 enchilada/ | |
| 225 lib/ | |
| 226 src/ | |
| 227 beans.dart | |
| 228 queso.dart | |
| 229 | |
| 230 The libraries inside "lib" are publicly visible: other packages are free to | |
| 231 import them. But much of a package's code is internal implementation libraries | |
| 232 that should only be imported and used by the package itself. Those go inside a | |
| 233 subdirectory of `lib` called `src`. You can create subdirectories in there if | |
| 234 it helps you organize things. | |
| 235 | |
| 236 You are free to import libraries that live in `lib/src` from within other Dart | |
| 237 code in the *same* package (like other libraries in `lib`, scripts in `bin`, and | |
| 238 tests) but you should never import from another package's `lib/src` directory. | |
| 239 Those files are not part of the package's public API, and they might change in | |
| 240 ways that could break your code. | |
| 241 | |
| 242 When you use libraries from within your own package, even stuff in `src`, you | |
| 243 can (and should) still use `"package:"` to import them. This is perfectly | |
| 244 legit: | |
| 245 | |
| 246 {% highlight dart %} | |
| 247 import "package:enchilada/src/beans.dart"; | |
| 248 {% endhighlight %} | |
| 249 | |
| 250 The name you use here (in this case `enchilada`) is the name you specify for | |
| 251 your package in its [pubspec](pubspec.html). | |
| 252 | |
| 253 ## Web files | |
| 254 | |
| 255 enchilada/ | |
| 256 web/ | |
| 257 index.html | |
| 258 main.dart | |
| 259 style.css | |
| 260 | |
| 261 Dart is a web language, so many pub packages will be doing web stuff. That | |
| 262 means HTML, CSS, images, and, heck, probably even some JavaScript. All of that | |
| 263 goes into your package's `web` directory. You're free to organize the contents | |
| 264 of that to your heart's content. Go crazy with subdirectories if that makes you | |
| 265 happy. | |
| 266 | |
| 267 Also, and this is important, any Dart web entrypoints (in other words, Dart | |
| 268 scripts that are referred to in a `<script>` tag) go under `web` and not `lib`. | |
| 269 That ensures that there is a nearby `packages` directory so that `package:` | |
| 270 imports can be resolved correctly. | |
| 271 | |
| 272 (You may be asking yourself, "Self, where should I put my web-based example | |
| 273 programs? `example` or `web`?" Put those in `example`.) | |
| 274 | |
| 275 ## Command-line apps | |
| 276 | |
| 277 enchilada/ | |
| 278 bin/ | |
| 279 enchilada | |
| 280 | |
| 281 Some packages define programs that can be run directly from the command line. | |
| 282 These can be shell scripts or any other scripting language, including Dart. | |
| 283 The `pub` application itself is one example: it's a simple shell script that | |
| 284 invokes `pub.dart`. | |
| 285 | |
| 286 If your package defines stuff like this, put it in a directory named `bin`. | |
| 287 | |
| 288 <aside class="alert alert-note"> | |
| 289 | |
| 290 At some point, pub will support automatically adding that directory to your | |
| 291 system path so that these scripts can be easily invoked. | |
| 292 | |
| 293 </aside> | |
| 294 | |
| 295 ## Tests and benchmarks | |
| 296 | |
| 297 enchilada/ | |
| 298 test/ | |
| 299 enchilada_test.dart | |
| 300 tortilla_test.dart | |
| 301 | |
| 302 Every self-respecting package should have tests. With pub, the convention is | |
| 303 that these go in a `test` directory (or some directory inside it if you like) | |
| 304 and have `_test` at the end of their file names. | |
| 305 | |
| 306 Typically, these use the [unittest](http://api.dartlang.org/unittest.html) | |
| 307 package but you can use whatever testing system that gets you excited. | |
| 308 | |
| 309 enchilada/ | |
| 310 benchmark/ | |
| 311 make_lunch.dart | |
| 312 | |
| 313 Packages that have performance critical code may also include *benchmarks*. | |
| 314 These test the API not for correctness but for speed (or memory use, or maybe | |
| 315 other empirical metrics). | |
| 316 | |
| 317 ## Documentation | |
| 318 | |
| 319 enchilada/ | |
| 320 doc/ | |
| 321 getting_started.md | |
| 322 | |
| 323 If you've got code and tests, the next piece you need to maximize your karma | |
| 324 is good documentation. That goes inside a directory named `doc`. We don't | |
| 325 currently have any guidelines about format or organization within that. Use | |
| 326 whatever markup format you like and be happy that you're actually writing docs. | |
| 327 | |
| 328 This directory should *not* just contain docs generated automatically from your | |
| 329 source code using | |
| 330 [dartdoc](http://api.dartlang.org/docs/continuous/dartdoc.html). Since that's | |
| 331 pulled directly from the code already in the package, putting those docs in | |
| 332 here would be redundant. Instead, this is for tutorials, guides, and other | |
| 333 hand-authored documentation *in addition to* generated API references. | |
| 334 | |
| 335 ## Examples | |
| 336 | |
| 337 enchilada/ | |
| 338 example/ | |
| 339 lunch.dart | |
| 340 | |
| 341 At this point, you're going for the brass ring. Code, tests, docs, what else | |
| 342 could your users want? Standalone example programs that use your package, of | |
| 343 course! Those go inside the `example` directory. If the examples are complex | |
| 344 and use multiple files, consider making a directory for each example. Otherwise, | |
| 345 you can place each one right inside `example`. | |
| 346 | |
| 347 This is an important place to consider using `package:` to import files from | |
| 348 your own package. That ensures the example code in your package looks exactly | |
| 349 like code outside of your package would look. | |
| 350 | |
| 351 ## Internal tools and scripts | |
| 352 | |
| 353 enchilada/ | |
| 354 tool/ | |
| 355 generate_docs.dart | |
| 356 | |
| 357 Mature packages often have little helper scripts and programs that people | |
| 358 run while developing the package itself. Think things like test runners, | |
| 359 documentation generators, or other bits of automation. | |
| 360 | |
| 361 Unlike the scripts in `bin`, these are *not* for external users of the package. | |
| 362 If you have any of these, place them in a directory called `tool`. | |
| OLD | NEW |