js modular development

js modular development history

The first stage

When the JavaScript language was first born, it was only used to implement some small effects on the page.

At that time, the JS used on a page might only be a few hundred lines of code.

In this case, some defects in the language itself are often intentionally ignored by everyone, because the size of the program is too small. As long as the developers are careful, they often do not cause any problems.

At this stage, there are no professional front-end engineers. Since there are too few things to do on the front-end, this part of the work is often completed by back-end engineers.

Major events in the first phase:

  • In 1996, NetScape submitted the JavaScript language to a European standards-setting block ECMA (European Computer Manufacturers Association)
  • In 1998, NetScape failed in the competition with Microsoft's browser IE and declared bankruptcy.

second stage

The emergence of ajax has gradually changed the role of JavaScript in browsers. Now, it can not only achieve small effects, but also interact with the server to change the data with a better experience

The amount of JS code began to gradually increase, from the first few hundred lines to tens of thousands of lines later, and the front-end program gradually became complex.

The pressure on back-end developers is gradually increasing, leading some companies to recruit professional front-end developers

But at this time, the treatment of front-end developers is far less than that of back-end developers, because the development tasks undertaken by front-end developers are relatively simple compared to back-end development. After just one month of intensive training, they can become a satisfactory Front-end development needs

The fundamental reason is that there are still several big problems that have not been solved in front-end development. These problems have seriously restricted the further expansion of the scale of front-end programs:

  1. The browser interprets and executes JS too slowly
  2. The client computer configuration is insufficient
  3. More code brings problems such as global variable pollution and dependency confusion.

The above three problems are like Achilles' heels, becoming the lingering shadow and original sin of front-end development.

At this stage, front-end development is in a very awkward position, wandering helplessly between the traditional development model and the separation of front-end and back-end.

Major events in the second phase:

  1. After IE browser dominated the market, it almost stopped updating
  2. The abortion of ES4.0 resulted in almost no changes in the JS language in 10 years
  3. ES5 was released in 2008, which only solved the bad situation of insufficient JS API.

The third phase

Time continued to move forward, and in 2008, Google's V8 engine was released, pushing the execution speed of JS to a new level, even comparable to back-end languages.

Moore's Law continues to ferment, and the configuration of personal computers begins to leap forward

Suddenly, the two major problems restricting front-end development were solved. At this time, only the last problem was still stubbornly resisting, namelyglobal variable pollution and dependency confusion Once the problem of a> is solved, the front-end can break through all obstacles, and the future is limitless.

As a result, front-end developers all over the world are having heated discussions in the community, trying to find a solution to this problem...

In 2008, a young man named Ryan Dahl was struggling with one thing. He needed to write a high-performance web service on the server side. The service had such high performance requirements that all existing web service products on the market were Can't meet demand.

After analysis, it was determined that if you want to achieve high performance, you must reduce threads as much as possible, and to reduce threads, you cannot avoid using asynchronous processing solutions.

At first, he planned to write it himself using C/C++ language, but the process was too painful.

Just when he was at a loss, the release of Google's V8 engine caught his attention. He suddenly discovered that isn't JS the best language for implementing web services? It is inherently single-threaded and based on async! With the support of the V8 engine, its execution speed can fully support a server. Moreover, V8 is released by the famous Google company. Google will continue to optimize V8. With such a good thing that saves money and effort, why should I write it myself?

Therefore, it was based on the open source V8 engine, made some modifications to the source code, and quickly completed the project.

In 2009, Ryan launched the web service project named nodejs.

From then on, JS took over the backend for the first time and was no longer a "toy" language that had to be attached to the browser.

It was also from this moment on that people realized that JS (ES) is a real language, which is executed depending on the running environment (runtime) (host program)

 

The birth of nodejs has brought the last problem in JS to the forefront, namelyglobal variable pollution and dependency confusionproblem a>

Until, nodejs is the server side. If this problem is not solved, module development will not be possible, and modular development is an essential content for all back-end programs.

After intense discussions in the community, a modular solution was finally formed, namely the famous CommonJS. This solution completely solved the problems of global variable pollution and dependency confusion.

As soon as this solution came out, it was immediately supported by nodejs. As a result, nodejs became the first platform to implement modularization for the JS language, laying a practical foundation for the rapid development of the front-end.

Major events that occurred during this stage:

  • In 2008, V8 was released
  • IE's market is gradually being eroded by firefox and chrome, and there is no way back now
  • In 2009, nodejs was released and came with the commonjs modular standard

Stage 4

The emergence of CommonJS has opened up the minds of front-end developers

Since the backend can use modular JS, why can’t the browser, the old club of JS language, also do it?

As a result, some people began to think of ways to apply CommonJS to browsers.

