Skip to content

Commit

Permalink
docs(custom): 优化 crx-manifest-webpack-plugin 文档
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidKk committed Oct 25, 2023
1 parent c92bac6 commit ac46424
Show file tree
Hide file tree
Showing 38 changed files with 542 additions and 49 deletions.
6 changes: 6 additions & 0 deletions @docs/webpack-plugin/crx-live-reload-webpack-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: CRX LiveReload Plugin
keywords: [chrome, extension]
---

<embed-project src="@dumlj/crx-live-reload-webpack-plugin"></embed-project>
6 changes: 0 additions & 6 deletions @docs/webpack-plugin/sse-live-reload-webpack-plugin.md

This file was deleted.

20 changes: 20 additions & 0 deletions @webpack-plugin/crx-live-reload-webpack-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- This file is dynamically generated. please edit in __readme__ -->

# Crx Live Reload Webpack Plugin

Livereload over SSE for develop Chrome Extension.

## INSTALL

```bash
# use npm
$ npm install --dev @dumlj/crx-live-reload-webpack-plugin
# use yarn
$ yarn add --dev @dumlj/crx-live-reload-webpack-plugin
# use pnpm
$ pnpm add @dumlj/crx-live-reload-webpack-plugin -D
```

## LIVE DEMO

<stackblitz-live-demo height="800px" src="@dumlj-example/crx-live-reload-webpack-plugin"></stackblitz-live-demo>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"installDependencies": false,
"startCommand": "yarn install && yarn serve"
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@dumlj-example/crx-live-reload-webpack-plugin",
"version": "0.0.1",
"private": true,
"main": "webpack.config.ts",
"scripts": {
"serve": "yarn webpack serve -c webpack.config.ts"
},
"dependencies": {
"@dumlj/vitrual-webpack-plugin": "^0.0.1",
"@dumlj/crx-live-reload-webpack-plugin": "0.0.1"
},
"devDependencies": {
"webpack": "^5",
"webpack-cli": "^5"
},
"optionalDependencies": {
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@babel/register": "^7.22.15"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import path from 'path'
import { type Configuration } from 'webpack'
import { VitrualWebpackPlugin } from '@dumlj/vitrual-webpack-plugin'
import { CrxLiveReloadWebpackPlugin } from '@dumlj/crx-live-reload-webpack-plugin'

const CONFIG: Configuration = {
mode: 'development',
// devServer: {
// devMiddleware: {
// writeToDisk: true,
// },
// },
entry: {
background: path.join(__dirname, 'index.ts'),
},
plugins: [new VitrualWebpackPlugin({ readFromDisk: true }), new CrxLiveReloadWebpackPlugin()],
}

export default CONFIG
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## LIVE DEMO

<stackblitz-live-demo height="800px" src="@dumlj-example/crx-live-reload-webpack-plugin"></stackblitz-live-demo>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "@dumlj/sse-live-reload-webpack-plugin",
"name": "@dumlj/crx-live-reload-webpack-plugin",
"version": "0.0.1",
"description": "livereload over SSE when developing with devServe",
"description": "Livereload over SSE for develop Chrome Extension.",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/dumlj/dumlj-build",
"directory": "@webpack-plugin/sse-live-reload-webpack-plugin"
"directory": "@webpack-plugin/crx-live-reload-webpack-plugin"
},
"license": "MIT",
"main": "./libs/index.js",
Expand All @@ -25,6 +25,9 @@
"webpack": "5.x",
"webpack-dev-server": "4.x"
},
"optionalDependencies": {
"@types/chrome": "^0.0.193"
},
"publishConfig": {
"access": "public"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,27 @@ import type { Compiler } from 'webpack'
import type WebpackDevServer from 'webpack-dev-server'
import { SSE_HEADERS, SSE_SESSION_ID, SSE_RELOAD_TOKEN } from './constants/sse'
import { BACKGROUND_DEFAULT_FILE, CONTENT_SCRIPT_DEFAULT_FILE } from './constants/crx'

export interface SseResponse<T = any> {
code: number
success: boolean
data: T
}
import type { SseResponse } from './types'

export interface Client {
id: string
res: ServerResponse
}

export interface SseLiveReloadWebpackPluginParams {
export interface CrxLiveReloadWebpackPluginParams {
host: string
port: number
}

export interface SseLiveReloadWebpackPluginOptions extends SeedWebpackPluginOptions {
export interface CrxLiveReloadWebpackPluginOptions extends SeedWebpackPluginOptions {
/** 后台 JS 文件 */
background?: string
/** 注入的 JS 文件 */
contentScript?: string
}

export class SseLiveReloadWebpackPlugin extends SeedWebpackPlugin {
static PLUGIN_NAME = 'sse-live-reload-webpack-plugin'
export class CrxLiveReloadWebpackPlugin extends SeedWebpackPlugin {
static PLUGIN_NAME = 'crx-live-reload-webpack-plugin'

protected clients: Client[]
protected host: string
Expand All @@ -42,7 +37,7 @@ export class SseLiveReloadWebpackPlugin extends SeedWebpackPlugin {
return `http://${this.host}:${this.port}/__livereload__`
}

constructor(params?: SseLiveReloadWebpackPluginParams, options?: SseLiveReloadWebpackPluginOptions) {
constructor(params?: CrxLiveReloadWebpackPluginParams, options?: CrxLiveReloadWebpackPluginOptions) {
super(options)

const { host = '0.0.0.0', port = 8182 } = params || {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { info } from './services/logger'
import sse from './services/sse'
import { onRuntimeMessage } from './utils/sender'
import * as Actions from './constants/action'

// 清除旧日志
// eslint-disable-next-line no-console
console.clear()

// 注册SSE服务
sse()

// 注册心跳服务
// 虽然不需要处理但是也必须注册, 否则调用方会报错
onRuntimeMessage(Actions.HEART_BEAT, () => ({ ok: true }))

// 注册完毕
info('LiveReload in Background is ready.')
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** 心跳 */
export const HEART_BEAT = 'HEART_BEAT'

/** 重载 */
export const LIVERELOAD = 'LIVERELOAD'

/** 日志 */
export const LOG = 'LOG'
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** 标识 */
export const LIVERELOAD_MESSAGE_TARGET = 'livereload'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { info } from './services/logger'
import { sendRuntimeMessage, onRuntimeMessage } from './utils/sender'
import * as Actions from './constants/action'

/** 心跳 */
const heartBeat = async (duration = 1e3) => {
try {
await sendRuntimeMessage(Actions.HEART_BEAT)
} catch (error) {
window.location.reload()
}

setTimeout(heartBeat, duration)
}

// 注册心跳
heartBeat()

// 注册重置服务
onRuntimeMessage(Actions.LIVERELOAD, () => window.location.reload())

// 注册完毕
info('LiveReload in Content-Script is ready.')
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { sendRuntimeMessage, onRuntimeMessage } from '../utils/sender'
import * as Actions from '../constants/action'

/** 是否为 Background */
const isBackground = typeof window === 'undefined'

export interface LogMessage {
type: 'ok' | 'info' | 'warn' | 'fail' | 'debug'
message: string
}

const banner = 'LiveReload'
const time = () => {
const now = new Date()
return `${now.getHours()}:${now.getMinutes()}:${now.getMinutes()}`
}

const styleTime = (color = '#777777') => `font-weight:bold;color:#fff;background-color:${color};`
const styleBanner = (color: string) => `font-weight:bold;color:#fff;background-color:${color};`
const styleMessage = (color: string) => `font-weight:normal;color:${color};`

const _ok = (message: string, styles = '') => {
const content = `%c[${time()}]%c[${banner}]%c ${message}`
// eslint-disable-next-line no-console
console.log(content, styleTime(), styleBanner('#1cdc9a'), styleMessage('#1cdc9a'), styles)
}

const _info = (message: string, styles = '') => {
const conten = `%c[${time()}]%c[${banner}]%c ${message}`
// eslint-disable-next-line no-console
console.info(conten, styleTime(), styleBanner('#1890ff'), styleMessage('#1890ff'), styles)
}

const _warn = (message: string, styles = '') => {
const content = `%c[${time()}]%c[${banner}]%c ${message}`
// eslint-disable-next-line no-console
console.warn(content, styleTime(), styleBanner('#fdbc4b'), styleMessage('#fdbc4b'), styles)
}

const _fail = (message: string, styles = '') => {
const content = `%c[${time()}]%c[${banner}]%c ${message}`
// eslint-disable-next-line no-console
console.error(content, styleTime(), styleBanner('#c0392b'), styleMessage('#c0392b'), styles)
}

const _debug = (message: string, styles = '') => {
const content = `%c[${time()}]%c[${banner}]%c ${message}`
// eslint-disable-next-line no-console
console.debug(content, styleTime(), styleBanner('#777777'), styleMessage('#777777'), styles)
}

export const ok = (message: string) => {
if (isBackground) {
_ok(message)
return
}

_ok(message)
sendRuntimeMessage(Actions.LOG, { type: 'ok', message })
}

export const info = (message: string) => {
if (isBackground) {
_info(message)
return
}

_info(message)
sendRuntimeMessage(Actions.LOG, { type: 'info', message })
}

export const warn = (message: string) => {
if (isBackground) {
_warn(message)
return
}

_warn(message)
sendRuntimeMessage(Actions.LOG, { type: 'warn', message })
}

export const fail = (message: string) => {
if (isBackground) {
_fail(message)
return
}

_fail(message)
sendRuntimeMessage(Actions.LOG, { type: 'fail', message })
}

export const debug = (message: string) => {
if (isBackground) {
_debug(message)
return
}

_debug(message)
sendRuntimeMessage(Actions.LOG, { type: 'debug', message })
}

if (isBackground) {
onRuntimeMessage<LogMessage>(Actions.LOG, async (payload, sender) => {
const from = `By ${sender.url}`
switch (payload.type) {
case 'ok': {
_ok(`${payload.message} %c${from}`, 'color:#999;')
break
}
case 'info': {
_info(`${payload.message} %c${from}`, 'color:#999;')
break
}
case 'fail': {
_fail(`${payload.message} %c${from}`, 'color:#999;')
break
}
case 'warn': {
_warn(`${payload.message} %c${from}`, 'color:#999;')
break
}
case 'debug': {
_debug(`${payload.message} %c${from}`, 'color:#999;')
break
}
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { broadcastTabs } from '../utils/sender'
import * as Actions from '../constants/action'
import { SSE_RELOAD_TOKEN } from '../../constants/sse'
import type { SseResponse } from '../../types'

/** 重载 */
export const reload = () => {
if (typeof chrome?.runtime?.reload === 'function') {
// 广播重载
broadcastTabs(Actions.LIVERELOAD)

// 重载
setTimeout(() => {
// eslint-disable-next-line no-console
console.clear()
chrome.runtime.reload()
}, 100)
}
}

let es: EventSource = null

/** 启动 */
export const sse = () => {
if (!(process.env.LIVERELOAD_SSE_URL && process.env.LIVERELOAD_SSE_SID)) {
return
}

es = new EventSource(`${process.env.LIVERELOAD_SSE_URL}?sid=${process.env.LIVERELOAD_SSE_SID}`)
es.onmessage = ({ data }) => {
const response: SseResponse = JSON.parse(data)
if (response.code === 0 && response.data === SSE_RELOAD_TOKEN) {
reload()
}
}

es.onerror = () => {
// 断开重连
if (es.readyState === 2) {
setTimeout(sse, 3e3)
}
}
}

export default sse
Loading

0 comments on commit ac46424

Please sign in to comment.