#7 - All you need to know about Dart Packages and the Pub Package Manager

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is going on everyone i'm wicked welcome back to my dart from novice to expert complete course a couple of tutorials back i introduced you to the components of a dar project not only that but we also established that every dar project is actually a package as i promised back then today i'll do a more thorough explanation on dart packages a crucial topic you should definitely understand before proceeding to the next tutorials so without further ado let's get right into it beforehand though i want to send a token of appreciation to everyone supporting me as official youtube members especially to diana and michael aka aza on discord if you want to become a member all you have to do is to click the join button right next to my channel and pick your desired membership having that said let's continue with our tutorial ok so in tutorial number 4 we learned that a dart package is a directory containing at minimum a pubspec.yaml file we also learned that the dart ecosystem uses packages to manage shared software such as implemented libraries and tools and that in order to get and manage dart packages you use the dedicated pub package manager which can communicate with the pubspec.yaml file let's get more in depth on these topics shall we let's create an empty folder that will be a new dart project if we fire up a terminal here and type in a dart pub command you'll see that it warns us it couldn't find any pubspec.yaml file inside the root of our folder this actually means currently our project isn't a package an important fact to be extracted from here is that if you don't want your project to be a package don't want to depend on other packages and don't want to benefit from any of their advantages you don't actually need a pub spec file you can simply go right ahead and create a dar file containing a main function and run it directly via the dart run command there's nothing wrong with this however as i said the main idea here is that the entire ecosystem uses packages so it's preferable that you turn your project into a package even if you don't want to share it with the community or perhaps benefit from their advantages therefore let's create this pubspec.yaml file the simplest possible pop spec contains only two fields the name of the package and the environment containing the sdk constraints your package will be bound between now if we run dart pub get our project will be initialized as a package you can observe the newly generated files we've previously encountered a couple of tutorials back for now let's focus on the pubspec file it's really important that you understand the fields this pubspec.yaml file supports so here's a complete file containing all of them know that on flutter the pubspec.yaml will contain additional fields every package needs a name it's how other packages refer to yours and how it appears to the world the name should be all lowercase with underscores to separate words every package also needs to have a version a version number is required to host your packages on the pub.dev site but it can be omitted for local only packages a version number is three numbers separated by dots the first number is the major the second is the minor and the third is the patch it can also come with build or pre-release suffixes the description is optional for your own personal packages but if you intend to publish your package you must provide a description which should be in english language think of the description as the sales page for your package users see it when they browse for packages home page repository issue tracker and documentation these fields are all optional and should contain the urls with their desired websites but only if you'll share the package with the world now a package may expose one or more of its scripts and executables that can be run directly from the command line entries are listed as key value pairs one being the name of the executable and the other one being the dar script from the bin folder inside your package we'll talk about this later on this tutorial and regarding the publish underscore 2 field the default uses the pub.dev site specify none to prevent the package from being published what you need to also understand is that a package has an implicit dependency the dart platform itself the dart platform evolves over time and the package might only work with certain versions of the platform a package can specify those versions using an sdk constraint this constraint goes inside a separate top level environment field in the pop spec file as of dart 2.12 omitting the sdk constraint is an error and now i left this part at the end because it's one of the most important fields of any pubspec file dependencies dependencies are one of the core concepts of dart you really need to understand a dependency is just another package that your package depends on in order to work and they are specified in the pubspec.yaml file under the dependencies field now while developing with dart most of the time you'll hear about immediate dependencies transitive dependencies regular dependencies and dev dependencies to understand the difference between immediate and transitive dependencies if your package depends on a which in turn depends on b which depends on c then a is an immediate dependency and b and c are transitive ones therefore this is mainly related to whether the dependency is direct or indirect with respect to your package and to understand the difference between regular and depth dependencies the regular ones are those your package will use during both the production and development phases while the dev ones will only be used during the development phase thus being ignored when building the app as an example say our package uses the test package to test its functionality if someone just wants to use this package it doesn't actually need the test package therefore the test needs to be a dev dependency now as you may have seen from the pubspec file for each dependency you specify the name of the package you depend on and the range of versions of that package that you allow inside your app dart community uses semantic versioning which helps you have an idea on which versions should work the general rule everyone uses is that if you know your package works fine with perhaps a version 1.2.3 of some dependency then semantic versioning tells you that it should work with any subsequent stable release before 2.0.0 this is why when introducing braking changes you'll often find package developers bumping up the packages major version so that people depending on it won't experience the breaking changes unless they'll upgrade the dependency version you can express version constraints using either carrot syntax or traditional syntax carrot syntax is a compact way of expressing the traditional syntax version constraint for example caret 1.2.3 is equivalent to greater or equal than 1.3.3 and less than 2.0.0 and carrot 0.1 0.1.2 is equivalent to greater or equal than 0.1.2 and less than 0.2.0 using the traditional syntax may give you a little bit more flexibility over version constraints as it is more abstract but in the end i highly recommend you use the carrot syntax as it's mostly what everyone else uses what i forgot to mention about these versions is that after they get downloaded pub will automatically generate the pubspec.log file containing the exact version of the dependencies your package actually works with this is why when working on a local package it's recommended to put this file into source control so that everyone working on the project is based on the same dependencies versions now speaking of dependencies i'm sure most of you may think that you can retrieve dependencies only from pub.dev and that's not true at all you can depend on packages from multiple sources first and foremost indeed you can depend on hosted packages but hosted packages doesn't necessarily mean pub.dev only even though pub.dev is the most popular approach you can also depend on packages hosted on other http servers that speak the same api as pub.dev secondly you can depend on git packages sometimes you just want to work on the latest version of a package that hasn't been formally released yet to make that easier you can depend directly on a package stored in a git repository here you have the ability to fine tune your version by depending on a specific comet branch or even a tag thirdly you can also depend on path packages sometimes you might find yourself working on multiple related packages at the same time maybe you are creating a big application that depends on other multiple small packages in those cases during development you really want to depend on the live version of that package this way changes in one package are instantly picked up by the one that depends on it facilitating the development speed and workflow last but not least you can depend on packages from inside an sdk source this is used for any sdks that are shipped along with packages which may themselves be dependencies currently flutter is the only sdk that is supported right here and speaking of retrieving packages you might wonder well where does pub store all these packages after it downloads them from a remote source when pub gets a remote package it downloads it into a single system cache directory maintained by pub this directory is platform specific however you can actually specify a different location using the pub underscore cache environment variable i've set myself to a folder which is more accessible to me inside one of my drives once packages are in the system cache folder pub creates a dot packages file and a package underscore config.json file mapping each package used by your application to the corresponding package in the cache the dot package file is deprecated and will be removed in favor of package underscore config.json file in the future as you can see these files mainly contain the names and the path to the packages now in order to put everything we learned to practice let's open up our previous console full project what we want to do inside of it is create an internal calculator library package with various simple calculator functionalities then we'll set it as a dependency to our console full package via the path method so that we can work on both packages live while doing so we'll also take a brief look over the dark pub commands with all of its features so right now we've opened the console full package what we want to do first is to create a packages folder into the root of our directory then we'll go right ahead and create our package which is going to be called calculator as we learned today what takes for a directory to become a dart package is the pubspec.yaml file therefore this is what we're going to create next dart automatically warns us that there is no name or environment fields inside of it so we'll specify the package name as being calculator and set the sdk constraints of the environment as we previously did if we save this file vs code will automatically run the dart pub get command which will initialize our package by generating the specific files and retrieving the dependencies now since we're concurrently working on two packages we shall open up two terminals side by side so that we can interact with both of them then we need to make sure our calculator package also benefits from analyzer lint rules so we'll go right ahead and create an analysis underscore options.yaml file and include the analysis options file from inside the pedantic package of course this means we'll have to also add our first package dependency which is going to be the pedantic package since we're at this step why don't we glass over the calculator terminal and check one of the dart pub commands that will help us add whatever dependency we want to our pubspec.yaml file i'm talking about the dark pub add command therefore if we type in dart pub add pedantic dart will automatically add the pedantic dependency to our calculator pop spec file then in order to retrieve the dependencies as i told you earlier we need to run dart pop get command if we switch our view to the package underscore config.json file will observe indeed that the pedantic package was successfully added as a dependency to our calculator package now since we're creating a library package which means that other packages will be able to depend on it and by other packages i mean our local console full package we need to structure its implementations inside a library so we'll create a lib folder and a calculator.dart file that will expose the calculator implementations the implementations will lay inside a source subfolder in this subfolder we'll create four files add subtract multiply and divide in each of these files we'll have a function similarly named that will take two integers as parameters and return their appropriate calculated values after we've done this it's time to export them inside the calculator.dart library file currently we have two standalone working packages one is the calculator and the other one is the console full project what we want now is the console full package to depend on the calculator package we created inside the packages subfolder to do that we'll go into the pubspec.yaml and set it as a dependency by mentioning its path then we'll go ahead and type in the dartpop get command again to link them up now all there's left to be done is to use the calculator package implementations inside our console full package as i previously said in one of my tutorials since the calculator package is a library package the only folder that's accessible to another package is the lib folder that's why all our implementations stay inside there therefore we'll create four identical functions just for demonstration purposes that will call the add multiply subtract and divide methods from inside the calculator package as you can see since every file was properly exported from inside the calculator.dart library file all we need to import at the top is that specific file and dart will automatically link everything together finally i'll make sure to appropriately print them into our main function to observe if our simple calculator works as it should as you can see all it has to do is to add subtract divide and multiply 25 with four if we type in dart run command inside the terminal you'll see that indeed our calculator package is working perfectly one key feature i wanted to observe is that since our calculator package is dependent on via its path if we modify a function inside of it we don't need to run any dart pub command to notify our console for package that there's been a change in the code of the package it depends on the changes are applied automatically the only thing that's left to be done now inside this tutorial is perhaps to cover the rest of the dart pub commands we hadn't had a chance to take a look at take dark pub cache for example if we type in dart pub cache add and the name of the package pub will make sure to download it into the cache location we've previously talked about take note it won't also add it to the pubsphere.yaml file also note that most of the commands here will only work if the terminal is opened inside the directory of a package dart pop depths for example will take the package and build a dependencies tree containing both immediate dependencies and transitive dependencies on the other hand dart pub global works without a package directory and that's because this command will be able to set up the executable files mentioned inside of abstract.yml of a remote package write as standalone terminal commands for example if we browse into the very good cli package you will see that inside its pubspec.yml file they set the executable field to be the very underscore good command with the same file name and sure enough we can see the very underscore good.dart file inside the bin folder now if we type in dart pub global activate very good cli dart will go and retrieve the package and set the very good command in the environment path so that we can call the utilitarian directly from inside the terminal the login and logout commands are self-explanatory the dart pub updated command will scan your package dependencies and show you if there's anything that can be upgraded you can observe that the analyzer package has a new version available however due to some transitive dependencies that use the previous version before this it can't be updated since it could break some implementations finally it is time to end this tutorial i hope you finally understood what dart packages and dependencies really are and how to use and manage them with the pub package manager in the next tutorial we'll take a look over the interesting topic of effective dart in which i'll tell you some of the rules for a consistent robust and maintainable code as always if you like this tutorial don't forget to smash that like button subscribe to my channel and share the video with all of your friends and colleagues in pursuit of top tier development until next time as always take care wicked is out bye bye
Info
Channel: Flutterly
Views: 1,820
Rating: undefined out of 5
Keywords: dart, dart tutorial, dart packages, packages, pubspec.yaml, pubspec, pubspec file, pub, pub package manager, package manager, dart package manager, dart package, dart packages in depth
Id: DciQbO_97oM
Channel Id: undefined
Length: 19min 9sec (1149 seconds)
Published: Thu Jun 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.