But there are many difficulties here (explained in detail in the course)

There are always more solutions than difficulties. Some developers think that since it is difficult to apply CommonJS to browsers, why don't we redefine a modular standard ourselves? Do we have to use the CommonJS standard?

So soon, the AMD specification was released. It solved the same problems as CommonJS, but could better adapt to the browser environment.

Subsequently, the CMD specification was released, which improved the AMD specification.

These behaviors have received close attention from ECMA officials...

In 2015, ES6 was released, which proposed an official modular solution - ES6 Modular

Since then, modularity has become a unique property of JS itself. This language finally has the capital to compete with other languages ​​and has become a formal language that can write large-scale applications.

At the same time, many developers and technology manufacturers have already foreseen the infinite potential of JS, so the following story came up

  • Since JS can also write large-scale applications, it naturally needs a development framework to solve complex problems like other languages.
    • Front-end development frameworks such as Angular, React, and Vue emerge
    • The emergence of back-end development frameworks such as Express and Koa
    • Various back-end database drivers appear
  • To develop large-scale applications, the support of various practical third-party libraries is naturally indispensable.
    • The emergence of npm package manager makes it extremely convenient to use third-party libraries
    • Build tools such as webpack appear specifically for packaging and deployment
  • Since JS can be placed in a server environment, why can't it be placed in other terminal environments?
    • Electron released, can use JS language to develop desktop applications
    • Technologies such as RN and Vuex are released, and mobile applications can be written using JS language
    • Various small programs appear, and you can use JS to write small programs that are attached to other applications.
    • There are currently many manufacturers committed to applying JS to various other terminal devices, eventually forming a large front-end ecosystem.

It can be seen that the emergence of modularization is the cornerstone of JS leading to large-scale applications. If you learn modularity well, you will have the basic skills to write large-scale applications.

CommonJS

In nodejs, since there is only one entry file (startup file), and developing an application will definitely involve the cooperation of multiple files, therefore, nodejs's demand for modularity is much greater than that of the browser.

Since nodejs was first released, there was no unified and official modular specification for the front end, so it chose to use CommonJS provided by the community as the modular specification.

Before learning CommonJS, first understand two important concepts: Export of module and module Import

Export of modules

To understand the export of modules, we must first understand the meaning of modules

What is a module?

A module is a JS file that implements some functions, hides its own internal implementation, and provides some interfaces for use by other modules.

The module has two core elements: Hide and Expose

What is hidden is its own internal realization

Exposed is the interface that is expected to be used by the outside world

Any normal modularization standard should hide all implementations in the module by default and expose the interface through some syntax or api calls.

The process of exposing the interface is the export of the module

 

Import of modules

When you need to use a module, the exposed part (exported part) of the module is used, and the hidden part can never be used.

When a module is used through a certain syntax or API, this process is called module import.

CommonJS specification

CommonJS usesexports to export modules, require to import modules

The specific specifications are as follows:

  1. If a JS file existsexports orrequire , the JS file is a module
  2. All code in the module is hidden code, including global variables and global functions. These global contents should not cause any pollution to global variables.
  3. If a module needs to expose some APIs for external use, it needs to be exported through exports, exports is an empty object, you can add any content that needs to be exported to this object
  4. If a module needs to import other modules, it is implemented through require, require< a i=4> is a function that returns the entire content exported by the module by passing in the path of the module

nodejs implementation of CommonJS

In order to implement the CommonJS specification, nodejs does the following processing for the module

  1. In order to ensure efficient execution, only necessary modules are loaded. nodejs will load and execute the module only when the require function is executed

