简体   繁体   English

无法将外部 JS 库导入 web 应用程序

[英]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.*.jspagedown/Markdown.*.js ,但两者都出现了相同的错误。

I'm not really sure what I'm doing wrong here.我不确定我在这里做错了什么。

1. Literal answer 1.字面答案

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';

2. Module error 2.模块错误

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”的导出

3. The fix 3.修复

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语句

3.1 ESM to non-ESM 3.1 ESM 到非 ESM

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>

3.1.1 ESM script loading note 3.1.1 ESM脚本加载说明

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

3.2 Remove the import 3.2 删除导入

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM