Plasmo 浏览器扩展项目 tsconfig 与 ~ 别名

Plasmo 写 Chrome 扩展项目,脚手架给的 tsconfig.json 是这样:

{
  "extends": "plasmo/templates/tsconfig.base",
  "exclude": ["node_modules"],
  "include": [
    ".plasmo/index.d.ts",
    "./**/*.ts",
    "./**/*.tsx"
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~*": ["./*"]
    }
  }
}

一份不到 20 行,但每一行都干活。

每行在做什么

  • extends: "plasmo/templates/tsconfig.base" — 继承 Plasmo 的严格模式基线(strictesModuleInteropjsx: react 等),只覆盖必要项
  • exclude: ["node_modules"] — 不给 TS 检查依赖
  • include: [".plasmo/index.d.ts", ...] — 包含 Plasmo 生成的类型声明和项目源码
  • baseUrl: "." — 相对根目录解析
  • paths: { "~*": ["./*"] }~utils 会被解析成 ./utils

想把代码搬进 src/

Plasmo 默认允许代码散在根目录(popup.tsxbackground.ts 直接扔外面)。你想集中放 src/ 下,tsconfig 需要相应改:

{
  "extends": "plasmo/templates/tsconfig.base",
  "exclude": ["node_modules"],
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    ".plasmo/index.d.ts"
  ],
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "~*": ["./*"],
      "@*": ["./*"]
    }
  }
}

三处变化:

  1. include./** 改成 src/**
  2. baseUrl. 改成 src
  3. paths 里 ~@ 都指到 src 根

之后代码里:

import Button from "~/components/Button";
import { fetchUser } from "@/api/user";

会被解析为 src/components/Button.tsxsrc/api/user.ts

Plasmo 的 url: 前缀

Plasmo 基于 Parcel 打包,导入 HTML 或图片资源有个特殊语法:

import fontPickerHTML from "url:./panels/font-picker/index.html";

url: 前缀告诉 Parcel”不要把这个当代码解析、当静态资源处理,导出打包后的 URL”。编译产物大致是:

const fontPickerHTML = "/assets/font-picker.abc123.html";

用途:chrome.windows.create({ url: fontPickerHTML }) 打开一个扩展页面。

代码搬进 src 后要配合修改:

import fontPickerHTML from "url:~/panels/font-picker/index.html";

因为 ~ 现在指向 src/

除了 url: 还有

Parcel 支持多个前缀,Plasmo 都能用:

  • url: — 当资源,返回 URL 字符串
  • data-url: — 编码成 base64 data URL
  • raw: — 读文件原始内容为字符串
  • bundle: — 把整个 JS 打成单独 bundle
  • data-text: — 直接嵌入文本

例如把某个 css 内联进背景 script:

import css from "raw:~/styles/inject.css";
chrome.scripting.insertCSS({ target: { tabId }, css });

Chrome 扩展 tsconfig 常见字段

Plasmo base 已经配好,但了解一下:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "react",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "types": ["chrome"]     // 让 chrome.* API 有类型
  }
}

types: ["chrome"] 是关键——扩展项目里 chrome.storagechrome.runtime 得靠它。Plasmo base 里默认带了。

一句话总结

Plasmo 的 ~ 别名跟着 baseUrl 走:搬到 src/ 就把 baseUrl 改成 src、include 换成 src/**url: 前缀是 Parcel 特有的静态资源导入,改路径时别忘了同步。