This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

preface

Front-end engineering has always been a hot topic and has always been concerned by everyone. Especially in recent years, the development of the front end is changing with each passing day, although it is a rising star but savage growth has become a highly influential industry. However, the rapid development of the whole front-end ecology is inseparable from a topic is how to define front-end engineering, I also found some information on the Internet, nothing more than some grand and broad concepts. And recently just in the interpretation of Vue source code, and involves the concept of front-end engineering, so I want to write an overview according to their own understanding, I hope to write at the same time to deepen the understanding, but also hope to help friends understand front-end engineering.

What is front-end engineering

Front-end engineering is the standardization, instrumentalization, standardization, simplification and automation of front-end development process by using software engineering technology and methods. Its main purpose is to improve the development efficiency in the development process and reduce unnecessary repeated development time.

How to do front-end engineering

Personally, in order to do front-end engineering, at least the following points are needed:

  • Project engineering
  • Code modularization
  • Page componentization
  • Code normalization
  • Build automation

Project engineering

Engineering is not a technology but an idea. It refers to the use of software engineering techniques and methods to develop, maintain, and manage front-end projects. For example, in a large Web project, the structure of the whole project is complex and tedious, which requires the cooperation of multiple teams to be well controlled, so we need to have a higher level of thinking to organize the technical selection, various specifications and project construction of the whole project.

Code modularization

Code modularization can be understood as the abstract encapsulation of a group of user-defined businesses, which can be encapsulated and combined according to the content of the project, such as login module, shopping cart module and order module. Module maintainability is good, combination is flexible, convenient to call, many people cooperate without interference.

Page componentization

Page componentization refers to the encapsulation of a specific function. For example, all tables can be encapsulated as table components for unified use to achieve component reuse and improve development efficiency.

Code normalization

The specification made in the early stage of project planning is extremely important for the later development. The general specifications include:

  • Naming conventions,
  • Coding specification,
  • Structural specifications,
  • Interface specification (front and back end intermodulation interface specification),
  • Document specification,
  • Component specification,
  • Code versioning specification (submission code remarks description specification),
  • UI specifications (e.g. icon libraries, etc.)
  • .

There is no uniform code specification, and each team can create its own set of specifications. Specific achieve what level, basically still have to see you refine to what level.

Build automation

Automation there are also many automation tools (Webpack, rollup, glup……) Do it for us, e.g.

  • Continuous integration
  • Automated build
  • Automated deployment
  • Automated testing

To sum up: any repetitive work done by a simple machine should be done by a machine.

Front-end engineering conclusion

The above concept in software engineering are actually very basic common sense, is mainly the front-end development is fast, the ecological speed become large developed from simple front page as a front-end engineering, as a front-end developer I feel focus on the development of technology is king, especially in this moment is really brutal growth is not to advance is to go back. As an old ape, the people around me are really the same every year. It is really the saying that you should learn quietly and surprise everyone. It is true that some people learn a new skill after not seeing each other for a period of time. Some people will double their salary after not masturbating for a few days. Some people have made 100 dollars a year after not seeing each other for a year or two. Ah ~ this is probably life! But when you are aware of it, do you also want to try to be better?

So much for front-end engineering, and a bit more modularity. Because the next article: Vue source code series (a) : Vue source code interpretation of the correct posture needs to be used.

Modular scheme

Here is a technical explanation of the points involved in engineering – > modular solutions: AMD, CMD, CommonJS, UMD and ES Modules.

AMD

AMD (Asynchronous Module Definition) means “Asynchronous Module Definition”. In the browser, due to the constraints of network and browser rendering, synchronous loading cannot be used, only asynchronous loading can be used. Hence the AMD specification. It is a browser-side modular development specification for asynchronously loading dependent modules and loading them ahead of time. AMD is the standardized output of RequireJS module definition in the promotion process. It is a concept. RequireJS is the realization of this concept. All statements that depend on this module are defined in a callback function that will not run until the load is complete. This works well with the browser’s asynchronous module loading environment 📢 Note: browser synchronous module loading can cause performance, availability, debugging, and cross-domain access issues

