Article From:

1. name conflict

  Start with a simple habit.

  Because I have been doing Java EE development before, in JavaScript development, I have been accustomed to abstracting some of the general functions of the project to form an independent function to facilitate code reuse, such as:

  function css(element, attr) { // Get the CSS attribute value corresponding to attr of element

  // …


  function offset(element) { // Get the position coordinates of element in the document

  // …


  And put these encapsulated functions in a unified tools. JS file.

  If these functions are needed for page functionality implementation, they can be introduced directly.

  In the early days, everything was fine. Everyone also felt that writing such tool files was very convenient for development. Until more and more use, page functions became more and more complex, and the needs of people to achieve were more and more diverse.

  At this time, some people complain because tools.js file is introduced. If you want to define a function that can set the value of CSS attribute, you can only take another function name (such as setCss) instead of using the function name css. Similarly, if you want to set oneThe location coordinates of each element in the entire document, and the offset function name can no longer be used, because that would conflict with the function name defined in the tools. JS file.

  Now that the problem has arisen, it needs to be solved.

  There is a very practical technology in Java, package, which organizes logically related code together and uses “package” to manage it, which is equivalent to folders in the file system. In the file system, the folder is a relatively independent space, do not worry about a folder andNaming conflicts in another folder. The same is true in “packages”, which can solve the problem of file naming conflict. If you want to reuse the resources inside the package outside the package, import the relevant packages directly through import. Concepts like packages, in other languages (e.g.C#) is also called a namespace.

  JavaScript There is no support for native packages or namespaces, but other methods such as objects and closures can be used to achieve similar effects.

  Referring to Java, I use objects in JavaScript to simply modify tools.js files:

  var Util = {

  css : function(element, attr) {

  // …


  offset : function(element) {

  // …



  In this way, when tools. JS file is introduced, to obtain CSS style or document coordinates of elements, it is implemented by a method similar to Util. CSS ()/ Util. offset (). The scope of CSS and offset is in objectsUnder Util, the definition of CSS attributes in global or new objects is unaffected.

  Util This name is also generic. It is usually used as an auxiliary tool definition. In order to reflect the uniqueness of the name, we can continue to learn from the package naming specification in Java (domain name inversion):

  var com = {};

  com.github = {};

  com.github.itrainhub = {};

  com.github.itrainhub.Util = {

  css : function(element, attr) {

  // …


  offset : function(element) {

  // …



  To get CSS style values, you can use the com. github. itrainhub. Util. CSS () method. However, this style of writing increases the difficulty of memory. YUI has a better solution to this problem. First, press and leave the table.

  The use of object writing can solve the naming conflict problem, but it also exposes all members of the object, so that the internal state of the object can be rewritten outside the object. For example, there is a counter inside the object:

  var Util = {

  _count : 0


  Outside the object, you can use Util. _count = 18; it’s not safe to change the value of the counter.

  Variables such as counters may normally exist as private members of the object and do not want to continue to modify their values outside the object. In this case, IIFE (immediate execution function) can be used to design:

  var Util = (function(){

  var _count = 0;

  function _css(element, attr) {

  // …


  function _offset(element) {

  // …


  return {

  css : _css,

  offset : _offset



  In this way, the value of _count can no longer be directly modified externally.

  Namespaces do solve naming conflicts, and we can breathe a sigh of relief for a while.

  2. File dependency

  Then tools. JS continues to develop.

  On the basis of tools. js, some common components of UI layer can be developed, such as magnifiers, wheel-seeding maps and so on, so that wheels need not be repeated when these functions are used in various projects.

  Usually, each UI component exists as a separate JS file, such as a magnifying glass, which can be placed in a zoom. JS file. When using the magnifying glass component, it can be introduced.

  But most of the time, before using zoom. js, you forget to introduce tools. js, then using zoom. JS will make an error, which can not guarantee its normal execution.

  zoom.js The normal execution depends on the use of tools. js. These problems are relatively easy to solve, but as the team grows larger and the business requirements become more complex, the dependencies between components in the project will become more and more complex. For example:

  One day, I expanded the functionality of the zoom. JS component, but in addition to tools. js, I also used another tool, JS component: helper. js. If the zoom. JS component has been used in N places in the project before, I willWe had to search for every reference to zoom. JS globally, plus the reference to helper. js.

  Think again, as the project progresses, we will continue to modify tools. js, add more components component_1. js, component_2. js… Tools.js is used only in some components, and helper is used only in others.Js, and some components use tools. JS and helper. js. As for the maintenance of dependencies between components, the workload can be imagined. If the maintenance of dependencies is guaranteed in a human way, it will almost collapse.

  Why is it so painful to maintain dependencies between components, because JavaScript inherently lacks the syntax to introduce other JS files? Dependency components can be introduced in Java through import, and the @import command is also available in CSS.To introduce other CSS files, but JS can not automatically manage dependencies.

  In addition to the inconvenience of maintenance of dependencies between files, if there are too many components introduced in the page, we have to ensure that the path and sequence of the referenced components can not be wrong. Once there is an error, we have to spend time looking for the error. It is conceivable that the workload is considerable, coupled with the introduction of too many components, and in a synchronous manner.Loading components may also lead to the phenomenon of browser dummy death.

  To solve these problems, the value of modular development is reflected.

  3. Modular development

  3.1 Modularization

  The so-called modularization is to form a relatively independent function into a single file, which can input the specified dependencies and output the specified functions for external calls, while other functions hide the implementation details inside. This will facilitate the reuse of different projects without additional impact on the project.

  The main functions of front-end modular delivery are:

  • Asynchronous loading of JS to avoid browser fake death

  • Manage dependencies between modules to facilitate module maintenance

  With modules, we can use other people’s code more conveniently and load whatever module we want.

  But the premise of using the module is to form the development criteria that can be followed, so that both developers and users can find information. Otherwise, if you have your writing style, I have my writing style, you can’t unify, and you can’t use each other very well.

  At present, the common specification is that the server side uses the CommonJS specification and the client side uses the AMD/CMD specification.

  3.2 CommonJS

  CommonJS The specification came into being in 2009, and Node.js is the implementation of the specification. The CommonJS specification loads modules like this:

  var gulp = require(“gulp”);

  gulp.task(/* Task * /);

  Modules are loaded synchronously, which is suitable for the server side, because the modules read by the server are all on the local disk, and the loading speed is very fast, so they can be loaded synchronously. But in the client browser, because the module is placed on the server side, the module loading depends on the network environment, adding in a synchronous manner.It is possible to “fake death” when loading modules.

  Today, I mainly introduce programming for browsers, not for Node. JS content, so I will not go into the Common JS specification here, knowing that require () is used to load modules.

  3.3 AMD

  Because in browser side, module loading in synchronous mode may lead to false death, so we use asynchronous loading mode to achieve module loading, which gave birth to the AMD specification.

  AMD That is the abbreviation of Asynchronous Module Definition, which means “Asynchronous Module Definition”. AMD Specification:

  AMD The module is loaded asynchronously, and the loading of the module does not affect the operation of the following statements. All statements that depend on the module loaded are defined in a callback function, which is not executed until the module is loaded.

  AMD Require () is also used to load the module. The grammatical structure is as follows:

  require([module], callback);

  module Callback is a callback function parameter, which is executed after all modules are loaded. Such as:

  require([“jquery”], function($){



  3.4 CMD

  CMD Common Module Definition stands for “General Module Definition”. CMD Specification:

  CMD The specification defines the basic writing format and interaction rules of the module. The specification was developed in China and produced by Yubo in the process of promoting SeaJS.

  SeaJS CMD specification is implemented. SeaJS solves the same problem as RequireJS, except that it differs in the way modules are defined and the timing of module loading (running and parsing).

  3.5 AMD Difference from CMD

  AMD RequireJS is the standardized output of module definition in the promotion process.

  CMD SeaJS is the standardized output of module definition in the promotion process.

  The main differences between them are as follows:

  1 For dependent modules, AMD is executed ahead of time and CMD is executed late.

  2 CMD Advocating dependence is near, AMD advocates dependence pre-position.

  3 AMD The default API is a multi-use, CMD API is strictly differentiated, advocating a single responsibility.

  Of course, there are some other differences in detail, just look at the definition of specifications.

Leave a Reply

Your email address will not be published. Required fields are marked *