Javascript模块在浏览器中不起作用?
Posted
技术标签:
【中文标题】Javascript模块在浏览器中不起作用?【英文标题】:Javascript module not working in browser? 【发布时间】:2019-02-07 22:10:44 【问题描述】:好的,我查看了这个网站并找到了几个不同的答案,但没有一个对我有用。 基本上有一个 js 文件,其中包含许多功能以及应用程序的主要代码。我想将我所有的函数移动到另一个 js 文件中,以便我可以稍微清理一下我的代码。我对 js 很陌生,但我知道在 python 中它就像说“import (module) as (nickname) from (path)”一样简单
无论如何,假设我的 functions.js 模块中有一个名为 show message 的函数。
export function show_message()
alert("Hello");
然后我在我的 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();
我知道这很简单,但正如我所说的,我到处都看到了不同的答案,但没有一个对我有用。我正在使用 Firefox 顺便说一句。我还在控制台中收到一个错误,说我的导入声明需要在我的模块的顶部,我通过在我的 html 链接中指定类型(脚本 src="/static/main.js" type="模块”) 错误消失了,但现在说“同源策略不允许读取文件(路径)处的远程资源(原因:cors 请求不是 HTTP)。”
另一个错误是“此文档中不允许模块源 URI”。
这让我觉得我的导入语法可能是正确的,而错误在我的 HTML 代码中?
感谢任何帮助。
【问题讨论】:
我知道这是一个老问题,但对于其他搜索的人来说:这个资源有帮助吗?不确定您尝试过哪些方法***.com/questions/5797852/… 你试过func.show_message();
吗?鉴于您使用的是import * as func from './functions.js'
这是一个 CORS 相对路径问题,不是导入问题。
纯 javascript 中没有“导入”和“导出”之类的东西。如果您正在使用其他库,请添加其他标签。
***.com/a/950146/1675954 就错误而言。模块源被禁止,禁用/卸载你的扩展
【参考方案1】:
function show_message()
alert("Hello");
export show_message ;
和
import show_message from './functions'
我认为这应该可以解决问题。这是一种命名的导出/导入技术。如果您愿意,可以在此名称下找到更多信息。
【讨论】:
【参考方案2】:您可能想改用broswerify。它允许您编写 NodeJS 样式的模块,然后将它们编译成单个浏览器友好的 JavaScript 文件,从而让您获得仅加载单个文件的所有性能优势。这也意味着您可以轻松地在服务器端和客户端使用相同的代码。
如果您想坚持使用单独的文件,那么您似乎一切顺利。与常规 JavaScript 文件不同,模块受跨域资源共享 (CORS) 限制。它们必须从同一来源加载,并且不能从本地文件系统加载。如果您从本地文件系统加载它们,请将它们移动到服务器。如果您已经将它们托管在服务器上,请将 Access-Control-Allow-Origin: *
标头添加到为模块文件提供服务的响应中。
更多陷阱和解决方案here 和here。
【讨论】:
【参考方案3】:在您用于在浏览器中加载js的脚本标签上,您需要添加属性
type="模块"
它将如下所示:
<script type="module">
import addTextToBody from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
utils.mjs
:
export function addTextToBody(text)
const div = document.createElement('div');
div.textContent = text;
document.body.appendChild(div);
这是在你没有使用 webpack 之类的打包工具并直接在浏览器中工作的情况下。
代码来源:https://jakearchibald.com/2017/es-modules-in-browsers/
【讨论】:
【参考方案4】:JavaScript 有模块很长时间了。但是,它们是通过库实现的,而不是内置于语言中,即您无法将这些模块的一部分导入或导出到您的 js 文件中(需要加载整个库)。 ES6 是 JavaScript 首次内置模块。
有关 ES 模块的更多信息,请参考Here。
但情况发生了变化,ES 模块现在可以在浏览器中使用!他们在……
Safari 10.1+、Chrome 61+、Firefox 60+、Edge 16+ 等。
现在,您需要使用新的扩展名 .mjs 创建您的 JS 文件,例如,
// utils.mjs
export function addTextToBody(text)
const div = document.createElement('div');
div.textContent = text;
document.body.appendChild(div);
然后,您可以将该文件导入到您的 html 页面中,例如,
<script type="module">
import addTextToBody from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
有关在浏览器中使用 ES 模块的更多信息,请参阅Here。
【讨论】:
【参考方案5】:考虑通过this url 某些扩展可能会导致模块加载出现问题:
This blog 可能是您所期望的答案。
您应该首先检查浏览器是否接受 type="module",如果不喜欢,请使用后备:
<script type="module" src="module.mjs"></script>
<script nomodule src="fallback.js"></script>
这可能是此处所写 CORS 错误的主要原因:
与常规脚本不同,模块脚本(及其导入)被获取 与 CORS。这意味着跨域模块脚本必须返回有效 CORS 标头,例如
Access-Control-Allow-Origin: *
所以你需要在模块文件中添加CORS头
请考虑 this blog 处理 CORS 问题。您应该添加 CORS 标头,即。 Access-Control-Allow-Origin: *
很可能是服务器配置。
【讨论】:
【参考方案6】:在浏览器中使用 JS 模块 在 Web 上,您可以通过将 type 属性设置为 module 来告诉浏览器将元素视为模块。
<script type="module" src="main.mjs"></script>
<script nomodule src="fallback.js"></script>
更多 https://developers.google.com/web/fundamentals/primers/modules
【讨论】:
【参考方案7】:如果你使用 webpack 和 babel 并且想将代码导入到你的包中,我猜它应该是以下之一:
export default function show_message()
alert("Hello");
然后在你的代码中:
import show_message from 'path/to/show_message.js'
// or
import default as someOtherName from 'path/to/show_message.js'
或者,如果您想导出多个函数:
const show_message = function()
alert("Hello");
export show_message ;
然后在你的代码中:
import show_message from 'path/to/show_message.js'
// or
import show_message as someOtherName from 'path/to/show_message.js'
希望对您有所帮助。
【讨论】:
【参考方案8】: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>
在子文件夹js
我把JavaScript文件functions.js
:
// js/functions.js
alert('Hello');
双击index.html
时,我的默认浏览器——Firefox 89.0
(64 位)- 按 F12 后显示以下内容。
注意 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).
作弊“解决方案”是(暂时)从 HTML 中删除 type="module"
代码。
然后警报显示没有错误。
但我想要将 JavaScript 代码作为模块运行,所以我放回去了
type="module"
在 HTML 中。
2。安装并运行本地 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
并显示警报。
见下文。)
注 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>
我还在子文件夹js
中创建了以下三个JavaScript文件:
// js/module1.js
export function hi () console.log('Hi from module 1.');
和
// js/module2.js
export function howdy () console.log('Howdy from module 2!');
和
// js/main.js
import hi from './module1.js';
import howdy from './module2.js';
hi();
howdy();
现在我从终端在 demo2.html
所在的文件夹中运行 live-server
居住。
这次我开始输入
live-server --port=1234 --entry-file=demo2.html
并点击 Enter。截图:
参考资料:
Installing Node.js live-server The live-server docs Live-server can't find the file specified Export and Import1 在 Windows 10 上,我曾经需要 repair the installation.
【讨论】:
我得到“live-server : FIle c:\path\to\live-server.ps1 无法加载,因为在此系统上禁用了运行脚本。” :( 无法加载,因为在这个系统上禁用了运行脚本 ~ * ~ 我用的是老式的cmd.exe
,所以在PowerShell中不知道怎么做.如果你坚持使用 PowerShell,不妨看看How to enable execution of PowerShell scripts? - or - PowerShell says “execution of scripts is disabled on this system.” 是否有帮助?
对不起,我来晚了,但您可以在 PowerShell 中运行 Set-ExecutionPolicy AllSigned
或 Set-ExecutionPolicy Bypass -Scope Process
。【参考方案9】:
我知道这个旧线程,但我只是通过使用 Parcel 启动我的网站 Parcel index.html
自己解决了这个问题,在我的情况下,我使用的是 Live 服务器,直到我切换到 parcel 才工作。
【讨论】:
【参考方案10】:Accepted answer 的快捷方式
如果您使用的是Visual Studio Code,只需通过Microsoft 安装Live Preview 扩展。
在任何 HTML 文件中单击 显示预览 图标。它将自动运行本地服务器并显示在代码编辑器中。每次编辑后,您都会刷新。您也可以在默认浏览器中显示它。
不再需要命令行!
【讨论】:
【参考方案11】:不要使用.js
,而是尝试使用.mjs
。
假设您的模块文件是/modules/App.js
,只需将其更改为/modules/App.mjs
。
当然,请确保您在脚本标签中添加了 type="module",如下所示 - <script type="module" src="./index.js" defer></script>
我的文件夹结构 -
index.html
index.js
modules/App.mjs
这对我有用!
【讨论】:
以上是关于Javascript模块在浏览器中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 重定向在 Facebook 应用内浏览器中不起作用
Javascript autotab keyup/keydown 在 Cordova Android 浏览器中不起作用
使用javascript禁用键盘快捷键在Safari中不起作用?
javascript代码在chrome移动浏览器中不起作用,但在桌面上它工作正常