使用 Parcel 导入 TypeScript 依赖项

3

我正在使用parcel处理web扩展的typescript。 JQuery及其类型定义已通过npm安装。 在我的typescript文件顶部,我有:

import $ from "jquery";
import "bootstrap";

但在运行时,Chrome报错称jquery未定义。 可以通过以下git示例来重现问题:https://github.com/lhk/parcel_jquery_bug_demo
git clone https://github.com/lhk/parcel_jquery_bug_demo
cd parcel_jquery_bug_demo
npm install
parcel build src/manifest.json

现在你可以打开Chrome并加载dist文件夹

该Git仓库包含:

src/manifest.json

{
  "manifest_version": 2,
  "name": "pc",
  "version": "0.0.1",
  "description": "none",
  "author": "",
  "content_security_policy":"script-src 'self'; object-src 'self'",
  "content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": [
         "./content/index.ts"]
    }
  ]
}

src/content/index.ts

import $ from "jquery";
import "bootstrap";

$(function () {
  $('[data-toggle="popover"]').popover();
});

./package.json

{
  "name": "pc",
  "version": "0.1.0",
  "description": "",
  "author": "",
  "license": "",
  "devDependencies": {
    "parcel-plugin-web-extension": "^1.4.0",
    "typescript": "^3.1.3"
  },
  "dependencies": {
    "@types/bootstrap": "^3.3.7",
    "@types/jquery": "^3.3.10",
    "bootstrap": "^3.3.7",
    "jquery": "^3.3.1"
  }
}

在chrome中加载扩展程序后,您可以加载任何网站。错误消息如下:

未捕获的引用错误:jQuery未定义

我正在使用以下工具:
  • Parcel 1.10.1
  • Node v8.12.0
  • npm 6.4.1
  • ubuntu 18.04.1 64bit
  • chrome 70
我认为这个问题与引入bootstrap有关。以下代码有效:
import $ from "jquery";

//import "bootstrap";

$(function () {
  //$('[data-toggle="popover"]').popover();
  $('[data-toggle="popover"]').click(function(){});
});

因此,我的TypeScript代码的依赖关系实际上是由Parcel处理的。但是Bootstrap还需要jQuery,而这种依赖关系似乎没有得到满足。


1
你是对的。Bootstrap 依赖于一个全局变量,但在模块化环境中加载 jQuery 时并没有创建该变量。 - Aluan Haddad
1
是的,这是一个非常有用的提示(没有讽刺意味)。在包问题跟踪器上,有人告诉我同样的事情。你可以通过手动将jQuery添加到窗口来使其工作。但这样做相当于破解补丁。如果npm和parcel能以某种方式解决这个问题就太好了。有更清晰的方法吗? - lhk
2个回答

3

实际上,Parcel 对此问题没有什么作用,主要原因是 jQuery/Bootstrap 依赖于全局范围中公开的 $jQuery 函数。

通过以下方式可以很容易地将其存档(仅适用于 JS,因为 TS 会抱怨 window 没有属性 $jQuery):

import jquery from "jquery";
window.$ = window.jQuery = jquery;
import "bootstrap";

但是,由于你正在使用TypeScript,为了让语法检查和智能提示正常工作,你需要做更多的工作。

  1. Install the TypeScript definition file npm install --save-dev @types/jquery @types/bootstrap
  2. use import * as $ from 'jquery'; to import it.
  3. Configure the libs for the DOM api since they are not enable by default for TypeScript, this will allow you to use a proper window and document but you need to change window to (<any> window)

    tsconfig.json

    {
      "compilerOptions": {
        //...
        "lib": ["dom"],
        //...
      },
    }  
    

1

我在这个 .babelrc 文件中添加了一个 Babel 插件 (babel-plugin-auto-import)

  {
    "plugins": [[
      "auto-import", {
        "declarations": [
          { "anonymous": ["jQuery"], "path": "jquery" }
        ]
      }
    ]]
  }

一切似乎都在运行。

新的 package.json 文件

{
  "name": "pc",
  "version": "0.1.0",
  "description": "",
  "author": "",
  "license": "",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-plugin-auto-import": "^0.9.3",
    "parcel-plugin-web-extension": "^1.4.0",
    "typescript": "^3.1.3"
  },
  "dependencies": {
    "@types/bootstrap": "^3.3.7",
    "@types/jquery": "^3.3.10",
    "bootstrap": "^3.3.7",
    "jquery": "^3.3.1"
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接