Lessons: 16Length: 1.8 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.1 Defining Modules

Modules are the backbone of our application and a fundamental reason to use RequireJS, so let's see exactly what a module is and how we can define one, including the different ways that we can specify dependencies.

2.1 Defining Modules

Hey, in this lesson, we'll see how we can define an AMD module. Although RequireJS can load regular JavaScript files, this is generally reserved for older scripts that aren't defined as modules. Whenever we're writing a new application, to get the most out of Require, we're going to want to create modules. A single JavaScript file should contain a single AMD module. We should never define two different modules in the same file. We should keep our modules as small as possible and instead opt for more modules rather than fewer files with larger modules inside them. Each module should be responsible for one thing, like a class would be in other languages. Although it may seem unintuitive to opt for a larger number of files in terms of HTTP requests, remember that with Require, the idea is to do an optimized build with r.js and concatenate all of our files together into a single package. We'll cover this later in the course. Okay, so let's create our first module. When we use RequireJS the only globals that should exist are require and define, both of which are functions. As you can probably guess, we use the define function to define a module. So let's create a new file and call it ui_strings in the src directory. [BLANK_AUDIO] So we can pass different arguments into the define method. The simplest type of module that we can create is a module that is simply an object literal. [BLANK_AUDIO] So this module will be used to display strings in different parts of the UI of our app. [BLANK_AUDIO] So like I said, this is the simplest form that the define method can take. And that's simply passing an object literal to the method. Other modules can now load this module and make use of any properties or methods held in the object. This can be useful for very simple modules that have no dependencies or when the module is just data. We'll use this when we add the UI for our app later on. For other modules, we might want to do some setup work or something inside the module instead of just returning a simple object. In this case, we can pass a callback function to the define method. So let's create another new module now. This can also go in the src directory. [BLANK_AUDIO] And we'll call this one task. [BLANK_AUDIO] So this time, let's pass a callback function to the define method. [BLANK_AUDIO] So now we can do any setup work inside the callback before returning a value. We can also pass additional arguments to the define method in different situations. If we pass a string as the first argument, this will be the name of the module. So sometimes, we might wanna do this. So now we've given this module an ID of task. Generally, we don't need to specify names for modules like this as Require will handle it for us and assign modules names based on their location. So let's get rid of it again. [BLANK_AUDIO] So let's define our task module now. And this will define a single task which can be the constructor for task objects. [BLANK_AUDIO] So our basic task will have a couple of different properties, which are whether the task is completed and the name of the task. The name can be passed into the constructor. We'll also want a list module as well to contain the tasks. [BLANK_AUDIO] And we'll call this one list. [BLANK_AUDIO] This module also has no dependencies. So now let's create a module that does have a dependency. Let's add another new file to the src folder and we can call this one task_manager. [BLANK_AUDIO] So when we have a module that has dependencies, we can specify those dependencies using a dependency array, which should be passed to the define method as the first argument. The task_manager module is going to use the task module, so the task module is a dependency. [BLANK_AUDIO] So we can pass this array as either the first or second argument, depending on whether we're using a module ID or not. The array should consist of strings that map to other modules that the module being defined relies on. Each item is a path to the module that we want to use. But we don't need to specify the file name if it's a JavaScript file. The callback function will only be executed once all of the dependencies have loaded and each dependency is passed to the callback function. This is the AMD way of specifying dependencies and is pretty easy to use. The only problem is that when we have a lot of dependencies, it can get a little hard to read. In this case, if we want, we can use a CommonJS style of specifying the dependencies instead. So if we wanted to do that, we would get rid of the task module from the function here, and we would get rid of the dependency array. And instead, our callback function is passed a method called require. We can then use the require method to load our dependencies. [BLANK_AUDIO] Require will still make sure that the callback function isn't invoked until all of the dependencies have loaded and are ready to be used. This is useful, but we'll switch back to the original format for now. And let's just make this module strict. So in this lesson we looked at the different ways we have of defining our module. We can use the AMD way of specifying the modules that we depend upon as an array passed to the define method. In this case, the callback function will automatically be passed a reference to each module and won't be executed until all of the dependencies have loaded. Or we can use the CommonJS style, usually known as the Simplified CommonJS Wrapper, where we don't pass an array of dependence to the define method. And our callback automatically receives the require method, which is what we use to load the dependencies. In this case, the callback function also won't be invoked until all of the dependencies have loaded. We also saw that we can create simple data-only modules by passing just an object literal to the define method, or we can pass a module name as the first argument if we want to. And we can pass a callback function, which is what we use to do any set-up work or to define the functionality of the module. Thanks for watching.

Back to the top