SeaJS getting started tutorial series using SeaJS (2)
This article mainly introduces SeaJS, a series of getting started tutorials, focuses on the use of SeaJS and the use of key methods. For more information, see
Download and install
To use SeaJS in a project, all you need to do is download sea. js and place it in a certain position of your project.
The SeaJS project is currently hosted on GitHub and the home page is https://github.com/seajs/seajs. You can download sea. js (Compressed) or sea-debug.js (uncompressed) under the build directory of its git repository ).
After the download is complete, put it in the corresponding position of the project, and then introduce it through the <script> tag on the page, you can use SeaJS.
SeaJS basic development principles
Before discussing the specific use of SeaJS, we will first introduce SeaJS's modular concept and development principles.
The basic principle for developing JavaScript using SeaJS is: Everything is a module. After SeaJS is introduced, writing JavaScript code becomes a compilation of one module after another. The concept of modules in SeaJS is somewhat similar to that in object-oriented classes. modules can have data and methods, data and methods can be defined as public or private. Public data and methods can be called by other modules.
In addition, each module should be defined in a separate js file, that is, a corresponding module.
The following describes how to write and call modules.
Module definition and writing
Module definition function define
Use the "define" function in SeaJS to define a module. Because the SeaJS documentation does not have a complete reference for define, I read the SeaJS source code and found that define can receive three parameters:
The Code is as follows :/**
* Defines a module.
* @ Param {string =} id The module id.
* @ Param {Array. | string =} deps The module dependencies.
* @ Param {function () | Object} factory The module factory function.
*/
Fn. define = function (id, deps, factory ){
// Code of function...
}
The above is extracted from the SeaJS source code. The parameters that define can receive are module IDs, dependent module arrays, and factory functions. After reading the source code, I found that define's resolution rules for the number of different parameters are as follows:
If there is only one parameter, it is assigned to factory.
If there are two parameters, the second value is assigned to the factory; the first value is assigned to the deps if it is an array; otherwise, the second value is assigned to the id.
If there are three parameters, they are assigned to id, deps, and factory respectively.
However, almost all the places that use define, including the official example of SeaJS, only one factory function is passed in, similar to the following code:
The Code is as follows:
Define (function (require, exports, module ){
// Code of the module...
});
Personally, we recommend that you follow the standard of the official SeaJS example and use a define parameter to define the module. What will id and deps do?
Id is the identifier string of a module. If define has only one parameter, the id is assigned the absolute path of the js file by default. For example, in the. js file under example.com, use define to define the module, the ID of this module will be assigned to the http://example.com/a.js, there is no special need to do not input the id. Deps generally does not need to be passed in. You can use require to load the required modules.
Factory function Parsing
Factory functions are the main body and focus of the module. When only one parameter is passed to define (recommended), this parameter is the factory function. At this time, the three parameters of the factory function are:
1. require-module Loading Function, used to record the dependency module.
2. exports -- interface point: expose data or method definitions to external calls.
3. module -- metadata of the module.
You can select whether to display the specified parameters as needed.
Let's talk about the module. A module is an object that stores the metadata of a module as follows:
1. module. id -- ID of the module.
2. module. dependencies -- an array that stores the IDs of all modules that this module depends on.
3. module. exports -- and exports point to the same object.
Three Writing module Modes
The first mode of defining the module is based on the exports mode:
The Code is as follows:
Define (function (require, exports, module ){
Var a = require ('A'); // introduce module
Var B = require ('B'); // introduce Module B
Var data1 = 1; // Private Data
Var func1 = function () {// Private Method
Return a. run (data1 );
}
Exports. data2 = 2; // Public Data
Exports. func2 = function () {// public Method
Return 'hello ';
}
});
The above is a more "authentic" module definition mode. In addition to attaching public data and methods to exports, you can also directly return an object representation module. The following code has the same function as the above Code:
The Code is as follows: define (function (require ){
Var a = require ('A'); // introduce module
Var B = require ('B'); // introduce Module B
Var data1 = 1; // Private Data
Var func1 = function () {// Private Method
Return a. run (data1 );
}
Return {
Data2: 2,
Func2: function (){
Return 'hello ';
}
};
});
If the module definition has no other code, only one object is returned. You can also simplify the writing as follows:
The Code is as follows: define ({
Data: 1,
Func: function (){
Return 'hello ';
}
});
The third method is suitable for the module defining pure JSON data.
Module loading and reference
Module addressing Algorithm
As mentioned above, a module corresponds to a js file. When loading a module, a string parameter is generally provided to indicate the module required by the loading function, therefore, we need a set of parsing algorithms from string identification to the path of the file where the actual module is located. SeaJS supports the following identifiers:
Absolute address: returns the absolute path of the js file.
For example:
The Code is as follows: require ("http: // example/js/");
Load http: // example/js/a. js.
Relative address: Use the relative address of the js file where the load function is called to find the module.
For example, load
Copy the Code as follows: require ("./c ");
Load http: // example/js/c. js.
Base Address: If the loaded string identifier is neither an absolute path nor begins with "./", it is addressed relative to "base" in the global configuration of SeaJS. This method will be discussed later.
Note that the extension ". js" is not required when loading the module. SeaJS will automatically add ". js ". However, it is not added in the following three cases:
When loading css, for example:
Copy the code as follows: require ("./module1-style.css ");
Path contains "?" Such:
Copy the Code as follows: require (<a href = "http: // example/js/a. json? Cb = func "> http: // example/js/a. json? Cb = func </a> );
When the path ends with "#", for example:
Copy the Code as follows: require ("http: // example/js/a. json #");
Based on different application scenarios, SeaJS provides three loading module APIs: seajs. use, require, and require. async, which are described below.
Seajs. use
Seajs. use is mainly used to load the entry module. The entry module is equivalent to the main function of the C program and also the root of the entire module dependency tree. In the small example of TinyApp above, init is the entry module. The usage of seajs. use is as follows:
The Code is as follows:
// Single Mode
Seajs. use ('./');
// Callback Mode
Seajs. use ('./A', function (){
A. run ();
});
// Multi-module Mode
Seajs. use (['./A','./B '], function (a, B ){
A. run ();
B. run ();
});
Generally, seajs. use Only loads the entry module on the page. SeaJS parses all the dependency modules along the entry module and loads them. You can also write the statement as follows:
The Code is as follows:
<! Doctype html>
<Html lang = "zh-CN">
<Head>
<Meta charset = "UTF-8">
<Title> TinyApp </title>
</Head>
<Body>
<P class = "content"> </p>
<Script src = "./sea. js" data-main = "./init"> </script>
</Body>
</Html>
This method makes html more concise.
Require
Require is the main module Loading Method of SeaJS. When other modules are required in a module, require is generally used for loading:
The Code is as follows: var m = require ('/path/to/module/file ');
Here we will briefly introduce the automatic loading mechanism of SeaJS. As mentioned above, after using SeaJS, html only needs to include sea. js. How can other js files be loaded in? SeaJS will first download the entry module, and then follow the entry module to use regular expressions to match all require in the code, and then download the corresponding js file according to the file path ID in require, perform similar operations on the downloaded js file after iteration. The whole process is similar to graph traversal (because cross-cycle dependency may exist, the entire dependent data structure is a graph rather than a tree ).
After understanding the above, the following rules are well understood:
The path ID passed to require must be a string literal instead of an expression. For example, the following require method is incorrect:
Copy the Code as follows: require ('module' + '1 ');
Require ('module'. toLowerCase ());
This will make SeaJS unable to perform correct regular matching to download the corresponding js file.
Require. async
As mentioned above, SeaJS will use static analysis to record all required js files at a time when opening the html page. If you want to download a js file only when it is used, you can use require. async:
The Code is as follows: require. async ('/path/to/module/file', function (m ){
// Code of callback...
});
In this way, the corresponding js file will be downloaded only when this module is used, and JavaScript code will be loaded on demand.
Global configuration of SeaJS
SeaJS provides a seajs. config method to set global configuration and receive a configuration object that represents global configuration. The usage is as follows:
The Code is as follows: seajs. config ({
Base: 'path/to/jslib /',
Alias :{
'App': 'path/to/app /'
},
Charset: 'utf-8 ',
Timeout: 20000,
Debug: false
});
Base indicates the base address path for base address addressing. For example, if base is set to http://example.com/js/3-party:
Copy the Code as follows: var $ = require ('jquery ');
Loads the http://example.com/js/3-party/jquery.js.
Alias can be used to set abbreviations for long common paths.
Charset indicates the charset attribute of the script label when downloading js.
Timeout indicates the maximum duration of the downloaded file, in milliseconds.
Debug indicates whether the job is in debugging mode.
How to Use SeaJS with existing JS Libraries
To use existing JS libraries such as jQuery and SeaJS together, you only need to encapsulate the existing libraries according to the module definition rules of SeaJS. For example, the following is an encapsulation method for jQuery:
The Code is as follows: define (function (){
// {Start of original jQuery code
/*!
* JQuery JavaScript Library v1.6.1
* Http://jquery.com/
*
* Copyright 2011, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* Http://jquery.org/license
*
* Includes Sizzle. js
* Http://sizzlejs.com/
* Copyright 2011, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Thu May 12 15:04:36 2011-0400
*/
//...
// }}} JQuery original code ended
Return $. noConflict ();
});
Packaging and deployment of the SeaJS Project
SeaJS was originally integrated with a packaging and Deployment Tool spm. Later, the author split the spm out of SeaJS and became a separate project for a more KISS. The core idea of spm is to merge and compress the code of all modules into the entry module. Due to the characteristics of SeaJS, html can be easily switched between the development environment and the production environment without any changes. However, since spm has not yet released the official version, I am not going to detail this article. If you are interested, please refer to the github project homepage https://github.com/seajs/spm /.
In fact, because the JS merge and compression tools used by each project are different, spm may not be fully suited to each project. After learning about the principles of SeaJS, you can write a merge and package script that meets the characteristics of your project.