网站搜索

javascript - 使用 parcel 引入 typescript 依赖


我正在使用 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

我正在使用:

  • 包裹 1.10.1
  • 节点 v8.12.0
  • npm 6.4.1
  • Ubuntu 18.04.1 64位
  • 谷歌浏览器 70

我认为这个问题与引入 bootstrap 有关。以下代码可以使用:

import $ from "jquery";

//import "bootstrap";

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

所以我的 TypeScript 代码的依赖实际上是由 Parcel 处理的。但 Bootstrap 也需要 jQuery,而这 somehow 没有被满足。

答案#1

实际上 Parcel 并没有参与这个问题,主要是因为 jQuery/Bootstrap 依赖于 $ 和 jQuery 函数在全局作用域中被暴露。

通过执行以下操作,这相当容易实现(仅针对 JS,因为 TS 会抱怨 window 没有属性 $ 和 jQuery):

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

但由于你正在使用 TypeScript,你还需要做更多工作以使 linting 和智能提示支持正常工作。

  1. 安装 TypeScript 定义文件 npm install --save-dev @types/jquery @types/bootstrap
  2. 使用 import * as $from 'jquery'; 来导入它。
  3. 为 DOM API 配置库,因为在 TypeScript 中默认未启用,这将允许你使用合适的 window 和 document,但你需要将 window 改为 (<any> window)

    tsconfig.json

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

答案#2

我用这个 .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"
  }
}

相关文章