@extend-chrome/messages

中文文档
1.2.2发布于 2021/05/26MITTypeScriptESM + CJS近 30 天下载 3238

An API for Chrome extension messages that makes sense.

原始使用文档
文档目录14 节
  1. @extend-chrome/messages
  2. Table of Contents
  3. Getting started
  4. Installation
  5. Usage
  6. getMessage has great TypeScript support!
  7. Features
  8. TypeScript Definitions
  9. RxJs Observables
  10. Scopes
  11. API
  12. getMessage(greeting)
  13. The messages Namespace
  14. getScope

@extend-chrome/messages logo

@extend-chrome/messages

npm (scoped) GitHub last commit License TypeScript Declarations Included

Fiverr: We make Chrome extensions ko-fi


An API for Chrome extension messaging that makes sense. Uses Promises and Observables for convenience.

Table of Contents

Getting started

You will need to use a bundler like Rollup, Parcel, or Webpack to include this library in the build of Chrome extension.

See rollup-plugin-chrome-extension for an easy way use Rollup to build your Chrome extension!

Installation

$ npm i @extend-chrome/messages

Usage

Send and receive messages using isomorphic message wrappers, or with a traditional messages object.

// messages.js, used in both the background and content script
import { getMessage } from '@extend-chrome/messages'

// getMessage returns [Function, Observable, Function]
export const [sendNumber, numberStream, waitForNumber] = getMessage(
  // String to be used as a greeting
  'NUMBER',
)
// background.js, a background script
import { numberStream } from './messages'

// numberStream is an RxJs Observable
numberStream.subscribe(([n, sender]) => {
  console.log('the data passed to sendNumber', n)
  // Sender is a Chrome runtime MessageSender
  console.log('the message sender', sender)
})
// content.ts, a content script
import { sendNumber } from './messages'

document.body.onclick = () => {
  sendNumber(42) // 42 is logged in the background
}

getMessage has great TypeScript support!

If you're into TypeScript, getMessage is a generic function. It shines when you define the message data type. No more message data type mistakes! Intellisense has you covered.

// messages.ts
import { getMessage } from '@extend-chrome/messages'

interface Stats {
  hi: number
  low: number
  date: string
}

export const [sendStats, statsStream, waitForStats] = getMessage<Stats>('STATS')

// If you have a message type with no data, use void rather than undefined
// This way you can call it with zero arguments
export const [sendReady, readyStream, waitForReady] = getMessage<void>('READY')
// background.ts
import { statsStream } from './messages'

statsStream.subscribe(([{ hi, lo, date }, sender]) => {
  // Intellisense knows this is an Observable of
  // [Stats, chrome.runtime.MessageSender]
})

waitForReady().then(() => {
  console.log('content.ts is ready')
})
// content.ts
import { sendStats } from './messages'

sendStats({ hi: 30, low: 14, date: '11/12/2019' })

// Throws a TS error
sendStats('not a Stats object')

sendReady()

Features

TypeScript Definitions

This library is written in TypeScript, extensively typed, and definitions are included, so no need to install an additional @types library!

RxJs Observables

Version 0.5.0 introduces an RxJs Observable as messages.stream.

Scopes

Version 0.5.0 introduces getScope, a way to use a separate messaging space.

This is useful if you are writing a library for Chrome extensions that uses messages internally, but you don't want to pollute the global messaging space.

API

getMessage(greeting)

import { getMessage } from '@extend-chrome/messages'

const [sendMessage, messageStream, waitForMessage] = getMessage('greeting')

Use this function to create an isomorphic message system. Import it into both the message sender and receiver context (ie, the background page and a content script). getMessage is a TypeScript generic function. See the Usage section for more information, including TypeScript support!

greeting

Type: string

A unique string to identify the message.

Returns: [messageSender, messageStream]

Type: [Function, Observable]

Import the messageSender into the context you wish to send a message. Call the sender with the data you want to send.

messageStream is an Observable of a [data, MessageSender] tuple. Import the messageStream into the context you wish to recieve messages. Subscribe to it with a message handler function.

The messages Namespace

If you're more comfortable with a traditional messages namespace, import the messages object.

