首页 > 解决方案 > 如何使用 Typescript 和 Webpack 捆绑纯 JavaScript 依赖项

问题描述

我有一个带有 Webpack 的简单 Typescript Web 应用程序,我正在尝试包含一个不导出任何模块/函数的纯 JavaScript 库。说明要求您添加一个脚本标签,这会将对象和函数添加到全局变量中,可以在整个应用程序中使用。而不是这样做,我想使用 webpack 将其捆绑在最终的 javascript 包中,并使其公开的对象和函数在全局变量中可用(因此可以以相同的方式使用它)。

到目前为止,我可以让 webpack 在包中包含 javascript 的唯一方法是将以下内容添加到我的 index.ts 中:

require("./lib/exolve-m")

虽然这会打包 javascript,但它会将它(应该如此)包装在一个公开导出的函数中。然而,这个包不使用 export 关键字,而且它们也没有加载到全局命名空间中。所以我留下了我无法访问的捆绑代码。

请问这样做的正确方法是什么?

标签: javascripttypescriptwebpack

解决方案


TL;DR:这个库与 js/ts 模块系统不兼容。您将不得不对其进行修改。


它声称以下内容:

 * The Exolve code creates only the following names at global scope:
 *
 * - Exolve
 * - createExolve
 * - createPuzzle (deprecated).
 * - exolvePuzzles

但这样做的方式是在根文件范围内声明变量。当 Web 浏览器通过<script>标记直接包含此文件时,此技术会创建全局变量。

// Run this in your browser console:
var foo = 123
console.log(window.foo) // returns: 123

这通常被认为是一种不好的做法,在像 Webpack 这样的打包工具之前,将代码包装在一个函数中以防止这种行为并避免污染全局范围是一种常见的做法。

(function() {
  var bar = 123;
  console.log(window.bar); // returns undefined
})()

但是,可悲的是,这是 exolve 库依赖于这种创建全局变量的方法来工作的行为。


但是,当您使用捆绑程序时,这一切都会改变。捆绑器将所有导入的文件包装在可以调用以获取该文件内容的函数中。这完全破坏了这种创建全局变量的方法,因为var语句不再处于全局范围内。

因此,当您将其作为模块导入时,它会在该模块内部创建一堆局部变量,不导出任何内容,并且保持全局范围不变。所以根本没有办法访问库中的代码。

这意味着该库与作为模块导入不兼容。


我认为你最好的选择是修改图书馆。只需在export要使用的声明中添加一个。例如,替换:

function Exolve(puzzleText,
                containerId="",
                customizer=null,
                addStateToUrl=true,
                visTop=0,
                maxDim=0)

export function Exolve(puzzleText,
                containerId="",
                customizer=null,
                addStateToUrl=true,
                visTop=0,
                maxDim=0)

现在您像任何其他模块一样导入项目:

import { Exolve } from "./exolve-m";

这里的工作示例


推荐阅读