如何在另一个JavaScript文件中包含一个JavaScript文件?

JavaScript中是否有类似于CSS中的@import的东西允许您在另一个JavaScript文件中包含一个JavaScript文件?


旧版本的JavaScript没有导入、包含或要求,因此开发了许多不同的方法来解决这个问题。

但是从2015年(ES6)开始,JavaScript就有了在Node中导入模块的ES6模块标准。,大多数现代浏览器也支持它。

为了与旧浏览器兼容,可以使用构建和/或转置工具。

ES6模块

从v8.5开始,ECMAScript (ES6)模块在Node.js中得到了支持,带有--experimental-modules标志。所有涉及的文件都必须具有.mjs扩展名。

1
2
3
4
// module.mjs
export function hello() {
  return"Hello";
}
1
2
3
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello();  // val is"Hello";

ECMAScript模块在浏览器

自Safari 10.1、Chrome 61、Firefox 60和Edge 16以来,浏览器一直支持直接加载ECMAScript模块(不需要Webpack之类的工具)。检查当前在caniuse的支持。

1
2
3
4
<script type="module">
  import { hello } from './hello.mjs';
  hello('world');
</script>
1
2
3
4
5
6
// hello.mjs
export function hello(text) {
  const div = document.createElement('div');
  div.textContent = `Hello ${text}`;
  document.body.appendChild(div);
}

更多信息请访问https://jakearchibald.com/2017/e-modules-inbrowsers/

动态导入浏览器

动态导入让脚本根据需要加载其他脚本:

1
2
3
4
5
<script type="module">
  import('hello.mjs').then(module => {
      module.hello('world');
    });
</script>

更多信息请访问https://developers.google.com/web/updates/2017/11/dynamic-import

node . js要求

老式的模块导入方式,在Node中仍被广泛使用。是模块。出口/需要系统。

1
2
3
4
5
6
// mymodule.js
module.exports = {
   hello: function() {
      return"Hello";
   }
}
1
2
3
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is"Hello"

JavaScript还可以通过其他方式在浏览器中包含不需要预处理的外部JavaScript内容。

AJAX加载

您可以使用AJAX调用加载一个附加脚本,然后使用eval运行它。这是最直接的方法,但由于JavaScript沙箱安全模型,它仅限于您的域。使用eval也为bug、黑客攻击和安全问题打开了大门。

获取加载

与动态导入一样,您可以使用fetch调用加载一个或多个脚本,使用Fetch注入库控制脚本依赖项的执行顺序:

1
2
3
4
5
fetchInject([
  'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
  console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})

jQuery加载

jQuery库提供了一行加载功能:

1
2
3
$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});

动态脚本加载

您可以将带有脚本URL的脚本标记添加到HTML中。为了避免jQuery的开销,这是一个理想的解决方案。

脚本甚至可以驻留在不同的服务器上。此外,浏览器会评估代码。


有个好消息要告诉你。很快您就可以轻松地加载JavaScript代码了。它将成为导入JavaScript代码模块的标准方式,并成为核心JavaScript本身的一部分。

只需编写import cond from 'cond.js';从文件cond.js加载一个名为cond的宏。

因此,您不必依赖于任何JavaScript框架,也不必显式地调用Ajax。

请参考:

静态模块解决方案

模块加载器


可以动态生成JavaScript标记,并从其他JavaScript代码中将其附加到HTML文档中。这将加载目标JavaScript文件。

1
2
3
4
5
6
7
8
9
10
function includeJs(jsFilePath) {
    var js = document.createElement("script");

    js.type ="text/javascript";
    js.src = jsFilePath;

    document.body.appendChild(js);
}

includeJs("/path/to/some/file.js");


语句import在ECMAScript 6中。

语法

1
2
3
4
5
6
7
import name from"module-name";
import { member } from"module-name";
import { member as alias } from"module-name";
import { member1 , member2 } from"module-name";
import { member1 , member2 as alias2 , [...] } from"module-name";
import name , { member [ , [...] ] } from"module-name";
import"module-name" as name;


也许你可以使用我在这个页面上找到的这个函数,我如何在一个JavaScript文件中包含一个JavaScript文件?

1
2
3
4
5
6
7
8
9
10
function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}


下面是一个没有jQuery的同步版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
    ajax.onreadystatechange = function () {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4) {
            switch( ajax.status) {
                case 200:
                    eval.apply( window, [script] );
                    console.log("script loaded:", url);
                    break;
                default:
                    console.log("ERROR: script not loaded:", url);
            }
        }
    };
    ajax.send(null);
}

注意,要获得这个跨域的工作状态,服务器需要在响应中设置allow-origin报头。