Nodejs import module uses a relative path and must start with ./ or ../

  1. In order to hide the code in the module, when nodejs executes the module, it will place all the code in the module into a function for execution to ensure that global variables are not polluted. (function(){  //Code in module  })( )
  2. In order to ensure the smooth export of module content, nodejs has done the following processing (function(module){ module.exports = {}; < /span>  return< /span> module.exports; })()//Code in module exports = module.exports;  var  
    1. Initialize a value before the module starts executingmodule.exports = {}
    2. module.exportsThat is, the export value of the module
    3. In order to facilitate developers to export conveniently, nodejs declares a variable after initializingmodule.exports< a i=3>exports = module.exports, so you can directly use exports to export
    4. If the code in the module reassigns module.exports, then exports will not be associated with module.exports, and using exports again will be invalid.
  1. In order to avoid loading the same module repeatedly, nodejs enables module caching by default. If the loaded module has already been loaded, the previous export result will be automatically used.

The problem with browser-side modularity

How CommonJS works

When usingrequire(module path) to import a module, node will do the following two things (regardless of module cache):< /span>

  1. Find the native file through the module path and read the file content
  2. Put the code in the file into a function environment for execution, and use the value of module.exports after execution as the return result of the require function

It is these two steps that enable CommonJS to be well supported on the node side.

It can be considered thatCommonJS is synchronous, and you must wait until the file is loaded and the code is executed before it can continue to execute backwards

When the browser encounters CommonJS

When trying to put CommonJS on the browser side, we encountered some challenges

  1. To load a JS file, the browser needs to read it remotely from the server, and the efficiency of network transmission is far lower than the efficiency of reading local files in the node environment. Since CommonJS is synchronous, this will greatly reduce running performance
  2. If you need to read the content of a JS file and put it into an environment for execution, you need the support of the browser manufacturer, but the browser manufacturer is unwilling to provide support. The biggest reason is that CommonJS is a community standard and not an official standard.

new norm

Based on the above two reasons, browsers cannot support modularity

But this does not mean that modularity cannot be implemented in browsers

To achieve modularity in the browser, as long as the above two problems can be solved

The solution is actually very simple:

  1. Is loading JS remotely a waste of time? Just make it asynchronous and call a callback after loading is complete.
  2. Does the code in the module need to be placed in a function for execution? When writing a module, just put it directly in the function.

Based on this simple and effective idea, AMD and CMD specifications emerged, which effectively solved the problem of browser modularization.

However, with es6 modularization, amd and cmd are no longer used.

Introduction to ES6 Modularity

The ECMA organization referred to many community modular standards, and finally in 2015, with the release of the official modular standard for ES6, it later became ES6 modular

ES6 modularity has the following characteristics

  1. Use dependencypredeclaration to import modules
    1. Dependency delayed declaration (commonjs)
      1. Advantages: Can sometimes improve efficiency
      2. Disadvantages: Module dependencies cannot be determined at the beginning (more ambiguous)
    1. dependency predeclaration
      1. Advantages: Module dependencies can be determined at the beginning
      2. Disadvantages: sometimes less efficient
  1. Flexible multiple import and export methods
  2. Canonical path notation: all paths must start with ./ or ../

Basic import and export

Introduction of modules

NOTE: This part of the non-modular standard

Currently, browsers use the following method to introduce an ES6 module file

<script src="入口文件" type="module">

Basic export and import of modules

There are two types of module import and export in ES6:

  1. Basic import and export
  2. Default import and export

 

Basic export

Similar to exports.xxx = xxxx

There can be multiple basic exports, each must have a name

The syntax for basic export is as follows:

export declare expression

export let a=1;

ecport function test(){}

or

export {Ingredient name code}

let age=18;

let sex=male;

export{age,sex}

Since the basic export must have a name, it is required that the export content must be followed by declaration expression or Named symbol

Basic import

Since you are using dependency preloading, therefore, to import any other modules, the import code must be placed before all code

For basic export, if you want to import, use the code below

import {imported symbol list} from "Module path"

Pay attention to the following details:

  • When importing, you can rename the imported symbols through the keywordas
  • The symbols used when importing are constants and cannot be modified.
  • You can use the * sign to import all basic exports to form an object, and the * must be renamed.

Default import and export

Default export

Each module, in addition to multiple basic exports, is also allowed to have a default export

The default export is similar to CommonJSmodule.exports. Since there is only one, there is no need to name it

The specific syntax is

export default Default exported data

or

export {默认弼传的数位as default}

Since only one default export is allowed per module, multiple default export statements cannot appear per module.

Default import

If you want to import the default export of a module, you need to use the following syntax

import Receive variable namefrom "Module path "

Similar to in CommonJS

var receives variable name = require("module path")

Since the variable name is defined by itself when imported by default, there is no alias.

If you want to import both the default and basic exports of a module, you can use the following syntax

import receives default exported variables, {receives basic exported variables} from "< /span>"Module path

Note: If you use the * sign, all basic exports and default exports will be aggregated into one object, and the default export will exist as the attribute default

Additional details about ES6 modularity

  1. Try to export immutable values

When exporting a content, try to ensure that the content is immutable (this is the case in most cases)

Because, although the imported content cannot be changed after importing, changes may occur inside the imported module, which will cause some unpredictable things to happen.

2. You can use unbound imports to execute some initialization code

If we just want to execute some code in a module without importing anything from it, we can use unbound imports:

import "model road diameter"

3. You can use binding and export to re-export content from another module

Sometimes, we may need to use one module to encapsulate multiple modules, and then selectively export the contents of multiple modules separately. This can be easily done using the following syntax

export {Bound identifier} from "Module path"

 

Guess you like

Origin blog.csdn.net/Vince_13/article/details/132432908