messages.send(data, [options])

Sending one-way messages is simple: just call messages.send with an object that includes at least a greeting property.

// content-script.js
import { messages } from '@extend-chrome/messages'

// Simple message with no data
messages.send({ greeting: 'hello' }).then(() => {
  console.log('The message was sent.')
})

// Message with data
messages
  .send({
    greeting: 'with-data',
    // You can use any prop name or value
    data: { x: 1 },
  })
  .then(() => {
    console.log('The message was sent.')
  })

Actually, you can send any data type as a message, but an object with a greeting prop is a nice, flexible pattern.

Get a response with options.async

Set the optional options.async to true to receive a response. Only message listeners with the third sendResponse argument will receive async messages.

// content-script.js
import { messages } from '@extend-chrome/messages'

messages
  .send(
    // Message
    { greeting: 'hello' },
    // Options
    { async: true },
  )
  .then((response) => {
    console.log('They said', response.greeting)
  })

messages.on(handler)

To receive one way messages, use a message handler function with 0 or 1 arguments. This handler will only receive messages sent without the async option.

The return value of the handler is unused.

// background.js
import * as messages from '@extend-chrome/messages'

// Listener should have 2, 1, or 0 arguments
messages.on((message, sender) => {
  if (message.greeting === 'hello') {
    console.log(sender.id, 'said hello')
  }
})
Async Messages

I've found relying on async messages to be a bit of an anti-pattern. Chrome is pretty aggressive about closing the response port, so unless you're doing something synchronous, it's better to use a separate message and use a listener to handle responses.

To receive async messages, use a message handler with 3 arguments. This handler will only receive messages sent with the async option.

The third argument is a sendResponse function, which must be called very quickly, or Chrome will throw an error. Even a single await may make the extension unreliable.

// Async functions are OK!
messages.on(async (message, sender, sendResponse) => {
  if (message.greeting === 'hello') {
    console.log(sender.id, 'said hello')

    await somethingAsync()

    // Still need to call sendResponse
    sendResponse({ greeting: 'goodbye' })
  }
})

messages.off(handler)

Call this with the message handler function you wish to stop using.

messages.stream

Type: Observable

An Observable of all messages in its scope.

import { messages } from '@extend-chrome/messages'

// Receives all messages in the default scope
messages.stream.subscribe(([message, sender, sendResponse]) => {
  if (typeof sendResponse !== 'undefined') {
    // If sendResponse is defined, it must be called
    sendResponse({ greeting: 'message received!' })
  }
})

getScope

This is useful if you are writing a library for Chrome extensions that uses messages internally, but you don't want to pollute the global messaging space.

import { messages, getScope } from '@extend-chrome/messages'

const myScope = getScope('my-library')

// `messages.on` will not receive this message
myScope.send({ greeting: 'hey' })

// `myScope.on` will not receive this message
messages.send({ greeting: 'hello?' })

Note: The Chrome API Event chrome.runtime.onMessage will still receive all messages, but projects using @extend-chrome/messages will not receive messages from other scopes.

版本与发布记录

@extend-chrome/messages 共发布 8 个版本,首次发布于 2020/06/10;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.2.2latest2021/05/265 年前
1.2.2-0beta2021/05/265 年前
1.2.12021/05/265 年前
1.2.02020/12/095 年前
1.2.0-02020/12/025 年前
1.1.22020/06/136 年前

关于 @extend-chrome/messages 的常见问题

@extend-chrome/messages 是什么?

An API for Chrome extension messages that makes sense.

如何安装 @extend-chrome/messages?

在项目目录运行 npm install @extend-chrome/messages,或使用 pnpm add / yarn add / bun add。

@extend-chrome/messages 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@extend-chrome/messages 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@extend-chrome/messages 可以商用吗?

@extend-chrome/messages 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@extend-chrome/messages 的下载量有多少?

根据 npm 官方下载统计,@extend-chrome/messages 在 2026/10/14 – 2026/11/12 这 30 天内被下载 3,238 次,日均约 108 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@extend-chrome/messages 还在维护吗?

最新版本 1.2.2 发布于 2021/05/26(5 年前);至今共发布 8 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/06/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。