[英]Unable to import external JS library into web application
I'm trying to make a basic web application which converts markdown in a <textarea>
into HTML.我正在尝试制作一个基本的 web 应用程序,它将
<textarea>
中的 markdown 转换为 HTML。 For this I wanted to use the PageDown library, which SO also uses: https://code.google.com/archive/p/pagedown/wikis/PageDown.wiki .为此,我想使用 PageDown 库,SO 也使用它: https://code.google.com/archive/p/pagedown/wikis/PageDown.wiki 。
I downloaded the PageDown source code, extracted it and placed it inside the top-level directory containing my HTML/JS files.我下载了 PageDown 源代码,将其解压缩并放在包含我的 HTML/JS 文件的顶级目录中。 So the directory structure looks like this:
所以目录结构是这样的:
.
├── index.html
├── main.js
├── pagedown
│ ├── LICENSE.txt
│ ├── Markdown.Converter.js
│ ├── Markdown.Editor.js
│ ├── Markdown.Sanitizer.js
│ ├── README.txt
│ ├── demo
│ ├── local
│ ├── node-pagedown.js
│ ├── package.json
│ ├── resources
│ └── wmd-buttons.png
└── style.css
Then I tried to load it in the following way:然后我尝试通过以下方式加载它:
main.js
: main.js
:
import { Converter } from 'Markdown.Converter.js'
var text = "**Markdown rocks**"
var converter = new Markdown.Converter();
var html = converter.makeHtml(text);
index.html
: index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script type="module" src="main.js" defer></script>
<script type="module" src="./pagedown/Markdown.Converter.js"></script>
<script type="module" src="./pagedown/Markdown.Sanitizer.js"></script>
<script type="module" src="./pagedown/Markdown.Editor.js"></script>
<title>Text</title>
</head>
<body>
<textarea name="" id="textinput" cols="30" rows="10"></textarea>
<div id="output"></div>
</body>
</html>
Then I'm running the code in Chrome using the VSCode Live Server extension.然后我使用 VSCode Live Server 扩展在 Chrome 中运行代码。 I get the following output:
我得到以下 output:
Uncaught TypeError: Failed to resolve module specifier "Markdown.Converter.js". Relative references must start with either "/", "./", or "../".
Markdown.Sanitizer.js:8 Uncaught TypeError: Cannot read properties of undefined (reading 'Converter')
at Markdown.Sanitizer.js:8:28
at Markdown.Sanitizer.js:108:3
(anonymous) @ Markdown.Sanitizer.js:8
(anonymous) @ Markdown.Sanitizer.js:108
Markdown.Editor.js:92 Uncaught ReferenceError: Markdown is not defined
at Markdown.Editor.js:92:5
at Markdown.Editor.js:2301:3
So I tried changing the path to the Markdown.*
scripts to /pagedown/Markdown.*.js
, and pagedown/Markdown.*.js
, but I got the same error for both.因此,我尝试将
Markdown.*
脚本的路径更改为/pagedown/Markdown.*.js
和pagedown/Markdown.*.js
,但两者都出现了相同的错误。
I'm not really sure what I'm doing wrong here.我不确定我在这里做错了什么。
You need to alter the import
path in your main.js
to the relative location of Markdown.Converter.js
:您需要将
Markdown.Converter.js
中的import
路径更改为main.js
的相对位置:
import { Converter } from './pagedown/Markdown.Converter.js';
But if you try this now, you will get some error like:但是如果你现在尝试这个,你会得到一些错误,比如:
Uncaught SyntaxError: The requested module './pagedown/Markdown.Converter.js' does not provide an export named 'Converter'
未捕获的语法错误:请求的模块“./pagedown/Markdown.Converter.js”未提供名为“Converter”的导出
And this is because Markdown.Converter.js
is not an ESM JavaScript file.这是因为
Markdown.Converter.js
不是 ESM JavaScript 文件。 We can tell this because it has no export
statements .我们可以告诉这一点,因为它没有
export
语句。
What we have to appeal to instead is the "old-fashioned" version of loading the script, as these scripts are setting their library code into the "global" scope.我们不得不呼吁的是加载脚本的“老式”版本,因为这些脚本将它们的库代码设置为“全局”scope。 We can see this in
Markdown.Converter.js
since in the first few lines of it, it has this statement not wrapped in any other scope:我们可以在
Markdown.Converter.js
中看到这一点,因为在它的前几行中,它的语句没有包含在任何其他 scope 中:
var Markdown;
So, to give these scripts access to the global scope such that main.js
can "access" their code, we need to remove the type="module"
from these scripts, since (as per MDN documentation ):因此,为了让这些脚本能够访问全局 scope 以便
main.js
可以“访问”它们的代码,我们需要从这些脚本中删除type="module"
,因为(根据MDN 文档):
Module-defined variables are scoped to the module unless explicitly attached to the global object.
除非显式附加到全局 object,否则模块定义的变量将作用于模块。
So now your index.html
should be所以现在你的
index.html
应该是
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script type="module" src="main.js"></script>
<script src="./pagedown/Markdown.Converter.js"></script>
<script src="./pagedown/Markdown.Sanitizer.js"></script>
<script src="./pagedown/Markdown.Editor.js"></script>
<title>Text</title>
</head>
<body>
<textarea name="" id="textinput" cols="30" rows="10"></textarea>
<div id="output"></div>
</body>
</html>
Note: as per the same MDN documentation mentioned above:注意:根据上述相同的MDN 文档:
There is no need to use the
defer
attribute (see<script>
attributes ) when loading a module script;加载模块脚本时无需使用
defer
属性(参见<script>
属性); modules are deferred automatically.模块会自动延迟。
We don't need the defer
on the main.js
script.我们不需要
main.js
脚本上的defer
。
Now Markdown
is in the global scope available to main.js
and we no longer need the import
statement so your entire main.js
should now look like:现在
Markdown
位于 main.js 可用的全局main.js
中,我们不再需要import
语句,因此您的整个main.js
现在应该如下所示:
var text = "**Markdown rocks**"
var converter = new Markdown.Converter();
var html = converter.makeHtml(text);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.