Require mainly solves the following problems:

  • Files can have dependencies, and the dependent file needs to be loaded by a browser prior to the dependent file
  • Browsing stops rendering while JS is loading. The more files you load, the longer the page takes to respond
  • Asynchronous preloading

Grammar:difine(id, dependencies, factory)

AMD defines only one function, “define”, which is the global variable define(ID? , dependencies? , factory), the parameters are module name, dependency, and factory method, respectively

id

It’s a string. It refers to the name of the module in the definition. This parameter is optional. If this parameter is not provided, the name of the module should default to the name of the specified script requested by the module loader. If provided, the module name must be “top-level” and absolute (relative names are not allowed).

dependencies

Is an array of modules that the module in the definition depends on. A dependency module must be executed according to the module’s factory method priority, and the results of the execution should be passed as arguments to the factory method (of the defining module) in order of position in the dependency array

factory

Factory method. Initialize the function or object to execute for the module. If it is a function, it should be executed only once. If it is an object, this object should be the output value of the module.

userequire.jsTo implement the modularization of AMD specifications:

  • withrequire.config()Specify a reference path
  • withdefine()To define a module
  • withrequireTo load the module
define('moduleName'['a'.'b'].function(ma, mb) {
    return someExportValue;
})

require(['a'.'b'].function(ma, mb) {
    // do something
})
Copy the code

CMD

CMD is another modularization solution, which is similar to AMD, except that AMD advocates relying on front-loading and early execution, while CMD advocates relying on nearby and delayed execution. CMD is the normalized output of module definition in SeaJS promotion process.

In the CMD specification, a module is a file. Therefore, the file name is often used as the module ID. CMD advocates the nearest dependency, so it is generally not written in define parameters, but in Factory: DEFINE (ID, DEps, Factory) ID and DEps parameters can be omitted. When omitted, it can be automatically generated by the build tool.

Note: The use of define with id and deps parameters does not belong to the CMD specification, but to the Modules/Transport specification.

CMD solves the following problems:

The specification addresses how to write code for modularity in the browser environment and defines characteristics that modularity can follow to support shared modules

  • Module single file
  • New free variables within the scope of the module should not be introduced
  • Lazy loading

Grammar:factory: function(require,exports,module) {}

  • The first argument to require: factory, used to retrieve interfaces provided by other modules
  • Exports: an object that provides module interfaces
  • Module: An object that stores properties and methods associated with the current module
// Define modules with no dependencies
define(function(require.exports.module){
    exports.xxx = value
    module.exports = value
})
 
// Define dependent modules
define(function(require.exports.module){
    var module = require('./module.js')
    require.async('./module.js'.function(m2) {
        // do something
    })
    export.xxx = value
})
 
// Import modules
define(function(require.exports.module){
    const module = require('./module.js')
    module.show()
})
Copy the code

CommonJS

Starting from CommonJS, the starting point of CommonJS is that JS has no perfect module system, less standard library, and lack of package management tools. Node.js is the best practitioner of Commonjs. With the rise of Node.js, the ability to run JS anywhere, especially on the server, and develop large projects, Commonjs was born. Commonjs has four important environment variables that support modular implementations: Module, exports, require, and Global. In practice, module.exports defines the interface for the current module to export (directly using exports is not recommended), and requires loads the module. Commonjs loads modules synchronously. On the server, module files can be stored on local disk and read very quickly, so there is no problem with this. However, on the browser side, the more reasonable loading mode should be asynchronous loading due to network and other reasons.

  • Exports = fn or exports. XXX = fn (not recommended to use exports directly)
  • Const XXX = require(‘ XXXX ‘)

Commonjs specification:

  • A file is a module with a separate scope;
  • Variables, functions and objects defined in normal mode belong to this module;
  • Load modules via require;
  • Exports or exports to expose the contents of modules;

Note:

  • Module. exports overwrites exports when both modules and exports exist;
  • Exports is the same as module.exports when all modules are exports;
  • Exports is a subset of module.exports;
  • All code runs in the module scope and does not pollute the global scope;
  • Modules can be loaded multiple times, but only on the first run. The results are then cached. Subsequent loads read the cached results directly;
  • Modules are loaded synchronously in the order in which the code appears;
  • __dirname represents the file path of the current module
  • __filename indicates the file path + filename of the current module file

