在JavaScript文件中引入另一个JavaScript文件的方法

在JavaScript文件中引入另一个JavaScript文件的方法

技术背景

在早期版本的JavaScript中,并没有内置的importincluderequire机制,这导致开发者们开发出了多种不同的方法来解决在一个JavaScript文件中引入另一个JavaScript文件的问题。不过,自2015年(ES6)起,JavaScript引入了ES6模块标准,该标准可用于在Node.js中导入模块,并且大多数现代浏览器也支持这一标准。为了兼容旧版浏览器,还可以使用Webpack和Rollup等构建工具以及Babel等转译工具。

实现步骤

ES6模块

  • Node.js环境
    • 自Node.js v8.5起,通过--experimental-modules标志支持ES6模块;自Node.js v13.8.0起,无需该标志即可支持。要启用“ESM”(相对于Node.js之前的CommonJS风格模块系统“CJS”),可以在package.json中使用"type": "module",或者给文件使用.mjs扩展名。
    • 示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
// package.json
{
"type": "module"
}

// module.js
export function hello() {
return "Hello";
}

// main.js
import { hello } from './module.js';
let val = hello(); // val is "Hello";
  • 浏览器环境
    • 自Safari 10.1、Chrome 61、Firefox 60和Edge 16起,浏览器开始支持直接加载ECMAScript模块(无需Webpack等工具)。
    • 示例代码:
1
2
3
4
5
6
7
8
9
10
11
<script type="module">
import { hello } from './hello.mjs'; // Or the extension could be just `.js`
hello('world');
</script>

// hello.mjs -- or the extension could be just `.js`
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
  • 动态导入(浏览器)
    • 动态导入允许脚本根据需要加载其他脚本。
    • 示例代码:
1
2
3
4
5
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>

Node.js的require

  • CommonJS模块风格:在Node.js中广泛使用的module.exports/require系统。
  • 示例代码:
1
2
3
4
5
6
7
8
9
10
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}

// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"

其他方法

  • AJAX加载:使用AJAX调用加载额外的脚本,然后使用eval运行它。但由于JavaScript沙箱安全模型,此方法仅限于同一域名,并且使用eval会带来安全问题。
  • Fetch加载:使用fetch调用加载一个或多个脚本,并使用Fetch Inject库通过Promise控制脚本依赖的执行顺序。
  • jQuery加载:使用jQuery库的$.getScript方法加载脚本。
  • 动态脚本加载:在HTML中动态添加一个<script>标签,其src属性指向要加载的脚本URL。
  • 示例代码:
1
2
3
4
5
6
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL

document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}

核心代码

ES6模块引入示例

1
2
3
4
5
6
7
8
// module.js
export function hello() {
return "Hello";
}

// main.js
import { hello } from './module.js';
let val = hello();

Node.js的require示例

1
2
3
4
5
6
7
8
9
10
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}

// server.js
const myModule = require('./mymodule');
let val = myModule.hello();

动态脚本加载示例

1
2
3
4
5
function dynamicallyLoadScript(url) {
var script = document.createElement("script");
script.src = url;
document.head.appendChild(script);
}

最佳实践

  • 使用ES6模块:对于现代项目,优先使用ES6模块,它提供了更清晰的语法和更好的模块化支持。
  • 使用构建工具:使用Webpack、Rollup等构建工具,将多个JavaScript文件打包成一个或少数几个文件,减少HTTP请求,提高性能。
  • 处理脚本加载完成事件:在动态加载脚本时,使用事件监听确保脚本加载完成后再使用其中的代码。

常见问题

  • ES6模块加载失败:可能是服务器未正确设置.mjs文件的Content-type头,应将其设置为text/javascript
  • 动态加载脚本后无法立即使用:现代浏览器异步加载脚本,因此在请求加载脚本的下一行代码中可能无法立即使用新加载的代码。可以使用事件监听或回调函数来确保脚本加载完成后再使用。
  • 使用eval带来的安全问题eval会执行任意代码,可能导致安全漏洞,应尽量避免使用。

在JavaScript文件中引入另一个JavaScript文件的方法
https://119291.xyz/posts/2025-04-16.ways-to-include-javascript-file-in-another/
作者
ww
发布于
2025年4月16日
许可协议