从另一个js文件中导入函数。Javascript

78

我有一个问题,关于在javascript中包含文件。我有一个非常简单的例子:

--> index.html
--> models
      --> course.js
      --> student.js

课程.js:

function Course() {
    this.id = '';
    this.name = '';
}
一个学生有一个课程属性。像这样:

import './course';

function Student() {
    this.firstName = '';
    this.lastName = '';
    this.course = new Course();
}

而 index.html 文件则像这样:

<html>
    <head>
        <script src="./models/student.js" type="text/javascript"></script>
    </head>
    <body>
        <div id="myDiv">
        </div>
        <script>
        window.onload= function() {
            var x = new Student();
            x.course.id = 1;
            document.getElementById('myDiv').innerHTML = x.course.id;
        }
        </script>
    </body>
</html>

但是我在"var x = new Student();"这行代码上遇到了一个错误:

Student未定义

当我从Student中移除import时,错误消息就不再出现了。 我已经尝试使用(require、import、include、创建自定义函数、export)等方式,但都没有成功。

有人知道原因吗?如何修复该问题?

P.S.路径正确,来自于VS Code的自动完成。


现在我可以链接到文档吗:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import - user5734311
1
我认为他并不是在处理导入问题,而是在处理他尝试运行的环境问题。浏览器默认情况下不处理导入。 - samanime
你在浏览器的F12开发工具窗口中看过它吗? - Al Kepp
@ChrisG 那篇文章已经过时了。现在你可以在浏览器中使用ES6模块,只需要使用“module”类型即可。 - samanime
@samanime 你们没有看到我提供的答案吗?这是经过充分测试的、可工作的代码。 - user5734311
显示剩余5条评论
4个回答

75

以下内容适用于Firefox和Chrome浏览器。在Firefox中,它甚至可以从file:///运行。

models/course.js

export function Course() {
    this.id = '';
    this.name = '';
};

学生的模型/student.js

import { Course } from './course.js';

export function Student() {
    this.firstName = '';
    this.lastName = '';
    this.course = new Course();
};

首页.html

<div id="myDiv">
</div>
<script type="module">
    import { Student } from './models/student.js';

    window.onload = function () {
        var x = new Student();
        x.course.id = 1;
        document.getElementById('myDiv').innerHTML = x.course.id;
    }
</script>

4
不幸的是,无法工作,控制台显示:由于CORS策略的限制,无法从源'null'访问“file:///........./models/student.js”的脚本。响应无效。因此,源'null'不被允许访问。 - Samy Sammour
@SamySammour 这是我在Chrome中得到的结果,但在Firefox中它确实可以工作。不过这并不重要;在生产环境中,您将始终提供文件(这将使该错误消失)。这就是如何为浏览器实现模块支持的当前状态,因此这就是您的问题的答案,无论它对您是否有效 ;) - user5734311
1
它在Firefox上也没有工作。它抛出了一个异常:“HTML文档的字符编码未声明。如果文档包含来自US-ASCII范围之外的字符,则在某些浏览器配置中,文档将以乱码形式呈现。页面的字符编码必须在文档或传输协议中声明。”屏幕上没有输出。 - Samy Sammour
我已经提到了没有输出,屏幕是空的。为什么JavaScript要这么复杂呢? - Samy Sammour
可以改进所提出的设计,包括在“models”文件夹中包含“models_include.js”。该文件导入所有所需的模型,在HTML文件中只需在<head>标签中添加<script type="module" language="javascript" src="models/models_include.js"></script>。使用这种方式可以避免在HTML代码中添加额外的脚本代码。 - RDCH106
显示剩余8条评论

22

您可以尝试以下方法:

//------ js/functions.js ------
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ js/main.js ------
import { square, diag } from './functions.js';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

你也可以完全导入:

//------ js/main.js ------
import * as lib from './functions.js';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

通常情况下,我们使用./fileName.js来导入自己的js文件/模块,并使用fileName.js来导入包/库模块。

当您将main.js文件包含在您的网页中时,必须设置type="module"属性,如下所示:

<script type="module" src="js/main.js"></script>

欲了解更多详情,请查看ES6模块


1
在 Qunit 的 HTML 中添加 type="module" 是非常重要的。 - ani627

9

默认情况下,脚本不能直接处理此类导入。您可能会遇到有关无法获取“Course”或未执行导入的其他错误。

如果您将 type="module" 添加到您的 <script> 标记中,并将导入更改为 ./course.js(因为浏览器不会自动添加 .js 部分),那么浏览器将为您拉取 course 并且这样做很可能会起作用。

import './course.js';

function Student() {
    this.firstName = '';
    this.lastName = '';
    this.course = new Course();
}

<html>
    <head>
        <script src="./models/student.js" type="module"></script>
    </head>
    <body>
        <div id="myDiv">
        </div>
        <script>
        window.onload= function() {
            var x = new Student();
            x.course.id = 1;
            document.getElementById('myDiv').innerHTML = x.course.id;
        }
        </script>
    </body>
</html>

如果你是通过file://协议传输文件,很可能会无法正常工作。一些IDE有快速运行服务器的功能。

你也可以编写一个简单的express服务器来传输你的文件(如果没有安装Node,请先安装):

//package.json
{
  "scripts": { "start": "node server" },
  "dependencies": { "express": "latest" }
}

// server/index.js
const express = require('express');
const app = express();

app.use('/', express.static('PATH_TO_YOUR_FILES_HERE');
app.listen(8000);

使用这两个文件,运行npm install,然后运行npm start,你将会拥有一个运行在http://localhost:8000的服务器,该服务器应该指向你的文件。

不幸的是,它没有起作用,现在它抛出了一个额外的异常。"无效响应。因此,'null'来源不允许访问。" - Samy Sammour
如果你看到这个,那么就是一个跨域异常。你是在 file:// 协议上运行它还是 http://?如果你是在 file:// 上运行它,那么你会遇到麻烦的。 - samanime
file://。那么该怎么办?如何修复? - Samy Sammour
最好的方法是使用某种服务器通过localhost来提供它们。一些IDE已经内置了它们。你也可以只用几行代码编写一个快速的express服务器。我会在我的回答中给你一个例子。 - samanime
我无法使用任何服务器。 - Samy Sammour

6
//In module.js add below code

export function multiply() {
    return 2 * 3;
}

// 在 calc.js 中使用该模块

import { multiply } from './modules.js';

const result = multiply();

console.log(`Result: ${result}`);

// 模块.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Module</title>
</head>
<body>

  <script type="module" src="./calc.js"></script>
</body>
</html>

这是一个设计模式,相同的代码可以在下面找到,请使用实时服务器进行测试,否则您将获得CORS错误。

https://github.com/rohan12patil/JSDesignPatterns/tree/master/Structural%20Patterns/module


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接