UMD

UMD is one idea, and it is an approach that integrates the AMD, CMD, and Commonjs specifications. Define. Amd/define. CMD/module/define

Principle of operation

UMD determines whether node.js modules are supported (export exists). If yes, use node.js module mode. Then check whether AMD is supported (define is not present). If yes, load the module in AMD mode.

(function (root, factory) { 
    if (typeof define === 'function' && (define.amd || define.cmd)) {
        //AMD,CMD 
        define(['b'].function(b){ 
            return (root.returnExportsGlobal = factory(b)) 
        });
    } else if (typeof module= = ='object' && module.exports) {
        //Node, CommonJS, etc
        module.exports = factory(require('b'));
    } else {
    // Public exposure to global objects
    root.returnExports = factory(root.b); 
    } 
}(this.function (b) {
    return {}; 
}));
Copy the code

ES Module(ESM)

ESM implements modular functions on the level of language standards, and the implementation is quite simple, aiming to become a common modular solution for browsers and servers. Its modular functions are mainly composed of two commands: exports and import.

  • The export command specifies the external interface of the module
  • The import command is used to enter functions of other modules

The ESM also provides the export default command, which specifies the default output for the module. The corresponding import statement does not need curly braces, which is also closer to AMD’s reference writing.

ESM modules are not objects, and import commands are statically parsed by the JavaScript engine, introducing module code at compile time. Instead of loading at runtime, you can’t do conditional loading. This makes static analysis possible.

export

Export can export objects containing multiple attributes and methods, while Export default can export only one unnamed function, which can be introduced by *import *. We can also use require directly because Webpack enables server dependencies.

import

import { fn } from './xxx'    // export Export mode
import fn from './xxx'           // export default Export mode
Copy the code

Conclusion:

AMD is an asynchronous load dependent module, and will load in advance and can load multiple modules. Mainly used in the browser environment, require.js is a modular tool that complies with the AMD specification. It is declared by define() and loaded by require(“,function() {}). Disadvantages: high development cost, difficult to read and write code, semantics of module definition is not smooth; Does not accord with the general modular way of thinking, is the realization of a compromise.

CMD is similar to AMD in that it keeps it as simple as possible and maintains great compatibility with Modules specifications of CommonJS and Node.js. Advantages: Proximity, lazy execution can easily run in Node.js; Disadvantages: rely on SPM packaging, the loading logic of modules is too heavy;

The difference between AMD and CMD

  1. AMD is the standardized output of RequireJS module definition in the process of promotion, CMD is the standardized output of SeaJS module definition in the process of promotion.
  2. For dependent modules, AMD isPerformed in advanceCMD isDelay the. However, since 2.0, RequireJS can also be delayed execution (according to the writing method, the processing method is different);
  3. CMD to promoteRely on nearbyAMD recommendedRely on the pre –;
  4. The DEFAULT AMD API isOne for more than oneThe CMD API is strictly differentiated and respectedResponsibility of the single. For example, in AMD, require is divided into global require and local require, both called require. In CMD, there is no global require, but according to the completeness of the module system, seajs.use is provided to realize the loading and starting of the module system. In CMD, every APISimple and pure.“Note: this difference between AMD and CMD comes from the answer of the Jade Uncle”

CommonJS is a synchronous loading, mainly node.js (server application) modular mechanism. Exports declarations through module.exports and loads them through require(“). Each file is a module with its own independent scope, and the variables, attributes, functions, and so on in the file cannot be accessed by the outside world. Node will cache the module and fetch it from the cache on the second load.

UMD is an approach that integrates the AMD, CMD, and Commonjs specifications. Use judgment to decide which approach is currently supported.

ES Module is exported through exports Default. Use import to import, and you can deconstruct the exported content. ES Module modules run differently from Commonjs. When the script is statically analyzed by the JS engine, a read-only reference is generated when a module load instruction is encountered. Wait until the script is actually executed. In the process of reference to the execution, the value in the module changes, and the imported here will also change. The ES Module Module is introduced dynamically. Values are not cached. A module is always bound to its own module.





The end of this article, if useful to you also want to like and follow 🙏🙏, thank you very much.