Home > Web Front-end > Front-end Q&A > Why should web pages be modularized?

Why should web pages be modularized?

伊谢尔伦
Release: 2016-11-23 10:07:53
Original
2392 people have browsed it

This article discusses why Web modularization is useful and introduces some mechanisms that can be used to implement Web modularization now. Here is another article that explains the design philosophy of the function wrapping format used by RequireJS.

 Problem §1

Websites are gradually transformed into Web apps

Code complexity is gradually increasing

Assembly becomes difficult

Developers want to separate JS files/modules

The code can be optimized into several HTTPs when deploying Request

Solution §2

Frontend developers need a solution like this:

Some such API #include/import/require

Has the ability to load nested dependencies

Easy to use for developers, And there are optimization tools behind it to help deploy

 Script loading API § 3

 First sort out the script loading API. There are a few options here:

Dojo: dojo.require("some.module")
LABjs: $LAB.script("some/module.js")
CommonJS: require("some/module")
Copy after login

All mapped to loading some/path/some/module.js. Ideally, we would choose CommonJS's syntax since it is likely to become more common and we want to reuse code.

We are also currently hoping to have some syntax that can load existing plain text JavaScript files, so developers don't have to rewrite all JavaScript to benefit from script loading.

 However, we need something that works better in the browser. CommonJS's require() is a synchronous call that expects that module to be returned immediately. This doesn't work very well in the browser though.

 Asynchronous and Synchronous§ 4

 The following example illustrates the basic problem of browsers. Suppose we have an Employee object and we want a Manager object derived from the Employee object. Taking this example, we might use our script to load the API and code it like this:

var Employee = require("types/Employee");function Manager () {
    this.reports = [];
}//Error if require call is asyncManager.prototype = new Employee();
Copy after login


As shown in the comments above, this code will not work if require() is asynchronous. However, synchronously loading scripts in the browser will kill performance. So, what to do?

 Script loading: XHR§ 5

 It is very attractive to use XMLHttpRequest (XHR) to load scripts. If we use XHR, we can touch the text above, which means we can use regular expressions to find require() calls to ensure that we load these scripts, and then use eval() or script elements to pass the text content to the user XHR loading script.

Using eval() to evaluate modules is not good:

Developers have been told that eval() is not good to use.

Some environments do not support eval().

Difficult to debug. Firebug and WebKit's inspectors have a //@sourceURL= convention for naming the text being evaluated, but this feature is not supported by all browsers.

Different browsers evaluate context differently. execScript in IE might do it, but it also means more moving parts.

Using a script tag with text content to set it as file text is not good either:

When debugging, the error line number you get does not match the source file number.

  XHR still has problems when making cross-domain requests. Some browsers now have cross-domain XHR support, but not all. And IE decided to create a different API object: XDomainRequest to implement cross-domain requests. There are more things that need to be changed, and it's easier to make mistakes. In particular, you need to make sure not to send any non-standard HTTP headers or require another "preflight" request to ensure that the cross-origin request is allowed.

  Dojo uses the XHR-based loader through eval(). However, although it works, it has always been a source of trouble for developers. Dojo has an xdomain loader but it needs to modify the require module by using a function wrapper, so the script src="" tag can be used to load the module. There are also many edge cases and variations that add difficulty to programmers.

 We can do better if we create a new script loader.

 Script Loading: Web Workers § 6

  Web workers might be another way to load scripts, but:

It’s not cross-platform

It’s a messaging API, and the script might have to deal with the DOM Interactively, it just uses the worker to get the text of the script, then passes the text back to the main window, and then uses eval/script to execute the script. This approach comes with all the problems of XHR mentioned above.

 Script loading: document.write()§ 7

 Document.write() can be used to load scripts. It can load scripts from other domains and maps how browsers usually use scripts, so it Can be used for simple debugging.

 However, in the asynchronous vs synchronous example, we cannot execute the script directly. Ideally, we would know the relevant dependencies via require() before executing the script, and ensure that these dependencies are loaded first. But we cannot access it before the script is executed.

  而且,document.write()在页面载入后就不工作了。对于你的网站,一个好的方法是在用户需要进行下一步操作时来载入脚本。

  最后,通过document.write()载入脚本或阻塞页面的渲染。要让你的网站有最佳表现,这个方法是不可取的。

  脚本载入:head.appendChild(script)§ 8

  我们可以在需要时创建脚本并将它们添加到头部:

var head = document.getElementsByTagName('head')[0],
    script = document.createElement('script');
 
script.src = url;
head.appendChild(script);
Copy after login

上面的脚本片段多了一点东西,不过那正是基本的思想。这种方法比document.write要好,因为它不会阻塞页面的渲染并且在页面载入后仍能工作。

  但是,它仍然有同步VS异步例子的问题:理想情况下,在执行脚本前我们能够通过require()知道相关依赖项,并且确保这些依赖项被首先载入。

  函数封装 § 9

  在执行我们的脚本前,我们需要知道相关依赖项并确保已经将其载入。做这件事的最好方法是通过函数封装来构造我们的模块载入API。像这样:

define(    //The name of this module
    "types/Manager",    //The array of dependencies
    ["types/Employee"],    //The function to execute when all dependencies have loaded. The
    //arguments to this function are the array of dependencies mentioned
    //above.
    function (Employee) {
        function Manager () {
            this.reports = [];
        }        //This will now work
        Manager.prototype = new Employee();        
        //return the Manager constructor function so it can be used by
        //other modules.
        return Manager;
    }
);
Copy after login

这是ReguireJS的句法。如果你想载入没有定义成模块的纯文本的JavaScript的话,有一种简单的句法:

require(["some/script.js"], function() {
    //This function is called after some/script.js has loaded.
});
Copy after login

选择这种句法是因为,它足够简洁并且允许载入者使用head.appendChild(script)载入类型。

  出于在浏览器中良好工作的需要,它有不同于普通的CommonJS句法。有建议说普通的CommonJS句法可以使用head.appendChild(script)的载入类型,如果服务器进程有封装的函数可以将模块转换成传输格式的话。

  我相信不强制使用一个运行时服务器进程来转换代码是很重要的事:

一是调试变的很怪异,因为服务器在注入封装函数时会导致源文件的行号关闭。

二是需要做更多的工作。前端开发应该尽可能的使用静态文件。

  关于设计的力量和功能封装格式的使用案例的更多细节,被叫做异步模块定义(Asynchronous Module Definition (AMD)),请前往为什么是AMD?

  原文地址:http://www.php.cn/website-design-ask-340211.html

以上就是为什么要web网页模块化?的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Related labels:
web
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template