From b28e59ef6d122a1d765bf2f2d4de5cc0676f6f5d Mon Sep 17 00:00:00 2001 From: Sherry-hue <37186915+Sherry-hue@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:36:36 +0800 Subject: [PATCH] feat(web): add nativeModules config to bundle it into worker --- .changeset/deep-heads-talk.md | 5 ++ .changeset/hot-adults-wear.md | 40 +++++++++ .changeset/thick-pots-clap.md | 5 ++ packages/web-platform/tsconfig.json | 1 + .../web-explorer/index.native-modules.ts | 12 +++ packages/web-platform/web-explorer/index.ts | 19 ---- .../web-explorer/rsbuild.config.ts | 8 +- .../web-platform/web-rsbuild-plugin/README.md | 48 +++++++++- .../web-rsbuild-plugin/package.json | 12 ++- .../src/loaders/native-modules.ts | 28 ++++++ .../src/pluginWebPlatform.ts | 52 ++++++++++- .../web-rsbuild-plugin/tests/bundle.test.ts | 63 +++++++++++++ .../tests/fixtures/index.native-modules.ts | 9 ++ .../tests/fixtures/index.ts | 9 ++ .../web-rsbuild-plugin/tests/tsconfig.json | 3 + .../background-apis/createNativeModules.ts | 2 + pnpm-lock.yaml | 88 +++++++++++++++++-- 17 files changed, 370 insertions(+), 34 deletions(-) create mode 100644 .changeset/deep-heads-talk.md create mode 100644 .changeset/hot-adults-wear.md create mode 100644 .changeset/thick-pots-clap.md create mode 100644 packages/web-platform/web-explorer/index.native-modules.ts create mode 100644 packages/web-platform/web-rsbuild-plugin/src/loaders/native-modules.ts create mode 100644 packages/web-platform/web-rsbuild-plugin/tests/bundle.test.ts create mode 100644 packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.native-modules.ts create mode 100644 packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.ts create mode 100644 packages/web-platform/web-rsbuild-plugin/tests/tsconfig.json diff --git a/.changeset/deep-heads-talk.md b/.changeset/deep-heads-talk.md new file mode 100644 index 0000000000..2344e4dba3 --- /dev/null +++ b/.changeset/deep-heads-talk.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/web-explorer": patch +--- + +feat: use nativeModulesPath instead of nativeModulesMap to lynx-view. diff --git a/.changeset/hot-adults-wear.md b/.changeset/hot-adults-wear.md new file mode 100644 index 0000000000..774d83251e --- /dev/null +++ b/.changeset/hot-adults-wear.md @@ -0,0 +1,40 @@ +--- +"@lynx-js/web-platform-rsbuild-plugin": minor +--- + +feat: add new parameter `nativeModulesPath` to `pluginWebPlatform({})`. + +After this commit, you can use `nativeModulesPath` to package custom nativeModules directly into the worker, and no longer need to pass `nativeModulesMap` to lynx-view. + +Here is an example: + +- `native-modules.ts`: + +```ts +// index.native-modules.ts +export default { + CustomModule: function(NativeModules, NativeModulesCall) { + return { + async getColor(data, callback) { + const color = await NativeModulesCall('getColor', data); + callback(color); + }, + }; + }, +}; +``` + +- plugin config: + +```ts +// rsbuild.config.ts +import { pluginWebPlatform } from '@lynx-js/web-platform-rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + plugins: [pluginWebPlatform({ + // replace with your actual native-modules file path + nativeModulesPath: path.resolve(__dirname, './index.native-modules.ts'), + })], +}); +``` diff --git a/.changeset/thick-pots-clap.md b/.changeset/thick-pots-clap.md new file mode 100644 index 0000000000..bed1ed1641 --- /dev/null +++ b/.changeset/thick-pots-clap.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/web-worker-runtime": patch +--- + +feat: provide comments for `@lynx-js/web-platform-rsbuild-plugin`. diff --git a/packages/web-platform/tsconfig.json b/packages/web-platform/tsconfig.json index cc7fb47af6..8f93796d36 100644 --- a/packages/web-platform/tsconfig.json +++ b/packages/web-platform/tsconfig.json @@ -20,6 +20,7 @@ { "path": "./web-worker-rpc/tsconfig.json" }, { "path": "./web-mainthread-apis/tsconfig.json" }, { "path": "./web-core/tsconfig.json" }, + { "path": "./web-rsbuild-plugin/tsconfig.json" }, /** packages-end */ ], "include": [], diff --git a/packages/web-platform/web-explorer/index.native-modules.ts b/packages/web-platform/web-explorer/index.native-modules.ts new file mode 100644 index 0000000000..776a5ab446 --- /dev/null +++ b/packages/web-platform/web-explorer/index.native-modules.ts @@ -0,0 +1,12 @@ +export default { + ExplorerModule: function(NativeModules, NativeModulesCall) { + return { + openSchema(value) { + NativeModulesCall('openSchema', value); + }, + openScan() { + NativeModulesCall('openScan'); + }, + }; + }, +}; diff --git a/packages/web-platform/web-explorer/index.ts b/packages/web-platform/web-explorer/index.ts index 033e15eb82..2c6adc271a 100644 --- a/packages/web-platform/web-explorer/index.ts +++ b/packages/web-platform/web-explorer/index.ts @@ -28,24 +28,6 @@ const qrScanner = new QrScanner(video, (result) => { highlightCodeOutline: true, }); -const nativeModulesMap = { - ExplorerModule: URL.createObjectURL( - new Blob( - [`export default function(NativeModules, NativeModulesCall) { - return { - openSchema(value) { - NativeModulesCall('openSchema', value); - }, - openScan() { - NativeModulesCall('openScan'); - }, - }; - }`], - { type: 'text/javascript' }, - ), - ), -}; - setLynxViewUrl(homepage); window.addEventListener('message', (ev) => { if (ev.data && ev.data.method === 'setLynxViewUrl' && ev.data.url) { @@ -65,7 +47,6 @@ function setLynxViewUrl(url: string) { const theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'Dark' : 'Light'; - lynxView.nativeModulesMap = nativeModulesMap; lynxView.onNativeModulesCall = (nm, data) => { if (nm === 'openScan') { lynxView.style.visibility = 'hidden'; diff --git a/packages/web-platform/web-explorer/rsbuild.config.ts b/packages/web-platform/web-explorer/rsbuild.config.ts index d1949b6d62..aab0c772e1 100644 --- a/packages/web-platform/web-explorer/rsbuild.config.ts +++ b/packages/web-platform/web-explorer/rsbuild.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from '@rsbuild/core'; import { codecovWebpackPlugin } from '@codecov/webpack-plugin'; import { pluginWebPlatform } from '@lynx-js/web-platform-rsbuild-plugin'; import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'; +import path from 'path'; const codecovEnabled = !!process.env.CI; console.info('codecov enabled:', codecovEnabled); export default defineConfig({ @@ -56,5 +57,10 @@ export default defineConfig({ }, profile: true, }, - plugins: [pluginWebPlatform({ polyfill: false })], + plugins: [ + pluginWebPlatform({ + polyfill: false, + nativeModulesPath: path.resolve(__dirname, './index.native-modules.ts'), + }), + ], }); diff --git a/packages/web-platform/web-rsbuild-plugin/README.md b/packages/web-platform/web-rsbuild-plugin/README.md index ee619412c2..3f978f1b8c 100644 --- a/packages/web-platform/web-rsbuild-plugin/README.md +++ b/packages/web-platform/web-rsbuild-plugin/README.md @@ -4,11 +4,55 @@ Lynx3 Web Platform rsbuild plugin ## Usage -```javascript +```ts import { pluginWebPlatform } from '@lynx-js/web-platform-rsbuild-plugin'; import { defineConfig } from '@rsbuild/core'; export default defineConfig({ - plugins: [pluginWebPlatform()], + plugins: [pluginWebPlatform({ + // replace with your actual native-modules file path + nativeModulesPath: path.resolve(__dirname, './index.native-modules.ts'), + })], }); ``` + +## Options + +```ts +{ + /** + * Whether to polyfill the packages about Lynx Web Platform. + * + * If it is true, @lynx-js will be compiled and polyfills will be added. + * + * @default true + */ + polyfill?: boolean; + /** + * The absolute path of the native-modules file. + * + * If you use it, you don't need to pass nativeModulesMap in the lynx-view tag, otherwise it will cause duplicate packaging. + * + * When enabled, nativeModules will be packaged directly into the worker chunk instead of being transferred through Blob. + */ + nativeModulesPath?: string; +} +``` + +### nativeModulesPath + +`native-modules.ts` example: + +```ts +// index.native-modules.ts +export default { + CustomModule: function(NativeModules, NativeModulesCall) { + return { + async getColor(data, callback) { + const color = await NativeModulesCall('getColor', data); + callback(color); + }, + }; + }, +}; +``` diff --git a/packages/web-platform/web-rsbuild-plugin/package.json b/packages/web-platform/web-rsbuild-plugin/package.json index 318b30b659..a337b1448a 100644 --- a/packages/web-platform/web-rsbuild-plugin/package.json +++ b/packages/web-platform/web-rsbuild-plugin/package.json @@ -23,18 +23,22 @@ "README.md" ], "scripts": { - "build": "rslib build", - "dev": "rslib build --watch", "test": "vitest" }, + "dependencies": { + "loader-utils": "^3.3.1" + }, "devDependencies": { - "@microsoft/api-extractor": "catalog:", + "@lynx-js/web-core": "workspace:*", + "@lynx-js/web-elements": "workspace:*", "@rsbuild/core": "catalog:rsbuild", - "@rslib/core": "^0.6.7", + "@types/loader-utils": "^2.0.6", + "@types/webpack": "^5.28.5", "typescript": "^5.8.3", "vitest": "^3.1.2" }, "peerDependencies": { + "@lynx-js/web-core": ">0.13.0", "@rsbuild/core": "*" } } diff --git a/packages/web-platform/web-rsbuild-plugin/src/loaders/native-modules.ts b/packages/web-platform/web-rsbuild-plugin/src/loaders/native-modules.ts new file mode 100644 index 0000000000..f9930e9d4f --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/src/loaders/native-modules.ts @@ -0,0 +1,28 @@ +import type { LoaderContext } from 'webpack'; + +interface NativeModulesLoaderOptions { + nativeModulesPath: string; +} + +export default function( + this: LoaderContext, + source: string, +) { + const options = this.getOptions(); + const { nativeModulesPath } = options; + const modifiedSource = source.replace( + /\/\* LYNX_NATIVE_MODULES_IMPORT \*\//g, + `import CUSTOM_NATIVE_MODULES from '${nativeModulesPath}';`, + ).replace( + /\/\* LYNX_NATIVE_MODULES_ADD \*\//g, + `Object.entries(CUSTOM_NATIVE_MODULES).map(([moduleName, moduleFunc]) => { + customNativeModules[moduleName] = moduleFunc( + nativeModules, + (name, data) => + nativeModulesCall(name, data, moduleName), + ); + });`, + ); + + return modifiedSource; +} diff --git a/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts b/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts index 3aab4ad959..b58b41db34 100644 --- a/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts +++ b/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts @@ -3,6 +3,10 @@ // LICENSE file in the root directory of this source tree. import type { RsbuildPlugin } from '@rsbuild/core'; +import path from 'path'; + +const __filename = new URL('', import.meta.url).pathname; +const __dirname = path.dirname(__filename); /** * The options for {@link pluginWebPlatform}. @@ -13,11 +17,19 @@ export interface PluginWebPlatformOptions { /** * Whether to polyfill the packages about Lynx Web Platform. * - * If it is true, @lynx-js will be compiled and polyfills will be added + * If it is true, @lynx-js will be compiled and polyfills will be added. * * @default true */ polyfill?: boolean; + /** + * The absolute path of the native-modules file. + * + * If you use it, you don't need to pass nativeModulesMap in the lynx-view tag, otherwise it will cause duplicate packaging. + * + * When enabled, nativeModules will be packaged directly into the worker chunk instead of being transferred through Blob. + */ + nativeModulesPath?: string; } /** @@ -30,7 +42,10 @@ export interface PluginWebPlatformOptions { * import { defineConfig } from '@rsbuild/core'; * * export default defineConfig({ - * plugins: [pluginWebPlatform()], + * plugins: [pluginWebPlatform({ + * // replace with your actual native-modules file path + * nativeModulesPath: path.resolve(__dirname, './index.native-modules.ts'), + * })], * }) * ``` * @@ -47,6 +62,15 @@ export function pluginWebPlatform( }; const options = Object.assign({}, defaultPluginOptions, userOptions); + if ( + options.nativeModulesPath !== undefined + && !path.isAbsolute(options.nativeModulesPath) + ) { + throw new Error( + 'options.nativeModulesPath must be an absolute path.', + ); + } + api.modifyRsbuildConfig(config => { if (options.polyfill === true) { config.source = { @@ -62,6 +86,30 @@ export function pluginWebPlatform( }; } }); + + api.modifyRspackConfig(rspackConfig => { + console.log(path.resolve( + __dirname, + './loaders/native-modules.js', + )); + rspackConfig.module = { + ...rspackConfig.module, + rules: [ + ...(rspackConfig.module?.rules ?? []), + { + test: + /backgroundThread\/background-apis\/createNativeModules\.js$/, + loader: path.resolve( + __dirname, + './loaders/native-modules.js', + ), + options: { + nativeModulesPath: options.nativeModulesPath, + }, + }, + ], + }; + }); }, }; } diff --git a/packages/web-platform/web-rsbuild-plugin/tests/bundle.test.ts b/packages/web-platform/web-rsbuild-plugin/tests/bundle.test.ts new file mode 100644 index 0000000000..25fd61d07e --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/bundle.test.ts @@ -0,0 +1,63 @@ +import { createRsbuild } from '@rsbuild/core'; +import { describe, expect, test, vi } from 'vitest'; +import { pluginWebPlatform } from '../dist/index.js'; +import path from 'path'; +import type { Stats, NormalModule } from '@rspack/core'; + +describe('Bundle Build', () => { + test('native-modules bundle', async () => { + const rsbuild = await createRsbuild({ + rsbuildConfig: { + source: { + entry: { + main: path.resolve(__dirname, './fixtures/index.ts'), + }, + }, + output: { + distPath: { + root: path.resolve(__dirname, './dist/native-modules-bundle'), + }, + }, + plugins: [ + pluginWebPlatform({ + nativeModulesPath: path.resolve( + __dirname, + './fixtures/index.native-modules.ts', + ), + }), + ], + performance: { + chunkSplit: { + strategy: 'all-in-one', + }, + }, + }, + }); + + let asyncChunkImportCount = 0; + let syncChunkImportCount = 0; + await rsbuild.initConfigs(); + const buildInfo = await rsbuild.build(); + for ( + const i of (buildInfo.stats as Stats).compilation.chunks.values() || [] + ) { + const modules = (buildInfo.stats as Stats).compilation.chunkGraph + .getChunkModules(i) as NormalModule[]; + + for (const m of modules) { + if ( + m.type === 'javascript/auto' + && m.userRequest.includes('tests/fixtures/index.native-modules.ts') + ) { + if (!i.isOnlyInitial()) { + asyncChunkImportCount++; + } else { + syncChunkImportCount++; + } + } + } + } + expect(asyncChunkImportCount).toBe(1); + expect(syncChunkImportCount).toBe(0); + }); +}); diff --git a/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.native-modules.ts b/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.native-modules.ts new file mode 100644 index 0000000000..695a25415d --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.native-modules.ts @@ -0,0 +1,9 @@ +export default { + CustomModule: function(NativeModules, NativeModulesCall) { + return { + async test(data, callback) { + console.log('CustomModule', NativeModules, NativeModulesCall); + }, + }; + }, +}; diff --git a/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.ts b/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.ts new file mode 100644 index 0000000000..e9a912b823 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/fixtures/index.ts @@ -0,0 +1,9 @@ +import '@lynx-js/web-core'; +import '@lynx-js/web-core/index.css'; +import '@lynx-js/web-elements/all'; +import '@lynx-js/web-elements/index.css'; +document.body.innerHTML = ` + +`; diff --git a/packages/web-platform/web-rsbuild-plugin/tests/tsconfig.json b/packages/web-platform/web-rsbuild-plugin/tests/tsconfig.json new file mode 100644 index 0000000000..48610a17ff --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.json", +} diff --git a/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeModules.ts b/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeModules.ts index fdf99cf153..1922ba42d2 100644 --- a/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeModules.ts +++ b/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeModules.ts @@ -2,6 +2,7 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +/* LYNX_NATIVE_MODULES_IMPORT */ import { nativeModulesCallEndpoint, switchExposureServiceEndpoint, @@ -53,6 +54,7 @@ export async function createNativeModules( ) ), ); + /* LYNX_NATIVE_MODULES_ADD */ return Object.assign(nativeModules, { bridge: bridgeModule, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9e58f6875..01e597a3a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -728,16 +728,26 @@ importers: version: 1.1.0 packages/web-platform/web-rsbuild-plugin: + dependencies: + loader-utils: + specifier: ^3.3.1 + version: 3.3.1 devDependencies: - '@microsoft/api-extractor': - specifier: 'catalog:' - version: 7.52.5(@types/node@22.15.2) + '@lynx-js/web-core': + specifier: workspace:* + version: link:../web-core + '@lynx-js/web-elements': + specifier: workspace:* + version: link:../web-elements '@rsbuild/core': specifier: catalog:rsbuild version: 1.3.14 - '@rslib/core': - specifier: ^0.6.7 - version: 0.6.7(@microsoft/api-extractor@7.52.5(@types/node@22.15.2))(typescript@5.8.3) + '@types/loader-utils': + specifier: ^2.0.6 + version: 2.0.6 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -3286,6 +3296,9 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/loader-utils@2.0.6': + resolution: {integrity: sha512-cgu0Xefgq9O5FjFR78jgI6X31aPjDWCaJ6LCfRtlj6BtyVVWiXagysSYlPACwGKAzRwsFLjKXcj4iGfcVt6cLw==} + '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} @@ -3348,21 +3361,39 @@ packages: '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + '@types/source-list-map@0.1.6': + resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==} + '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/tapable@1.0.12': + resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==} + '@types/tapable@2.2.7': resolution: {integrity: sha512-D6QzACV9vNX3r8HQQNTOnpG+Bv1rko+yEA82wKs3O9CQ5+XW7HI7TED17/UE7+5dIxyxZIWTxKbsBeF6uKFCwA==} '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/uglify-js@3.17.5': + resolution: {integrity: sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/webpack-sources@3.2.3': + resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==} + + '@types/webpack@4.41.40': + resolution: {integrity: sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==} + + '@types/webpack@5.28.5': + resolution: {integrity: sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -6218,6 +6249,10 @@ packages: resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} engines: {node: '>=8.9.0'} + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -11463,6 +11498,11 @@ snapshots: dependencies: '@types/node': 22.15.2 + '@types/loader-utils@2.0.6': + dependencies: + '@types/node': 22.15.2 + '@types/webpack': 4.41.40 + '@types/mdast@3.0.15': dependencies: '@types/unist': 2.0.11 @@ -11527,18 +11567,52 @@ snapshots: dependencies: '@types/node': 22.15.2 + '@types/source-list-map@0.1.6': {} + '@types/stack-utils@2.0.3': {} + '@types/tapable@1.0.12': {} + '@types/tapable@2.2.7': dependencies: tapable: 2.2.1 '@types/tough-cookie@4.0.5': {} + '@types/uglify-js@3.17.5': + dependencies: + source-map: 0.6.1 + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} + '@types/webpack-sources@3.2.3': + dependencies: + '@types/node': 22.15.2 + '@types/source-list-map': 0.1.6 + source-map: 0.7.4 + + '@types/webpack@4.41.40': + dependencies: + '@types/node': 22.15.2 + '@types/tapable': 1.0.12 + '@types/uglify-js': 3.17.5 + '@types/webpack-sources': 3.2.3 + anymatch: 3.1.3 + source-map: 0.6.1 + + '@types/webpack@5.28.5': + dependencies: + '@types/node': 22.15.2 + tapable: 2.2.1 + webpack: 5.99.6 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + - webpack-cli + '@types/ws@8.18.1': dependencies: '@types/node': 22.15.2 @@ -14888,6 +14962,8 @@ snapshots: emojis-list: 3.0.0 json5: 2.2.3 + loader-utils@3.3.1: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0