Javascript模块无法在浏览器中运行?

Rob*_*Man 13 javascript module

好吧,我看过这个网站并找到了几个不同的答案,其中没有一个对我有用.基本上有一个js文件,其中包含许多函数以及应用程序的主要代码.我想将我的所有函数移动到另一个js文件,以便我可以稍微清理一下我的代码.我对js相当新,但我知道在python中它就像从(路径)说"import(module)as(nickname)"一样简单

不管怎样,让我说我的functions.js模块中有一个名为show message的函数.

export function show_message(){
    alert("Hello");
}
Run Code Online (Sandbox Code Playgroud)

然后我在我的main.js文件的顶部

import { show_message } from './functions.js'
//I have also tried to import like this:
import * as func from './functions.js'

//And then I call it
show_message();
//I have also tried
func.show_message();
Run Code Online (Sandbox Code Playgroud)

我知道这很简单,但正如我在任何地方所说的那样,我看到了不同的答案,其中没有一个适合我.我正在使用Firefox btw.我也在控制台中收到错误,说我的导入声明需要在我的模块的顶部,我通过在HTML链接中指定类型来修复它(脚本src ="/ static/main.js"type ="模块")错误消失但现在说"同源策略不允许在文件(路径)读取远程资源(原因:cors请求不是HTTP)."

另一个错误是"本文档中不允许使用模块源URI".

这让我觉得我的导入语法可能正确,错误在我的HTML代码中?

任何帮助表示赞赏.

Hen*_*nke 15

0. 简短的回答

您需要安装并运行本地 Web 服务器。- 有关如何操作的建议,请继续阅读。

1. 基础知识

我尝试了一个简单的HTML文件————index.html如下:

<!-- index.html - minimal HTML to keep it simple -->
<html>
<head>
  <meta charset="UTF-8">
  <link rel="shortcut icon" href="#">
</head>
<body>
  <h1>Hello world!</h1>
  <p>Experimenting with JavaScript modules.</p>
  <script type="module" src="js/functions.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

在子文件夹中,js我放置了 JavaScript 文件functions.js

// js/functions.js
alert('Hello');
Run Code Online (Sandbox Code Playgroud)

双击 时index.html,我的默认 Web 浏览器 – Firefox 89.0(64 位) – 在按下 后显示以下内容F12。注意 JavaScript 代码没有运行

JavaScript 在浏览器中不起作用。

错误信息:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///C:/stackexchange/reproduce/jsModule/moduleNW/basics/js/functions.js. (Reason: CORS request not http).

作弊的“解决方案”是(暂时)type="module"从 HTML 代码中删除。
警报然后显示没有错误。

但是我将 JavaScript 代码作为一个模块运行,所以我放回 type="module"了 HTML。

2. 安装并运行本地 Web 服务器

要将其作为模块运行,它需要在 Web 服务器上运行。因此,如果您想在自己的计算机上运行代码,则需要(安装和)启动本地 Web 服务器。
目前流行的一种替代方法是live-server。这对我有用。

  • 打开一个终端。(在 Windows 上:cmd.exe.)
  • 输入npm并点击Enter查看是否安装了Node.js。
  • 如果你得到command not found,请在https://nodejs.org/en/download/下载 并安装。1
    (在 Ubuntu 上,您可以尝试sudo apt install -y nodejs.)
  • 安装实时服务器:npm install live-server -g.
  • 将目录更改为您的页面所在的位置:cd <path-to-index.html>.
  • 启动服务器:(live-server .
    应该localhost:8080在您的默认浏览器中打开并显示警报。见下文。)

在实时服务器上本地运行的 JavaScript。

注 1。我使用的是 Windows 10,但上述说明在 Linux 和 macOS 上也应该可以正常工作。
注2。在这里我使用了 Firefox 89.0,但我也尝试过 Google Chrome 91.0。唯一显着的区别是 CORS 错误消息,在 Chrome 中显示为:
Access to script at 'file:///C:/stackexchange/reproduce/jsModule/basics/js/functions.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

3. 出口和进口

接下来我创建一个demo2包含以下内容的新文件夹demo2.html

<!-- demo2.html - even shorter HTML for simplicity -->
<body>
  <h1>Hello world!</h1>
  <p>Javascript modules.</p>
  <script type="module" src="js/main.js"></script>
</body>
Run Code Online (Sandbox Code Playgroud)

我还在子文件夹中创建了以下三个 JavaScript 文件js

// js/module1.js
export function hi () { console.log('Hi from module 1.'); }
Run Code Online (Sandbox Code Playgroud)

// js/module2.js
export function howdy () { console.log('Howdy from module 2!'); }
Run Code Online (Sandbox Code Playgroud)

// js/main.js
import { hi } from './module1.js';
import { howdy } from './module2.js';
hi();
howdy();
Run Code Online (Sandbox Code Playgroud)

现在,我从终端demo2.html 所在文件夹中的终端运行 live-server 。这次我首先输入 live-server --port=1234 --entry-file=demo2.html 并点击Enter。截屏:

从多个子模块调用时运行的 JavaScript。

参考:


1在 Windows 10 上,我曾经需要 修复安装


Fra*_*cia 10

在用于在浏览器中加载 js 的脚本标记上,您需要添加属性

类型=“模块”

它将如下所示:

<script type="module">
  import {addTextToBody} from './utils.mjs';

  addTextToBody('Modules are pretty cool.');
</script>
Run Code Online (Sandbox Code Playgroud)

utils.mjs

export function addTextToBody(text) {
  const div = document.createElement('div');
  div.textContent = text;
  document.body.appendChild(div);
}
Run Code Online (Sandbox Code Playgroud)

这是如果您没有使用像 webpack 这样的打包器并直接在浏览器中工作。

代码来源:https : //jakearchibald.com/2017/es-modules-in-browsers/


Old*_*Pro 6

您可能想改用broswerify。它允许你编写 NodeJS 风格的模块,然后将它们编译成一个浏览器友好的 JavaScript 文件,让你获得只加载单个文件的所有性能优势。这也意味着您可以轻松地在服务器端和客户端使用相同的代码。

如果您想坚持使用单独的文件,看起来您的工作进展顺利。与常规 JavaScript 文件不同,模块受跨源资源共享 ( CORS ) 限制。它们必须从同一来源加载,不能从本地文件系统加载。如果您从本地文件系统加载它们,请将它们移动到服务器。如果您已经将它们托管在服务器上,请将Access-Control-Allow-Origin: *标头添加到为模块文件提供服务的响应中。

此处此处有更多问题和解决方案。


小智 5

接受答案的快捷方式

如果您使用的是Visual Studio Code,只需安装Microsoft的实时预览扩展。

Visual Studio Code 中的实时预览

在任何 HTML 文件中单击“显示预览”图标。它将自动运行本地服务器并显示在代码编辑器中。每次编辑后都会刷新。您还可以在默认浏览器中显示它。

不再需要命令行!


小智 3

function show_message(){
    alert("Hello");
}

export { show_message };
Run Code Online (Sandbox Code Playgroud)

import { show_message } from './functions'
Run Code Online (Sandbox Code Playgroud)

我认为这应该可以解决问题。这是一种命名的导出/导入 技术。如果您愿意,您可以在此名称下找到更多信息。