diff --git a/.changeset/thirty-shirts-grow.md b/.changeset/thirty-shirts-grow.md new file mode 100644 index 00000000..9281088e --- /dev/null +++ b/.changeset/thirty-shirts-grow.md @@ -0,0 +1,16 @@ +--- +"all": patch +"packer": patch +"plugins": patch +"record": patch +"replay": patch +"rrdom": patch +"rrdom-nodejs": patch +"rrweb": patch +"rrweb-player": patch +"rrweb-snapshot": patch +"types": patch +"utils": patch +--- + +Provide a /umd/ output folder alongside the /dist/ one so that we can serve UMD (Universal Module Definition) files with a .js extension, without upsetting expectations set by package.json that all .js files in /dist/ are modules diff --git a/.gitignore b/.gitignore index 42662613..f5fee78e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ temp # output of `yarn build` build dist +umd # turbo cache .turbo diff --git a/README.md b/README.md index 856d8b90..01e54198 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ [![Join the chat at slack](https://img.shields.io/badge/slack-@rrweb-teal.svg?logo=slack)](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg) [![Twitter Follow](https://img.shields.io/badge/twitter-@rrweb__io-teal.svg?logo=twitter)](https://twitter.com/rrweb_io) [![Reddit](https://img.shields.io/badge/reddit-r/rrweb-teal.svg?logo=reddit)](https://www.reddit.com/r/rrweb) -![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/record@latest/dist/record.min.js?compression=gzip&label=recorder%20gzip%20size&max=200000&softmax=100000) -![replayer gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/replay.min.js?compression=gzip&label=replayer%20gzip%20size&max=200000&softmax=100000) +![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js?compression=gzip&label=recorder%20gzip%20size&max=200000&softmax=100000) +![replayer gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/umd/replay.min.js?compression=gzip&label=replayer%20gzip%20size&max=200000&softmax=100000) [![](https://data.jsdelivr.com/v1/package/npm/rrweb/badge)](https://www.jsdelivr.com/package/npm/rrweb) [中文文档](./README.zh_CN.md) diff --git a/README.zh_CN.md b/README.zh_CN.md index 7e49f0ee..7f250b24 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -11,8 +11,8 @@ [![Join the chat at slack](https://img.shields.io/badge/slack-@rrweb-teal.svg?logo=slack)](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg) [![Reddit](https://img.shields.io/badge/reddit-r/rrweb-teal.svg?logo=reddit)](https://www.reddit.com/r/rrweb) -![total gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/rrweb@latest/dist/rrweb.min.cjs?compression=gzip&label=total%20gzip%20size) -![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/rrweb@latest/dist/record/rrweb-record.min.cjs?compression=gzip&label=recorder%20gzip%20size) +![total gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/rrweb@latest/umd/rrweb.min.js?compression=gzip&label=total%20gzip%20size) +![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js?compression=gzip&label=recorder%20gzip%20size) [![](https://data.jsdelivr.com/v1/package/npm/rrweb/badge)](https://www.jsdelivr.com/package/npm/rrweb) > 我已开通 Github Sponsor, 您可以通过赞助的形式帮助 rrweb 的开发。 diff --git a/guide.md b/guide.md index 887382a0..96727a49 100644 --- a/guide.md +++ b/guide.md @@ -15,13 +15,13 @@ You are recommended to install rrweb via jsdelivr's CDN service: rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css" /> - + ``` Also, you can link to a specific version number that you can update manually: ```html - + ``` #### Only include the recorder code @@ -30,7 +30,7 @@ rrweb's code includes both the record and the replay parts. Most of the time you This also can be done by using the `@rrweb/record` package and the CDN service: ```html - + ``` The recorder UMD build exposes a global named `rrwebRecord`. @@ -42,7 +42,7 @@ The recorder UMD build exposes a global named `rrwebRecord`. rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css" /> - + ``` The replayer UMD build exposes a global named `rrwebReplay`. @@ -340,7 +340,7 @@ rrweb-player can also be included with ` + ``` Or installed by using NPM: diff --git a/guide.zh_CN.md b/guide.zh_CN.md index aa7ee438..8786e03a 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -13,13 +13,13 @@ rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css" /> - + ``` 也可以在 URL 中指定具体的版本号,例如: ```html - + ``` #### 仅引入录制部分 @@ -27,7 +27,7 @@ rrweb 代码分为录制和回放两部分,大多数时候用户在被录制的应用中只需要引入录制部分代码。同样可以通过使用 @rrweb/record 包和 CDN 服务来实现: ```html - + ``` 录制端的 UMD build 会暴露全局变量 `rrwebRecord`。 @@ -39,7 +39,7 @@ rrweb 代码分为录制和回放两部分,大多数时候用户在被录制 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css" /> - + ``` 回放端的 UMD build 会暴露全局变量 `rrwebReplay`。 @@ -334,7 +334,7 @@ rrweb-player 同样可以使用 CDN 方式安装: rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css" /> - + ``` 或者通过 npm 安装: diff --git a/packages/all/package.json b/packages/all/package.json index 1c82ec37..9807b7ff 100644 --- a/packages/all/package.json +++ b/packages/all/package.json @@ -44,6 +44,7 @@ } }, "files": [ + "umd", "build", "dist", "package.json" diff --git a/packages/plugins/rrweb-plugin-canvas-webrtc-record/package.json b/packages/plugins/rrweb-plugin-canvas-webrtc-record/package.json index 3507a881..b31c9d16 100644 --- a/packages/plugins/rrweb-plugin-canvas-webrtc-record/package.json +++ b/packages/plugins/rrweb-plugin-canvas-webrtc-record/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/plugins/rrweb-plugin-canvas-webrtc-replay/package.json b/packages/plugins/rrweb-plugin-canvas-webrtc-replay/package.json index 8c11d607..6c15c3cc 100644 --- a/packages/plugins/rrweb-plugin-canvas-webrtc-replay/package.json +++ b/packages/plugins/rrweb-plugin-canvas-webrtc-replay/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/plugins/rrweb-plugin-console-record/package.json b/packages/plugins/rrweb-plugin-console-record/package.json index a5d98992..a7803d3d 100644 --- a/packages/plugins/rrweb-plugin-console-record/package.json +++ b/packages/plugins/rrweb-plugin-console-record/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/plugins/rrweb-plugin-console-replay/package.json b/packages/plugins/rrweb-plugin-console-replay/package.json index 0f7d9038..8442d7f9 100644 --- a/packages/plugins/rrweb-plugin-console-replay/package.json +++ b/packages/plugins/rrweb-plugin-console-replay/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/plugins/rrweb-plugin-sequential-id-record/package.json b/packages/plugins/rrweb-plugin-sequential-id-record/package.json index 25128478..fb0a8207 100644 --- a/packages/plugins/rrweb-plugin-sequential-id-record/package.json +++ b/packages/plugins/rrweb-plugin-sequential-id-record/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/plugins/rrweb-plugin-sequential-id-replay/package.json b/packages/plugins/rrweb-plugin-sequential-id-replay/package.json index 3228f84c..4bd951a1 100644 --- a/packages/plugins/rrweb-plugin-sequential-id-replay/package.json +++ b/packages/plugins/rrweb-plugin-sequential-id-replay/package.json @@ -20,6 +20,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/record/package.json b/packages/record/package.json index 0bc9ebfd..d6d1afaf 100644 --- a/packages/record/package.json +++ b/packages/record/package.json @@ -44,6 +44,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/replay/package.json b/packages/replay/package.json index 8c821627..a73dce8b 100644 --- a/packages/replay/package.json +++ b/packages/replay/package.json @@ -45,6 +45,7 @@ "./dist/style.css": "./dist/style.css" }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrdom-nodejs/package.json b/packages/rrdom-nodejs/package.json index b58b0d88..bc5ab3f9 100644 --- a/packages/rrdom-nodejs/package.json +++ b/packages/rrdom-nodejs/package.json @@ -33,6 +33,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrdom/package.json b/packages/rrdom/package.json index dbd14207..f82b48e1 100644 --- a/packages/rrdom/package.json +++ b/packages/rrdom/package.json @@ -21,6 +21,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrweb-player/README.md b/packages/rrweb-player/README.md index e80d2007..15fcf4c8 100644 --- a/packages/rrweb-player/README.md +++ b/packages/rrweb-player/README.md @@ -19,7 +19,7 @@ rrweb-player can also be included with ` + ``` Or installed by using NPM: diff --git a/packages/rrweb-player/package.json b/packages/rrweb-player/package.json index bd061db0..a15adea2 100644 --- a/packages/rrweb-player/package.json +++ b/packages/rrweb-player/package.json @@ -51,6 +51,7 @@ "./dist/style.css": "./dist/style.css" }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrweb-snapshot/package.json b/packages/rrweb-snapshot/package.json index 209705da..39e4b35e 100644 --- a/packages/rrweb-snapshot/package.json +++ b/packages/rrweb-snapshot/package.json @@ -44,6 +44,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrweb/package.json b/packages/rrweb/package.json index 4e8474c5..b3f8a425 100644 --- a/packages/rrweb/package.json +++ b/packages/rrweb/package.json @@ -49,6 +49,7 @@ "./dist/style.css": "./dist/style.css" }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/rrweb/rollup.config.js b/packages/rrweb/rollup.config.js deleted file mode 100644 index 998433bd..00000000 --- a/packages/rrweb/rollup.config.js +++ /dev/null @@ -1,261 +0,0 @@ -import typescript from 'rollup-plugin-typescript2'; -import esbuild from 'rollup-plugin-esbuild'; -import resolve from '@rollup/plugin-node-resolve'; -import postcss from 'rollup-plugin-postcss'; -import renameNodeModules from 'rollup-plugin-rename-node-modules'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; -import pkg from './package.json'; - -function toRecordPath(path) { - return path - .replace(/^([\w]+)\//, '$1/record/') - .replace('rrweb', 'rrweb-record'); -} - -function toRecordPackPath(path) { - return path - .replace(/^([\w]+)\//, '$1/record/') - .replace('rrweb', 'rrweb-record-pack'); -} - -function toReplayPath(path) { - return path - .replace(/^([\w]+)\//, '$1/replay/') - .replace('rrweb', 'rrweb-replay'); -} - -function toReplayUnpackPath(path) { - return path - .replace(/^([\w]+)\//, '$1/replay/') - .replace('rrweb', 'rrweb-replay-unpack'); -} - -function toAllPath(path) { - return path.replace('rrweb', 'rrweb-all'); -} - -function toPluginPath(pluginName, stage) { - return (path) => - path - .replace(/^([\w]+)\//, '$1/plugins/') - .replace('rrweb', `${pluginName}-${stage}`); -} - -function toMinPath(path) { - return path.replace(/\.js$/, '.min.js'); -} - -const baseConfigs = [ - // all in one - { - input: './src/entries/all.ts', - name: 'rrweb', - pathFn: toAllPath, - esm: true, - }, - // record only - { - input: './src/record/index.ts', - name: 'rrwebRecord', - pathFn: toRecordPath, - }, - // record and pack - { - input: './src/entries/record-pack.ts', - name: 'rrwebRecord', - pathFn: toRecordPackPath, - }, - // replay only - { - input: './src/replay/index.ts', - name: 'rrwebReplay', - pathFn: toReplayPath, - }, - // replay and unpack - { - input: './src/entries/replay-unpack.ts', - name: 'rrwebReplay', - pathFn: toReplayUnpackPath, - }, - // record and replay - { - input: './src/index.ts', - name: 'rrweb', - pathFn: (p) => p, - }, - // plugins - { - input: './src/plugins/console/record/index.ts', - name: 'rrwebConsoleRecord', - pathFn: toPluginPath('console', 'record'), - }, - { - input: './src/plugins/canvas-webrtc/record/index.ts', - name: 'rrwebCanvasWebRTCRecord', - pathFn: toPluginPath('canvas-webrtc', 'record'), - }, - { - input: './src/plugins/canvas-webrtc/replay/index.ts', - name: 'rrwebCanvasWebRTCReplay', - pathFn: toPluginPath('canvas-webrtc', 'replay'), - }, - { - input: './src/plugins/console/replay/index.ts', - name: 'rrwebConsoleReplay', - pathFn: toPluginPath('console', 'replay'), - }, - { - input: './src/plugins/sequential-id/record/index.ts', - name: 'rrwebSequentialIdRecord', - pathFn: toPluginPath('sequential-id', 'record'), - }, - { - input: './src/plugins/sequential-id/replay/index.ts', - name: 'rrwebSequentialIdReplay', - pathFn: toPluginPath('sequential-id', 'replay'), - }, -]; - -let configs = []; - -function getPlugins(options = {}) { - const { minify = false, sourceMap = false } = options; - return [ - resolve({ browser: true }), - webWorkerLoader({ - targetPlatform: 'browser', - inline: true, - preserveSource: true, - sourceMap, - }), - esbuild({ - minify, - }), - postcss({ - extract: true, - inject: false, - minimize: minify, - sourceMap, - }), - ]; -} - -for (const c of baseConfigs) { - const basePlugins = [ - resolve({ browser: true }), - - // supports bundling `web-worker:..filename` - webWorkerLoader({ - targetPlatform: 'browser', - inline: true, - preserveSource: true, - }), - - typescript(), - ]; - const plugins = basePlugins.concat( - postcss({ - extract: false, - inject: false, - }), - ); - // browser - configs.push({ - input: c.input, - plugins: getPlugins(), - output: [ - { - name: c.name, - format: 'iife', - file: c.pathFn(pkg.unpkg), - }, - ], - }); - // browser + minify - configs.push({ - input: c.input, - plugins: getPlugins({ minify: true, sourceMap: true }), - output: [ - { - name: c.name, - format: 'iife', - file: toMinPath(c.pathFn(pkg.unpkg)), - sourcemap: true, - }, - ], - }); - // CommonJS - configs.push({ - input: c.input, - plugins, - output: [ - { - format: 'cjs', - file: c.pathFn('lib/rrweb.cjs'), - }, - ], - }); - if (c.esm) { - // ES module - configs.push({ - input: c.input, - plugins, - preserveModules: true, - output: [ - { - format: 'esm', - dir: 'es/rrweb', - plugins: [renameNodeModules('ext')], - }, - ], - }); - } -} - -if (process.env.BROWSER_ONLY) { - const browserOnlyBaseConfigs = [ - { - input: './src/index.ts', - name: 'rrweb', - pathFn: (p) => p, - }, - { - input: './src/entries/all.ts', - name: 'rrweb', - pathFn: toAllPath, - }, - { - input: './src/plugins/console/record/index.ts', - name: 'rrwebConsoleRecord', - pathFn: toPluginPath('console', 'record'), - }, - { - input: './src/plugins/canvas-webrtc/record/index.ts', - name: 'rrwebCanvasWebRTCRecord', - pathFn: toPluginPath('canvas-webrtc', 'record'), - }, - { - input: './src/plugins/canvas-webrtc/replay/index.ts', - name: 'rrwebCanvasWebRTCReplay', - pathFn: toPluginPath('canvas-webrtc', 'replay'), - }, - ]; - - configs = []; - - for (const c of browserOnlyBaseConfigs) { - configs.push({ - input: c.input, - plugins: getPlugins(), - output: [ - { - name: c.name, - format: 'iife', - file: c.pathFn(pkg.unpkg), - }, - ], - }); - } -} - -export default configs; diff --git a/packages/types/package.json b/packages/types/package.json index 7d1b1adb..0c7ebbf7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -42,6 +42,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/packages/utils/package.json b/packages/utils/package.json index 50e8556f..e94d031b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -42,6 +42,7 @@ } }, "files": [ + "umd", "dist", "package.json" ], diff --git a/vite.config.default.ts b/vite.config.default.ts index dabc56ed..fe6d6d6c 100644 --- a/vite.config.default.ts +++ b/vite.config.default.ts @@ -1,9 +1,9 @@ /// import dts from 'vite-plugin-dts'; -import { copyFileSync } from 'node:fs'; +import { copyFileSync, mkdirSync, existsSync } from 'node:fs'; import { defineConfig, LibraryOptions, LibraryFormats, Plugin } from 'vite'; import { build, Format } from 'esbuild'; -import { resolve } from 'path'; +import { resolve, dirname } from 'path'; import { umdWrapper } from 'esbuild-plugin-umd-wrapper'; import * as fs from 'node:fs'; import { visualizer } from 'rollup-plugin-visualizer'; @@ -51,22 +51,38 @@ function minifyAndUMDPlugin({ outDir, }); } else { + const umdDir = dirname(outputFilePath).replace('/dist', '/umd'); + if (!existsSync(umdDir)) { + mkdirSync(umdDir); + } + const outUmd = `${outputFilePath}.umd.cjs`; await buildFile({ name, input: inputFilePath, - output: `${outputFilePath}.umd.cjs`, + output: outUmd, minify: false, isCss: false, outDir, }); + // Workaround because jsdelivr does use correct mime types for .umd.cjs + // More info: https://github.com/jsdelivr/jsdelivr/issues/18584 https://github.com/rrweb-io/rrweb/pull/1704 + copyFileSync( + outUmd, + `${outputFilePath.replace('/dist/', '/umd/')}.js`, + ); + const outUmdMin = `${outputFilePath}.umd.min.cjs`; await buildFile({ name, input: inputFilePath, - output: `${outputFilePath}.umd.min.cjs`, + output: outUmdMin, minify: true, isCss: false, outDir, }); + copyFileSync( + outUmdMin, + `${outputFilePath.replace('/dist/', '/umd/')}.min.js`, + ); } } }