JS implements perfect include loading function code

  • 2020-05-12 02:27:04
  • OfStack

Why does js need include? Let's consider a scenario where a.js requires a common common.js, which you can use on a page that USES a.js < script src="common.js" > ", but let's say you have five pages that use a.js, do you have to write it five times < script. And if a.js needs to reference common2.js again in the future, have you changed 5 more pages?

There are already some problems with js include
Before writing this, I searched some information on the Internet and found that there are two problems with include written before, which are also two important problems that include needs to solve.
1. Relative path problem: include(".. / js common. js "); The include function must use the relative path, which is the path to a.js. a.js is used in html < script > The embedding could be a relative path, it could be an absolute path. How can the include function really determine the absolute path of common.js, or the relative path of html? In order to solve this problem, we also need to add 1 js variable, which is inconvenient.
2. Question of quotation. Almost all implementations of include functions on the web insert common.js in the following two ways
document. write (" < script src='" + .. + " > < /script > ")
or
var s = document. createElement (" script ");
s. src =... ;
head. insertAfter (s,...). ;
The script output from document.write is loaded after a.js, while the script created by createElement("script") is non-blocking. So if the common.js function calls common.js before common.js is loaded, the a.js function will report an error.

implementation
By solving the above two problems, js include can be implemented.
For the first problem, my method is to first obtain the absolute path of a.js in html (if it is a relative path, it will be converted to an absolute path), and then convert the path of common.js into an absolute path.
The second problem USES a synchronous ajax to request common.js so that there is no reference problem.

The implementation code is as follows:
 
//  Get the absolute path according to the relative path  
function getPath(relativePath,absolutePath){ 
var reg = new RegExp("\\.\\./","g"); 
var uplayCount = 0; //  The number of times a relative path returns the upper level.  
var m = relativePath.match(reg); 
if(m) uplayCount = m.length; 
var lastIndex = absolutePath.length-1; 
for(var i=0;i<=uplayCount;i++){ 
lastIndex = absolutePath.lastIndexOf("/",lastIndex); 
} 
return absolutePath.substr(0,lastIndex+1) + relativePath.replace(reg,""); 
} 
function include(jssrc){ 
//  Get the current a.js the src . a.js In the call include, Get the end directly 1 a script The label is a.js The reference.  
var scripts = document.getElementsByTagName("script"); 
var lastScript = scripts[scripts.length-1]; 
var src = lastScript.src; 
if(src.indexOf("http://")!=0 && src.indexOf("/") !=0){ 
// a.js Using relative paths , I'm going to replace it with an absolute path  
var url = location.href; 
var index = url.indexOf("?"); 
if(index != -1){ 
url = url.substring(0, index-1); 
} 
src = getPath(src,url); 
} 
var jssrcs = jssrc.split("|"); //  can include multiple js with | separated  
for(var i=0;i<jssrcs.length;i++){ 
//  use juqery The synchronous ajax loading js. 
//  use document.write  Dynamically added js In the current js In the back, there might be js Reference questions  
//  Dynamically create script Scripts, non-blocking downloads, can also have reference problems  
$.ajax({type:'GET',url:getPath(jssrc,src),async:false,dataType:'script'}); 
} 
} 

include(".. / js common. js ");

The problem of multiple requests
Using include above looks great, but another serious problem is sending one more ajax request.
We often merge js for WEB performance, reducing requests. With include, however, there are more requests. If this problem is not solved, it is believed that many people will not use include in official products, unless it is a LAN product.

I have been thinking for a long time about how to solve this problem of multiple requests. Finally, I think it is impossible to solve this problem by only using the client js. So I came up with the idea of using server-side code
Remember that when I wrote about "merge, compress, cache management of js and css", I used server-side code to merge js at startup.

So I added include's multi-request solution as well. It is to search for all js when the program is started, and if you find that include is used, replace the include function with the common.js source code in include. This way, a.js does not have the include function at run time, but the js file that actually contains the contents of common.js

After the language
Ya. In the end, why did I replace all the include? I didn't say so much before.

In my opinion, each product should distinguish between the development environment and the production environment (usually through configuration files). In the development environment, the development efficiency should be the priority, while the production environment should be the performance first. Therefore, inlcude should be treated differently here, using js include in the development environment to improve the efficiency of development and maintenance, and automatically replacing all include with the contents of the real js files in the production environment.

That's all. Welcome to the discussion.
[author] : BearRui(AK-47)
[blog] : http: / / www cnblogs. com/BearsTaR /

Related articles: