diff --git a/.changeset/modern-peaches-marry.md b/.changeset/modern-peaches-marry.md new file mode 100644 index 0000000000..1994b45796 --- /dev/null +++ b/.changeset/modern-peaches-marry.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/web-platform-rsbuild-plugin": minor +--- + +feat: Provides Rsbuild plugin for Web projects in Lynx Web Platform, currently supports polyfill about lynx. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 78f7a0f6b5..e3dc9d2c12 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -236,6 +236,27 @@ jobs: export ALL_ON_UI=true pnpm --filter @lynx-js/web-tests run test --reporter='github,dot,junit,html' pnpm --filter @lynx-js/web-tests run coverage:ci + test-web-platform: + needs: build + uses: ./.github/workflows/workflow-test.yml + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + runs-on: lynx-ubuntu-24.04-medium + run: > + pnpm + --filter @lynx-js/web-platform-rsbuild-plugin + run test + --reporter=github-actions + --reporter=dot + --reporter=junit + --outputFile=test-report.junit.xml + --coverage.reporter='json' + --coverage.reporter='text' + --test-timeout=50000 + --no-cache + --logHeapUsage + --silent lighthouse: needs: build uses: ./.github/workflows/workflow-test.yml @@ -286,6 +307,7 @@ jobs: - code-style-check - playwright-linux - playwright-linux-all-on-ui + - test-web-platform - test-plugins - test-publish - test-react diff --git a/.gitignore b/.gitignore index 6b2ffb578a..4056f6442c 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,7 @@ target/ .pnpm-store # lighthouse-ci -.lighthouseci \ No newline at end of file +.lighthouseci + +# rslib +.rslib diff --git a/packages/web-platform/web-explorer/package.json b/packages/web-platform/web-explorer/package.json index 2b7f49d1dd..893b92caa7 100644 --- a/packages/web-platform/web-explorer/package.json +++ b/packages/web-platform/web-explorer/package.json @@ -20,7 +20,8 @@ ], "scripts": { "build": "rsbuild build", - "dev": "rsbuild dev" + "dev": "rsbuild dev", + "build:rsdoctor": "RSDOCTOR=true rsbuild build" }, "dependencies": { "qr-scanner": "^1.4.2" @@ -30,7 +31,9 @@ "@lynx-js/lynx-core": "0.1.2", "@lynx-js/web-core": "workspace:*", "@lynx-js/web-elements": "workspace:*", + "@lynx-js/web-platform-rsbuild-plugin": "workspace:*", "@rsbuild/core": "catalog:rsbuild", + "@rsdoctor/rspack-plugin": "1.0.2", "tslib": "^2.8.1" } } diff --git a/packages/web-platform/web-explorer/rsbuild.config.ts b/packages/web-platform/web-explorer/rsbuild.config.ts index cf391fe5ad..d1949b6d62 100644 --- a/packages/web-platform/web-explorer/rsbuild.config.ts +++ b/packages/web-platform/web-explorer/rsbuild.config.ts @@ -1,5 +1,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'; const codecovEnabled = !!process.env.CI; console.info('codecov enabled:', codecovEnabled); export default defineConfig({ @@ -7,6 +9,7 @@ export default defineConfig({ entry: { index: './index.ts', }, + include: [/web/], }, output: { target: 'web', @@ -14,6 +17,7 @@ export default defineConfig({ root: 'dist', }, filenameHash: false, + overrideBrowserslist: ['Chrome > 118'], }, dev: { writeToDisk: true, @@ -37,6 +41,12 @@ export default defineConfig({ sha: process.env.GITHUB_SHA, }, }), + process.env.RSDOCTOR === 'true' + && new RsdoctorRspackPlugin({ + supports: { + generateTileGraph: true, + }, + }), ], }, }, @@ -46,4 +56,5 @@ export default defineConfig({ }, profile: true, }, + plugins: [pluginWebPlatform({ polyfill: false })], }); diff --git a/packages/web-platform/web-rsbuild-plugin/README.md b/packages/web-platform/web-rsbuild-plugin/README.md new file mode 100644 index 0000000000..ee619412c2 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/README.md @@ -0,0 +1,14 @@ +# @lynx-js/web-platform-rsbuild-plugin + +Lynx3 Web Platform rsbuild plugin + +## Usage + +```javascript +import { pluginWebPlatform } from '@lynx-js/web-platform-rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + plugins: [pluginWebPlatform()], +}); +``` diff --git a/packages/web-platform/web-rsbuild-plugin/api-extractor.json b/packages/web-platform/web-rsbuild-plugin/api-extractor.json new file mode 100644 index 0000000000..65b0c69ca6 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/api-extractor.json @@ -0,0 +1,6 @@ +/** + * Config file for API Extractor. For more info, please visit: https://api-extractor.com + */ +{ + "extends": "../../../api-extractor.json", +} diff --git a/packages/web-platform/web-rsbuild-plugin/package.json b/packages/web-platform/web-rsbuild-plugin/package.json new file mode 100644 index 0000000000..318b30b659 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/package.json @@ -0,0 +1,40 @@ +{ + "name": "@lynx-js/web-platform-rsbuild-plugin", + "version": "0.0.0", + "private": false, + "description": "A rsbuild plugin for Web projects in Lynx Web Platform", + "keywords": [ + "rsbuild", + "Lynx", + "Web Platform" + ], + "repository": { + "type": "git", + "url": "https://github.com/lynx-family/lynx-stack.git", + "directory": "packages/web-platform/web-rsbuild-plugin" + }, + "license": "Apache-2.0", + "type": "module", + "main": "dist/index.js", + "typings": "dist/index.d.ts", + "files": [ + "dist", + "CHANGELOG.md", + "README.md" + ], + "scripts": { + "build": "rslib build", + "dev": "rslib build --watch", + "test": "vitest" + }, + "devDependencies": { + "@microsoft/api-extractor": "catalog:", + "@rsbuild/core": "catalog:rsbuild", + "@rslib/core": "^0.6.7", + "typescript": "^5.8.3", + "vitest": "^3.1.2" + }, + "peerDependencies": { + "@rsbuild/core": "*" + } +} diff --git a/packages/web-platform/web-rsbuild-plugin/rslib.config.ts b/packages/web-platform/web-rsbuild-plugin/rslib.config.ts new file mode 100644 index 0000000000..92a6b11025 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/rslib.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { format: 'esm', syntax: 'es2022', dts: { bundle: true } }, + ], +}); diff --git a/packages/web-platform/web-rsbuild-plugin/src/index.ts b/packages/web-platform/web-rsbuild-plugin/src/index.ts new file mode 100644 index 0000000000..9fbecff720 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/src/index.ts @@ -0,0 +1,11 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. + +/** + * @packageDocumentation + * + * A rsbuild plugin that integrates with Web Platform. + */ + +export { pluginWebPlatform } from './pluginWebPlatform.js'; diff --git a/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts b/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts new file mode 100644 index 0000000000..3aab4ad959 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/src/pluginWebPlatform.ts @@ -0,0 +1,67 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. + +import type { RsbuildPlugin } from '@rsbuild/core'; + +/** + * The options for {@link pluginWebPlatform}. + * + * @public + */ +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 + * + * @default true + */ + polyfill?: boolean; +} + +/** + * Create a rsbuild plugin for Lynx Web Platform. + * + * @example + * ```ts + * // rsbuild.config.ts + * import { pluginWebPlatform } from '@lynx-js/web-platform-rsbuild-plugin' + * import { defineConfig } from '@rsbuild/core'; + * + * export default defineConfig({ + * plugins: [pluginWebPlatform()], + * }) + * ``` + * + * @public + */ +export function pluginWebPlatform( + userOptions?: PluginWebPlatformOptions, +): RsbuildPlugin { + return { + name: 'lynx:web-platform', + async setup(api) { + const defaultPluginOptions = { + polyfill: true, + }; + const options = Object.assign({}, defaultPluginOptions, userOptions); + + api.modifyRsbuildConfig(config => { + if (options.polyfill === true) { + config.source = { + ...config.source, + include: [ + ...(config.source?.include ?? []), + /node_modules[\\/]@lynx-js[\\/]/, + ], + }; + config.output = { + ...config.output, + polyfill: 'usage', + }; + } + }); + }, + }; +} diff --git a/packages/web-platform/web-rsbuild-plugin/tests/__snapshots__/config.test.ts.snap b/packages/web-platform/web-rsbuild-plugin/tests/__snapshots__/config.test.ts.snap new file mode 100644 index 0000000000..0079db6849 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/__snapshots__/config.test.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Config > basic config 1`] = ` +[ + /node_modules\\[\\\\\\\\/\\]@lynx-js\\[\\\\\\\\/\\]/, +] +`; diff --git a/packages/web-platform/web-rsbuild-plugin/tests/config.test.ts b/packages/web-platform/web-rsbuild-plugin/tests/config.test.ts new file mode 100644 index 0000000000..ced15c0de1 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tests/config.test.ts @@ -0,0 +1,21 @@ +import { createRsbuild } from '@rsbuild/core'; +import { describe, expect, test, vi } from 'vitest'; +import { pluginWebPlatform } from '../src/index.js'; + +describe('Config', () => { + test('basic config', async () => { + const rsbuild = await createRsbuild({ + rsbuildConfig: { + plugins: [ + pluginWebPlatform(), + ], + }, + }); + + await rsbuild.initConfigs(); + const rsbuildConfig = rsbuild.getRsbuildConfig(); + + expect(rsbuildConfig.source?.include).toMatchSnapshot(); + expect(rsbuildConfig.output?.polyfill).toBe('usage'); + }); +}); diff --git a/packages/web-platform/web-rsbuild-plugin/tsconfig.json b/packages/web-platform/web-rsbuild-plugin/tsconfig.json new file mode 100644 index 0000000000..cffb9f9080 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "composite": true, + "rootDir": "./src", + "outDir": "./dist", + "lib": ["ESNext"], + "noUnusedParameters": false, + "noImplicitReturns": false, + }, + "include": ["src"], +} diff --git a/packages/web-platform/web-rsbuild-plugin/turbo.json b/packages/web-platform/web-rsbuild-plugin/turbo.json new file mode 100644 index 0000000000..c73c3199b8 --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/turbo.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": [ + "//" + ], + "tasks": { + "build": { + "dependsOn": [ + "^build" + ], + "inputs": [ + "src" + ], + "outputs": [ + "dist" + ] + } + } +} diff --git a/packages/web-platform/web-rsbuild-plugin/vitest.config.ts b/packages/web-platform/web-rsbuild-plugin/vitest.config.ts new file mode 100644 index 0000000000..0658fa4d5c --- /dev/null +++ b/packages/web-platform/web-rsbuild-plugin/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineProject } from 'vitest/config'; +import type { UserWorkspaceConfig } from 'vitest/config'; + +const config: UserWorkspaceConfig = defineProject({ + test: { + name: 'web-platform', + expect: { + poll: { + timeout: 3000, + }, + }, + }, +}); + +export default config; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a98551b5ba..f8a02320ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -699,9 +699,15 @@ importers: '@lynx-js/web-elements': specifier: workspace:* version: link:../web-elements + '@lynx-js/web-platform-rsbuild-plugin': + specifier: workspace:* + version: link:../web-rsbuild-plugin '@rsbuild/core': specifier: catalog:rsbuild version: 1.3.11 + '@rsdoctor/rspack-plugin': + specifier: 1.0.2 + version: 1.0.2(@rsbuild/core@1.3.11)(@rspack/core@1.3.6(@swc/helpers@0.5.17))(webpack@5.99.6) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -721,6 +727,24 @@ importers: specifier: ^1.1.0 version: 1.1.0 + packages/web-platform/web-rsbuild-plugin: + devDependencies: + '@microsoft/api-extractor': + specifier: 'catalog:' + version: 7.52.5(@types/node@22.15.2) + '@rsbuild/core': + specifier: catalog:rsbuild + version: 1.3.11 + '@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) + typescript: + specifier: ^5.8.3 + version: 5.8.3 + vitest: + specifier: ^3.1.2 + version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(@vitest/ui@3.1.2)(jsdom@26.1.0)(sass-embedded@1.86.0)(terser@5.31.6) + packages/web-platform/web-style-transformer: {} packages/web-platform/web-tests: