Full Digest from: ( Good article, suggest go directly to see, the following only in this series of article "History development" space to backup ) http://zhaoda.net/webpack-handbook/module-system.html
Present situation
With the trend of mobile interconnection, more and more websites have evolved from web-based mode to Webapp mode. They run in modern high-level browsers, using newer technologies such as HTML5, CSS3, ES6 and more to develop rich functionality, and Web pages are more than just basic requirements for browsing, and WebApp is usually a single-page application, where each view is loaded asynchronously. This results in more and more JavaScript code being loaded during page initialization and usage, which poses a huge challenge to the front-end development process and resource organization.
The main difference between front-end development and other development work is that the front-end is based on multi-lingual, multi-layered coding and organization work, followed by the front-end product delivery is browser-based, these resources are incrementally loaded to the browser side, how to organize these fragmented code and resources in the development environment, and ensuring that they load and update quickly and gracefully on the browser side requires a modular system that is the ideal modular system that the front-end engineers have been exploring for years.
Evolution of Modular Systems
Module system mainly solves the module definition, dependence and export, first to look at the existing module system.
<script> tags
<script src= "module1.js" ></ script><script src=" module2.js "> </script><script src=" librarya.js "> </script><script src=" module3.js "> </SCRIPT>
This is the most primitive way to load JavaScript files, if each file as a module, then their interface is usually exposed to the global scope, that is defined in the window
object, the interface calls of different modules are a scope, some complex framework, The concept of namespaces is used to organize the interfaces of these modules, typical examples such as the YUI library.
This primitive loading method exposes some obvious drawbacks:
- Variable collisions can be caused by global scope
- Files can only be
<script>
loaded in the order in which they are written
- Developers must subjectively resolve dependencies between modules and code base
- Resources are difficult to manage in large-scale projects, and long-term accumulation of problems leads to a confusing code base
CommonJS
The server-side node. JS follows the COMMONJS specification, the core idea of which is to allow the module to require
synchronously load the other modules to be relied upon by means of a method, and then exports
module.exports
to export the interfaces that need to be exposed.
require("module");require("../file.js");exports.doStuff = function() {};module.exports = someValue;
Advantages:
- Server-side modules for ease of reuse
- There are already nearly 200,000 modules in NPM that can use the module package
- Simple and easy to use
Disadvantages:
- Synchronous modules are not loaded in a browser environment, synchronization means blocking loading, and browser resources are loaded asynchronously
- Cannot load multiple modules in parallel without blocking
Realize:
- Server-side node. js
- Browserify, browser-side CommonJS implementation, can use NPM modules, but the volume of the compiled packaged file may be very large
- Modules-webmake, like browserify, browserify flexible
- The predecessor of Wreq,browserify
Amd
The asynchronous module Definition specification has only one primary interface define(id?, dependencies?, factory)
, which specifies all dependencies when declaring the module, dependencies
and also as a formal parameter, which is factory
pre-executed for the dependent module and relies on the predecessor.
define("module", ["dep1", "dep2"], function(d1, d2) { return someExportedValue;});require(["module", "../file"], function(module, file) { /* ... */ });
Advantages:
- Suitable for loading modules asynchronously in a browser environment
- Multiple modules can be loaded in parallel
Disadvantages:
- Improve the development cost, code reading and writing is more difficult, the definition of the module is not smooth semantics
- Not conforming to the universal modular thinking mode, is a kind of compromise realization
Realize:
Cmd
The Common Module Definition specification is similar to AMD and is kept as simple as possible, and is very compatible with the CommonJS and node. JS Modules specifications.
define(function(require, exports, module) { var $ = require(‘jquery‘); var Spinning = require(‘./spinning‘); exports.doSomething = ... module.exports = ...})
Advantages:
- Rely on the nearest, deferred execution
- Can be easily run in node. js
Disadvantages:
- Depending on SPM packaging, the load logic of the module is biased
Realize:
Umd
The Universal module definition specification is similar to CommonJS and AMD's syntactic sugars and is a cross-platform solution defined by the module.
ES6 Module
The ECMASCRIPT6 standard adds a modular system definition to the JavaScript language level. The design idea of the ES6 module is to make it as static as possible, so that the dependencies of the module can be determined at compile time, as well as the input and output variables. CommonJS and AMD modules can only be identified at runtime.
import "jquery";export function doStuff() {}module "localModule" {}
Advantages:
- Easy to perform static analysis
- Future-oriented ECMASCRIPT standards
Disadvantages:
- Native browser side has not yet implemented this standard
- New command Word, the new version of node. JS is supported
Realize:
The desired module system
Can be compatible with a variety of module style, as far as possible to take advantage of existing code, not just JavaScript modularity, as well as CSS, pictures, fonts and other resources need to be modular.
Front-End Module loading
The front-end modules are executed in the client, so they need to be incrementally loaded into the browser.
Module loading and transfer, we can first think of two extreme ways, one is that each module file is requested separately, the other is to package all modules into a file and then request only once. It is obvious that each module initiates a separate request resulting in too many requests, which causes the application to start slowly, and a request to load all of the modules results in a waste of traffic and a slow initialization process. Neither of these approaches is a good solution, they are too simple and rude.
Block transfer, lazy loading on demand, in the actual use of some modules and then incremental update, is a more reasonable module loading scheme.
To implement a module's on-demand load, you need a process for static analysis and compilation of the modules in the entire code base.
All resources are modules
In the above analysis, the modules we mentioned refer only to JavaScript module files. However, in the front-end development process also involves the style, the picture, the font, the HTML template and so on many resources. These resources also exist in various dialects, such as Coffeescript, less, sass, numerous template libraries, multi-lingual systems (i18n), and so on.
If they can all be seen as modules and can be require
loaded in a way that brings an elegant development experience, such as:
require("./style.css");require("./style.less");require("./template.jade");require("./image.png");
So how do you make it possible to require
load all kinds of resources?
Static analysis
At compile time, the entire code is statically analyzed, the types of each module and their dependencies are analyzed, and then the different types of modules are submitted to the appropriate loader for processing. For example a style module with less, you can first use the less loader to turn it into a CSS module, in the CSS module to insert him into the page of the <style>
tag execution. Webpack was born in such a demand.
At the same time, in order to take advantage of existing frameworks, libraries, and already written files, we also need a module-loaded compatibility policy to avoid rewriting all of the modules.
So next, let's start the magical journey of Webpack.
Modular (CommonJs, AMD, CMD, UMD)