├── .changeset
└── config.json
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── 1-bug-report.en-US.yml
│ ├── 2-feature-request.en-US.yml
│ └── config.yml
├── PULL_REQUEST_TEMPLATE.md
├── pr-labeler.yml
├── release.yml
├── renovate.json5
└── workflows
│ ├── lint.yml
│ ├── pr-label.yaml
│ ├── release.yml
│ ├── test-ubuntu.yml
│ └── test-windows.yml
├── .gitignore
├── .husky
├── post-checkout
└── pre-commit
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .prettierrc
├── .vscode
├── extensions.json
└── settings.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── README.zh-CN.md
├── SECURITY.md
├── biome.json
├── cspell.config.cjs
├── e2e
├── README.md
├── cases
│ ├── doctor-rsbuild
│ │ ├── fixtures
│ │ │ ├── a.js
│ │ │ ├── b.js
│ │ │ ├── loaders
│ │ │ │ ├── comment.js
│ │ │ │ ├── serialize-query-to-comment.js
│ │ │ │ └── serialize-resource-query-to-comment.js
│ │ │ └── port.js
│ │ ├── loaders
│ │ │ └── loader.test.ts
│ │ └── test-utils.ts
│ ├── doctor-rspack
│ │ ├── banner-plugin.test.ts
│ │ ├── brief.test.ts
│ │ ├── bundle-diff.test.ts
│ │ ├── fixtures
│ │ │ ├── a.js
│ │ │ ├── b.js
│ │ │ ├── c.js
│ │ │ ├── index.css
│ │ │ ├── index.ts
│ │ │ ├── loaders
│ │ │ │ ├── comment.js
│ │ │ │ ├── esm-serialize-query-to-comment.mjs
│ │ │ │ ├── esm
│ │ │ │ │ ├── esm-serialize-query-to-comment.js
│ │ │ │ │ └── package.json
│ │ │ │ └── serialize-query-to-comment.js
│ │ │ ├── port.js
│ │ │ └── rspack-banner-plugin.js
│ │ ├── layer-plugin.test.ts
│ │ ├── linter-rule-render.test.ts
│ │ ├── plugin.test.ts
│ │ ├── tag-plugin-without-banner.test.ts
│ │ └── test-utils.ts
│ └── doctor-webpack
│ │ ├── experiments.test.ts
│ │ ├── fixtures
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── loaders
│ │ │ ├── comment.js
│ │ │ ├── serialize-query-to-comment.js
│ │ │ └── serialize-resource-query-to-comment.js
│ │ └── port.js
│ │ ├── fixtures2
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── index.less
│ │ ├── loaders
│ │ │ ├── comment.js
│ │ │ ├── serialize-query-to-comment.js
│ │ │ └── serialize-resource-query-to-comment.js
│ │ └── port.js
│ │ ├── loaders
│ │ ├── loader.test.ts
│ │ ├── proxy.test.ts
│ │ ├── query.test.ts
│ │ └── resourceQuery.test.ts
│ │ ├── plugins
│ │ ├── loader-mini-css-extract.test.ts
│ │ ├── loader.test.ts
│ │ ├── multi-plugin-brief.test.ts
│ │ ├── plugin.test.ts
│ │ ├── rules.test.ts
│ │ └── treeShaking.test.ts
│ │ ├── summary.test.ts
│ │ └── test-utils.ts
├── fixtures
│ ├── manifests
│ │ └── empty-manifest.json
│ └── rsdoctor
│ │ ├── chunkGraph
│ │ └── 0
│ │ ├── configs
│ │ └── 0
│ │ ├── envinfo
│ │ └── 0
│ │ ├── errors
│ │ └── 0
│ │ ├── loader
│ │ └── 0
│ │ ├── manifest.json
│ │ ├── moduleCodeMap
│ │ └── 0
│ │ ├── moduleGraph
│ │ └── 0
│ │ ├── otherReports
│ │ └── 0
│ │ ├── packageGraph
│ │ └── 0
│ │ ├── plugin
│ │ └── 0
│ │ ├── resolver
│ │ └── 0
│ │ └── summary
│ │ └── 0
├── package.json
├── playwright.config.ts
├── test-kit
│ ├── index.ts
│ ├── launch.ts
│ └── path.ts
└── tsconfig.json
├── examples
├── modern-minimal
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── myapp
│ │ │ └── routes
│ │ │ │ ├── index.css
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ ├── myapp2
│ │ │ └── routes
│ │ │ │ ├── index.css
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ └── utils
│ │ │ └── utils.ts
│ └── tsconfig.json
├── multiple-minimal
│ ├── build.ts
│ ├── package.json
│ ├── src
│ │ ├── app.tsx
│ │ ├── declaration.d.ts
│ │ ├── index.module.less
│ │ └── index.ts
│ └── tsconfig.json
├── rsbuild-minimal
│ ├── package.json
│ ├── rsbuild.config.ts
│ ├── rules
│ │ └── assets-count-limit.ts
│ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── button.css
│ │ ├── env.d.ts
│ │ ├── index.tsx
│ │ ├── semver.ts
│ │ └── semver7.ts
│ └── tsconfig.json
├── rspack-banner-minimal
│ ├── index.html
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ └── manifest.json
│ ├── rspack.config.js
│ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── Footer
│ │ │ ├── index.tsx
│ │ │ └── style
│ │ │ │ └── index.module.less
│ │ ├── app1.tsx
│ │ ├── declaration.d.ts
│ │ ├── index.css
│ │ ├── index.module.less
│ │ ├── index.ts
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── reportWebVitals.ts
│ │ ├── setupTests.ts
│ │ └── typings
│ │ │ └── assetsDefinition.d.ts
│ └── tsconfig.json
├── rspack-layers-minimal
│ ├── build.ts
│ ├── index.html
│ ├── legacy-loader.js
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── rspack.config.js
│ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── Footer
│ │ │ ├── index.tsx
│ │ │ └── style
│ │ │ │ └── index.module.less
│ │ ├── app1.tsx
│ │ ├── declaration.d.ts
│ │ ├── index.css
│ │ ├── index.module.less
│ │ ├── index.ts
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── reportWebVitals.ts
│ │ ├── setupTests.ts
│ │ └── typings
│ │ │ └── assetsDefinition.d.ts
│ └── tsconfig.json
├── rspack-minimal
│ ├── build.ts
│ ├── index.html
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── rspack.config.js
│ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── Footer
│ │ │ ├── index.tsx
│ │ │ └── style
│ │ │ │ └── index.module.less
│ │ ├── app1.tsx
│ │ ├── declaration.d.ts
│ │ ├── index.css
│ │ ├── index.module.less
│ │ ├── index.ts
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── reportWebVitals.ts
│ │ ├── setupTests.ts
│ │ └── typings
│ │ │ └── assetsDefinition.d.ts
│ └── tsconfig.json
├── rspress-minimal
│ ├── .gitignore
│ ├── README.md
│ ├── docs
│ │ ├── _meta.json
│ │ ├── guide
│ │ │ ├── _meta.json
│ │ │ └── index.md
│ │ ├── hello.md
│ │ ├── index.md
│ │ └── public
│ │ │ ├── rspress-dark-logo.png
│ │ │ ├── rspress-icon.png
│ │ │ └── rspress-light-logo.png
│ ├── package.json
│ ├── rspress.config.ts
│ └── tsconfig.json
└── webpack-minimal
│ ├── package.json
│ ├── src
│ ├── html.ts
│ ├── images
│ │ └── file.svg
│ ├── index.ts
│ ├── style.css
│ ├── types.ts
│ ├── typings
│ │ └── assetsDefinition.d.ts
│ ├── utils.ts
│ ├── utils
│ │ ├── index.ts
│ │ └── utils.js
│ ├── utils2.ts
│ ├── utils3.ts
│ ├── utils4.ts
│ ├── utils5.ts
│ └── utils6.ts
│ ├── tsconfig.json
│ └── webpack.config.ts
├── nx.json
├── package.json
├── packages
├── ai
│ ├── .env.sample
│ ├── .gitignore
│ ├── README.md
│ ├── README.zh-CN.md
│ ├── bin
│ │ └── rsdoctor-mcp
│ ├── package.json
│ ├── resources
│ │ ├── rsdoctor-config.md
│ │ └── rsdoctor-context.md
│ ├── rslib.config.ts
│ ├── src
│ │ ├── index.ts
│ │ ├── prompt
│ │ │ ├── assets.ts
│ │ │ ├── bundle.ts
│ │ │ ├── code.ts
│ │ │ ├── deps.ts
│ │ │ ├── functions.ts
│ │ │ ├── index.ts
│ │ │ └── schema.ts
│ │ ├── schema.ts
│ │ ├── server
│ │ │ ├── index.ts
│ │ │ ├── prompt.ts
│ │ │ ├── resource.ts
│ │ │ ├── server.ts
│ │ │ ├── socket.ts
│ │ │ └── tools.ts
│ │ ├── types
│ │ │ └── index.d.ts
│ │ └── utils
│ │ │ ├── chunks.ts
│ │ │ ├── env.ts
│ │ │ └── index.ts
│ ├── tests
│ │ ├── chunks.test.ts
│ │ ├── code.test.ts
│ │ ├── fixtures
│ │ │ ├── chunks_client.json
│ │ │ ├── deps.json
│ │ │ ├── group.json
│ │ │ ├── result.json
│ │ │ └── test.cjs
│ │ ├── index.test.ts
│ │ ├── model
│ │ │ ├── coze.ts
│ │ │ ├── index.ts
│ │ │ └── openai.ts
│ │ ├── socket.test.ts
│ │ ├── tsconfig.json
│ │ └── utils.test.ts
│ ├── tsconfig.build.json
│ ├── tsconfig.json
│ └── vitest.config.ts
├── cli
│ ├── LICENSE
│ ├── README.md
│ ├── bin
│ │ └── rsdoctor
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── commands
│ │ │ ├── analyze.ts
│ │ │ ├── bundle-diff.ts
│ │ │ └── index.ts
│ │ ├── constants.ts
│ │ ├── index.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ └── tsconfig.json
├── client
│ ├── LICENSE
│ ├── README.md
│ ├── config
│ │ └── constants.ts
│ ├── package.json
│ ├── rsbuild.config.ts
│ ├── src
│ │ ├── App.tsx
│ │ ├── common
│ │ │ ├── imgs
│ │ │ │ └── connection-point.svg
│ │ │ └── styles
│ │ │ │ ├── base.scss
│ │ │ │ └── theme.scss
│ │ ├── index.tsx
│ │ ├── router.tsx
│ │ └── typings
│ │ │ └── assetsDefinition.d.ts
│ └── tsconfig.json
├── components
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── common
│ │ │ ├── imgs
│ │ │ │ ├── connection-point.svg
│ │ │ │ ├── rsdoctor-navbar.png
│ │ │ │ └── webpack.svg
│ │ │ └── svg
│ │ │ │ ├── bundle-size.svg
│ │ │ │ ├── error.svg
│ │ │ │ ├── file-css.svg
│ │ │ │ ├── file-html.svg
│ │ │ │ ├── file-image.svg
│ │ │ │ ├── file-js.svg
│ │ │ │ ├── file-unknown.svg
│ │ │ │ ├── file.svg
│ │ │ │ ├── files
│ │ │ │ ├── css.svg
│ │ │ │ ├── html.svg
│ │ │ │ ├── image.svg
│ │ │ │ ├── js.svg
│ │ │ │ └── unkown-file.svg
│ │ │ │ ├── loader
│ │ │ │ ├── input.svg
│ │ │ │ ├── output.svg
│ │ │ │ └── step.svg
│ │ │ │ ├── navbar
│ │ │ │ ├── bundle-size-active.svg
│ │ │ │ ├── bundle-size-inactive.svg
│ │ │ │ ├── compile-analysis-active.svg
│ │ │ │ ├── compile-analysis-inactive.svg
│ │ │ │ ├── overall-active.svg
│ │ │ │ └── overall-inactive.svg
│ │ │ │ ├── output.svg
│ │ │ │ ├── source-size.svg
│ │ │ │ ├── source.svg
│ │ │ │ ├── total-size.svg
│ │ │ │ └── version.svg
│ │ ├── components
│ │ │ ├── Alert
│ │ │ │ ├── change.tsx
│ │ │ │ ├── ecma-version-check.module.scss
│ │ │ │ ├── ecma-version-check.tsx
│ │ │ │ ├── file-relation.tsx
│ │ │ │ ├── index.scss
│ │ │ │ ├── package-relation.module.scss
│ │ │ │ ├── package-relation.tsx
│ │ │ │ ├── types.ts
│ │ │ │ └── view.tsx
│ │ │ ├── Alerts
│ │ │ │ ├── bundle-alert.module.scss
│ │ │ │ ├── bundle-alert.tsx
│ │ │ │ ├── bundle.tsx
│ │ │ │ ├── collapse-cross-chunks.tsx
│ │ │ │ ├── collapse.module.scss
│ │ │ │ ├── collapse.tsx
│ │ │ │ ├── compile.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── list.module.scss
│ │ │ │ ├── list.tsx
│ │ │ │ ├── overlay.module.scss
│ │ │ │ └── overlay.tsx
│ │ │ ├── Badge
│ │ │ │ └── index.tsx
│ │ │ ├── Card
│ │ │ │ ├── diff.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── size.module.scss
│ │ │ │ ├── size.tsx
│ │ │ │ └── statistic.tsx
│ │ │ ├── Charts
│ │ │ │ ├── TimelineCharts
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── bootstrap.tsx
│ │ │ │ ├── common.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ ├── done.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── loader.scss
│ │ │ │ ├── loader.tsx
│ │ │ │ ├── minify.tsx
│ │ │ │ ├── tooltips.scss
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ │ ├── Configuration
│ │ │ │ ├── builder.module.scss
│ │ │ │ ├── builder.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── FileTree
│ │ │ │ ├── css.svg
│ │ │ │ ├── html.svg
│ │ │ │ ├── image.svg
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ ├── js.svg
│ │ │ │ └── unkown-file.svg
│ │ │ ├── Form
│ │ │ │ └── keyword.tsx
│ │ │ ├── Keyword
│ │ │ │ ├── index.tsx
│ │ │ │ └── style.module.scss
│ │ │ ├── Layout
│ │ │ │ ├── builder-select.tsx
│ │ │ │ ├── bundle-size-icon.svg
│ │ │ │ ├── compile-icon.svg
│ │ │ │ ├── constants.ts
│ │ │ │ ├── header.scss
│ │ │ │ ├── header.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── menus.tsx
│ │ │ │ ├── overall-icon.svg
│ │ │ │ └── progress.tsx
│ │ │ ├── Loader
│ │ │ │ ├── Analysis
│ │ │ │ │ ├── files.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── input.svg
│ │ │ │ │ ├── output.svg
│ │ │ │ │ └── style.module.scss
│ │ │ │ ├── executions.tsx
│ │ │ │ └── step.svg
│ │ │ ├── Manifest
│ │ │ │ ├── api.tsx
│ │ │ │ ├── data.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Opener
│ │ │ │ ├── code.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── vscode.tsx
│ │ │ ├── Overall
│ │ │ │ ├── DataSummary.module.scss
│ │ │ │ ├── DataSummary.tsx
│ │ │ │ ├── bundle.module.scss
│ │ │ │ ├── bundle.tsx
│ │ │ │ ├── card.module.scss
│ │ │ │ ├── compile.module.scss
│ │ │ │ ├── compile.tsx
│ │ │ │ ├── help-center.module.scss
│ │ │ │ ├── help-center.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── list.module.scss
│ │ │ │ ├── overview.module.scss
│ │ │ │ ├── overview.tsx
│ │ │ │ ├── project.module.scss
│ │ │ │ └── project.tsx
│ │ │ ├── Plugins
│ │ │ │ └── webpack.tsx
│ │ │ ├── Resolver
│ │ │ │ └── analysis.tsx
│ │ │ ├── Select
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Status
│ │ │ │ ├── failed.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── TextDrawer
│ │ │ │ ├── duplicate.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Title
│ │ │ │ └── index.tsx
│ │ │ ├── base
│ │ │ │ ├── CodeViewer
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── interface.ts
│ │ │ │ │ ├── useCodeDrawer.tsx
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── DiffViewer
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── interface.ts
│ │ │ │ │ ├── useDiffDrawer.tsx
│ │ │ │ │ └── utils.ts
│ │ │ │ └── index.ts
│ │ │ └── index.ts
│ │ ├── config.tsx
│ │ ├── constants.tsx
│ │ ├── index.ts
│ │ ├── modern-app-env.d.ts
│ │ ├── pages
│ │ │ ├── BundleSize
│ │ │ │ ├── components
│ │ │ │ │ ├── asset.tsx
│ │ │ │ │ ├── card.module.scss
│ │ │ │ │ ├── cards.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ ├── index.scss
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── search-modal.tsx
│ │ │ │ ├── config.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ └── index.tsx
│ │ │ ├── ModuleAnalyze
│ │ │ │ ├── chunks.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── fileTreeCom.scss
│ │ │ │ │ └── fileTreeCom.tsx
│ │ │ │ ├── constants.ts
│ │ │ │ ├── dependency.tsx
│ │ │ │ ├── fileTree.tsx
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── utils
│ │ │ │ │ ├── hooks.tsx
│ │ │ │ │ └── index.ts
│ │ │ ├── ModuleResolve
│ │ │ │ ├── constants.ts
│ │ │ │ └── index.tsx
│ │ │ ├── Overall
│ │ │ │ ├── constants.ts
│ │ │ │ ├── index.module.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── responsiveLayout.tsx
│ │ │ ├── Resources
│ │ │ │ ├── BundleDiff
│ │ │ │ │ ├── DiffContainer
│ │ │ │ │ │ ├── assets.tsx
│ │ │ │ │ │ ├── cards.tsx
│ │ │ │ │ │ ├── changes.tsx
│ │ │ │ │ │ ├── constants.ts
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── modules.tsx
│ │ │ │ │ │ ├── overview.tsx
│ │ │ │ │ │ ├── packages.tsx
│ │ │ │ │ │ ├── row.tsx
│ │ │ │ │ │ ├── types.ts
│ │ │ │ │ │ └── utils.tsx
│ │ │ │ │ ├── DiffServerAPIProvider
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── RuleIndex
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ └── index.tsx
│ │ │ ├── TreeShaking
│ │ │ │ ├── constants.ts
│ │ │ │ ├── editor.tsx
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ ├── open-tag.ts
│ │ │ │ ├── range.ts
│ │ │ │ ├── space.tsx
│ │ │ │ ├── table.tsx
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.tsx
│ │ │ ├── WebpackLoaders
│ │ │ │ ├── Analysis
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Overall
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ └── index.tsx
│ │ │ │ └── constants.ts
│ │ │ ├── WebpackPlugins
│ │ │ │ ├── constants.ts
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ └── index.ts
│ │ ├── typings
│ │ │ ├── assetsDefinition.d.ts
│ │ │ └── index.d.ts
│ │ └── utils
│ │ │ ├── data
│ │ │ ├── base.ts
│ │ │ ├── brief.ts
│ │ │ ├── index.ts
│ │ │ ├── local.ts
│ │ │ └── remote.ts
│ │ │ ├── file.tsx
│ │ │ ├── hooks.ts
│ │ │ ├── i18n
│ │ │ ├── cn.ts
│ │ │ ├── en.ts
│ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── loader.ts
│ │ │ ├── locale.ts
│ │ │ ├── manifest.tsx
│ │ │ ├── request.ts
│ │ │ ├── routes.ts
│ │ │ ├── size.ts
│ │ │ ├── socket.ts
│ │ │ ├── storage.tsx
│ │ │ ├── string.ts
│ │ │ ├── time.ts
│ │ │ ├── url.ts
│ │ │ └── worker
│ │ │ ├── index.ts
│ │ │ ├── master.ts
│ │ │ ├── types.ts
│ │ │ ├── utils.ts
│ │ │ └── worker.ts
│ └── tsconfig.json
├── core
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── build-utils
│ │ │ ├── build
│ │ │ │ ├── chunks
│ │ │ │ │ ├── assetsModules.ts
│ │ │ │ │ ├── chunkTransform.ts
│ │ │ │ │ ├── generateTileGraph.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── rspack
│ │ │ │ │ │ └── transform.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── loader
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── probeLoader.ts
│ │ │ │ │ └── probeLoaderPlugin.ts
│ │ │ │ ├── module-graph
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── parser.ts
│ │ │ │ │ ├── rspack
│ │ │ │ │ │ └── transform.ts
│ │ │ │ │ ├── transform.ts
│ │ │ │ │ ├── treeShaking.ts
│ │ │ │ │ ├── utils.ts
│ │ │ │ │ └── webpack
│ │ │ │ │ │ └── transform.ts
│ │ │ │ └── utils
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── loader.ts
│ │ │ │ │ ├── parseBundle.ts
│ │ │ │ │ └── plugin.ts
│ │ │ ├── common
│ │ │ │ ├── chunks
│ │ │ │ │ ├── assetsContent.ts
│ │ │ │ │ ├── assetsModules.ts
│ │ │ │ │ ├── chunkTransform.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── module-graph
│ │ │ │ │ ├── compatible.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── transform.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── trans-utils
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transStats.ts
│ │ │ │ └── webpack
│ │ │ │ │ └── compatible.ts
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── inner-plugins
│ │ │ ├── constants.ts
│ │ │ ├── index.ts
│ │ │ ├── loaders
│ │ │ │ └── proxy.ts
│ │ │ ├── plugins
│ │ │ │ ├── base.ts
│ │ │ │ ├── bundle.ts
│ │ │ │ ├── bundleTagPlugin.ts
│ │ │ │ ├── ensureModulesChunkGraph.ts
│ │ │ │ ├── errors.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── loader.ts
│ │ │ │ ├── plugins.ts
│ │ │ │ ├── progress.ts
│ │ │ │ ├── rspack.ts
│ │ │ │ ├── rules.ts
│ │ │ │ └── summary.ts
│ │ │ └── utils
│ │ │ │ ├── circleDetect.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── loader.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ └── sdk.ts
│ │ ├── rules
│ │ │ ├── index.ts
│ │ │ ├── linter.ts
│ │ │ ├── rule.ts
│ │ │ ├── rules
│ │ │ │ ├── cross-chunks-package
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── default-import-check
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── duplicate-package
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── ecma-version-check
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── loader-performance-optimization
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ └── utils.ts
│ │ └── types
│ │ │ ├── chunks.ts
│ │ │ ├── declare.d.ts
│ │ │ ├── index.ts
│ │ │ ├── loader.ts
│ │ │ ├── plugin.ts
│ │ │ ├── rules.ts
│ │ │ └── webpack.ts
│ ├── tests
│ │ ├── build
│ │ │ ├── utils.ts
│ │ │ └── utils
│ │ │ │ ├── bundles
│ │ │ │ ├── validBundleWithArrowFunction.js
│ │ │ │ ├── validBundleWithArrowFunction.modules.json
│ │ │ │ ├── validBundleWithEsNextFeatures.js
│ │ │ │ ├── validBundleWithEsNextFeatures.modules.json
│ │ │ │ ├── validCommonBundleWithModulesAsArray.js
│ │ │ │ ├── validCommonBundleWithModulesAsArray.modules.json
│ │ │ │ ├── validCommonBundleWithModulesAsObject.js
│ │ │ │ └── validCommonBundleWithModulesAsObject.modules.json
│ │ │ │ ├── loader
│ │ │ │ ├── __snapshots__
│ │ │ │ │ ├── changeBuiltinLoader.test.ts.snap
│ │ │ │ │ └── changeBuiltinLoaderVue.test.ts.snap
│ │ │ │ ├── basic.test.ts
│ │ │ │ ├── changeBuiltinLoader.test.ts
│ │ │ │ ├── changeBuiltinLoaderVue.test.ts
│ │ │ │ ├── createLoaderContextTrap.test.ts
│ │ │ │ ├── loadLoaderModule.test.ts
│ │ │ │ └── mapEachRules.test.ts
│ │ │ │ ├── parseBundle.test.ts
│ │ │ │ └── plugin.test.ts
│ │ ├── common
│ │ │ ├── module-graph
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── transform.test.ts.snap
│ │ │ │ └── transform.test.ts
│ │ │ └── utils.ts
│ │ ├── fixtures
│ │ │ ├── assets
│ │ │ │ └── webpack-stats.json
│ │ │ ├── default-export
│ │ │ │ ├── expression
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── utils.js
│ │ │ │ ├── literal
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── utils.js
│ │ │ │ └── variable
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── utils.js
│ │ │ ├── loaders
│ │ │ │ ├── basic-loader-esm.js
│ │ │ │ ├── basic-loader.js
│ │ │ │ ├── pitch-loader-esm.js
│ │ │ │ ├── pitch-loader.js
│ │ │ │ ├── raw-loader-esm.js
│ │ │ │ └── raw-loader.js
│ │ │ └── normal-module-in-multi-concatenation
│ │ │ │ ├── common.js
│ │ │ │ ├── entry1.js
│ │ │ │ └── entry2.js
│ │ ├── plugins
│ │ │ ├── __snapshots__
│ │ │ │ ├── circle-check.test.ts.snap
│ │ │ │ └── config.test.ts.snap
│ │ │ ├── circle-check.test.ts
│ │ │ ├── config.test.ts
│ │ │ ├── fixtures
│ │ │ │ ├── a.js
│ │ │ │ ├── b.js
│ │ │ │ └── loaders
│ │ │ │ │ ├── comment.js
│ │ │ │ │ └── serialize-query-to-comment.js
│ │ │ └── loader.test.ts
│ │ └── tsconfig.json
│ └── tsconfig.json
├── document
│ ├── README.md
│ ├── docs
│ │ ├── en
│ │ │ ├── _meta.json
│ │ │ ├── blog
│ │ │ │ ├── _meta.json
│ │ │ │ ├── release
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── release-note-0_1.mdx
│ │ │ │ │ ├── release-note-0_3.mdx
│ │ │ │ │ ├── release-note-0_4.mdx
│ │ │ │ │ └── release-note-1_0.mdx
│ │ │ │ └── topic
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── duplicate-pkg-problem.mdx
│ │ │ │ │ └── loader-optimization.mdx
│ │ │ ├── config
│ │ │ │ ├── _meta.json
│ │ │ │ └── options
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── options-shared.mdx
│ │ │ │ │ ├── options.mdx
│ │ │ │ │ └── term.mdx
│ │ │ ├── guide
│ │ │ │ ├── _meta.json
│ │ │ │ ├── more
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── faq.mdx
│ │ │ │ │ └── rules.mdx
│ │ │ │ ├── rules
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── rule-custom.mdx
│ │ │ │ │ ├── rules.mdx
│ │ │ │ │ └── upload-data.mdx
│ │ │ │ ├── start
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── cicd.mdx
│ │ │ │ │ ├── cli.mdx
│ │ │ │ │ ├── features.mdx
│ │ │ │ │ ├── intro.mdx
│ │ │ │ │ ├── quick-start-shared.mdx
│ │ │ │ │ └── quick-start.mdx
│ │ │ │ └── usage
│ │ │ │ │ ├── _meta.json
│ │ │ │ │ ├── bundle-alerts.mdx
│ │ │ │ │ ├── bundle-diff.mdx
│ │ │ │ │ ├── bundle-overall.mdx
│ │ │ │ │ ├── bundle-size.mdx
│ │ │ │ │ ├── compile-alerts.mdx
│ │ │ │ │ ├── compile-overall.mdx
│ │ │ │ │ ├── loaders-analysis.mdx
│ │ │ │ │ ├── loaders-timeline.mdx
│ │ │ │ │ ├── module-analysis.mdx
│ │ │ │ │ ├── plugins-analysis.mdx
│ │ │ │ │ ├── project-overall.mdx
│ │ │ │ │ ├── resolver.mdx
│ │ │ │ │ └── rule-config.mdx
│ │ │ ├── index.md
│ │ │ └── shared
│ │ │ │ ├── features-rspack.md
│ │ │ │ ├── features.md
│ │ │ │ └── mode-intro.md
│ │ ├── public
│ │ │ └── netlify.toml
│ │ └── zh
│ │ │ ├── _meta.json
│ │ │ ├── blog
│ │ │ ├── _meta.json
│ │ │ ├── release
│ │ │ │ ├── _meta.json
│ │ │ │ ├── release-note-0_1.mdx
│ │ │ │ ├── release-note-0_3.mdx
│ │ │ │ ├── release-note-0_4.mdx
│ │ │ │ └── release-note-1_0.mdx
│ │ │ └── topic
│ │ │ │ ├── _meta.json
│ │ │ │ ├── duplicate-pkg-problem.mdx
│ │ │ │ └── loader-optimization.mdx
│ │ │ ├── config
│ │ │ ├── _meta.json
│ │ │ └── options
│ │ │ │ ├── _meta.json
│ │ │ │ ├── options-shared.mdx
│ │ │ │ ├── options.mdx
│ │ │ │ └── term.mdx
│ │ │ ├── guide
│ │ │ ├── _meta.json
│ │ │ ├── more
│ │ │ │ ├── _meta.json
│ │ │ │ ├── faq.mdx
│ │ │ │ └── rules.mdx
│ │ │ ├── rules
│ │ │ │ ├── _meta.json
│ │ │ │ ├── rule-custom.mdx
│ │ │ │ ├── rules.mdx
│ │ │ │ └── upload-data.mdx
│ │ │ ├── start
│ │ │ │ ├── _meta.json
│ │ │ │ ├── cicd.mdx
│ │ │ │ ├── cli.mdx
│ │ │ │ ├── features.mdx
│ │ │ │ ├── intro.mdx
│ │ │ │ ├── quick-start-shared.mdx
│ │ │ │ └── quick-start.mdx
│ │ │ └── usage
│ │ │ │ ├── _meta.json
│ │ │ │ ├── bundle-alerts.mdx
│ │ │ │ ├── bundle-diff.mdx
│ │ │ │ ├── bundle-overall.mdx
│ │ │ │ ├── bundle-size.mdx
│ │ │ │ ├── compile-alerts.mdx
│ │ │ │ ├── compile-overall.mdx
│ │ │ │ ├── loaders-analysis.mdx
│ │ │ │ ├── loaders-timeline.mdx
│ │ │ │ ├── module-analysis.mdx
│ │ │ │ ├── plugins-analysis.mdx
│ │ │ │ ├── project-overall.mdx
│ │ │ │ ├── resolver.mdx
│ │ │ │ └── rule-config.mdx
│ │ │ ├── index.md
│ │ │ └── shared
│ │ │ ├── features-rspack.md
│ │ │ ├── features.md
│ │ │ └── mode-intro.md
│ ├── i18n.json
│ ├── package.json
│ ├── rspress.config.ts
│ ├── theme
│ │ ├── components
│ │ │ ├── Copyright.module.scss
│ │ │ ├── Copyright.tsx
│ │ │ ├── Features.module.scss
│ │ │ ├── Features.tsx
│ │ │ ├── Hero.module.scss
│ │ │ ├── Hero.tsx
│ │ │ ├── NextSteps.module.scss
│ │ │ ├── NextSteps.tsx
│ │ │ ├── Overview.module.scss
│ │ │ ├── Overview.tsx
│ │ │ ├── RuleIndex.module.scss
│ │ │ ├── RuleIndex.tsx
│ │ │ ├── Step.module.scss
│ │ │ ├── Step.tsx
│ │ │ ├── ToolStack.tsx
│ │ │ └── utils.ts
│ │ ├── global.d.ts
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── pages
│ │ │ └── index.tsx
│ │ ├── types.d.ts
│ │ └── utils.ts
│ └── tsconfig.json
├── graph
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── graph
│ │ │ ├── chunk-graph
│ │ │ │ ├── asset.ts
│ │ │ │ ├── chunk.ts
│ │ │ │ ├── entrypoint.ts
│ │ │ │ ├── graph.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── module-graph
│ │ │ │ ├── dependency.ts
│ │ │ │ ├── graph.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── module.ts
│ │ │ │ ├── statement.ts
│ │ │ │ ├── tree-shaking
│ │ │ │ │ ├── export.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── module.ts
│ │ │ │ │ ├── sideEffect.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── variable.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ │ └── package-graph
│ │ │ │ ├── dependency.ts
│ │ │ │ ├── graph.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── package.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ └── index.ts
│ ├── tests
│ │ ├── __snapshots__
│ │ │ ├── module-graph.test.ts.snap
│ │ │ └── utils.test.ts.snap
│ │ ├── fixture
│ │ │ ├── index
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── module-graph-basic.json
│ │ │ └── package.json
│ │ ├── module-graph.test.ts
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ └── tsconfig.json
├── rspack-plugin
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── constants.ts
│ │ ├── index.ts
│ │ ├── multiple.ts
│ │ ├── plugin.ts
│ │ └── types
│ │ │ └── index.ts
│ ├── tsconfig.build.json
│ └── tsconfig.json
├── sdk
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ └── sdk
│ │ │ ├── index.ts
│ │ │ ├── multiple
│ │ │ ├── controller.ts
│ │ │ ├── index.ts
│ │ │ ├── primary.ts
│ │ │ └── server.ts
│ │ │ ├── sdk
│ │ │ ├── core.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ │ ├── server
│ │ │ ├── apis
│ │ │ │ ├── alerts.ts
│ │ │ │ ├── base.ts
│ │ │ │ ├── bundle-diff.ts
│ │ │ │ ├── data.ts
│ │ │ │ ├── fs.ts
│ │ │ │ ├── graph.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── loader.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── project.ts
│ │ │ │ ├── renderer.ts
│ │ │ │ └── resolver.ts
│ │ │ ├── fakeServer.ts
│ │ │ ├── index.ts
│ │ │ ├── router.ts
│ │ │ ├── socket
│ │ │ │ ├── api.ts
│ │ │ │ └── index.ts
│ │ │ └── utils.ts
│ │ │ └── utils
│ │ │ ├── constant.ts
│ │ │ ├── index.ts
│ │ │ ├── openBrowser.ts
│ │ │ └── upload.ts
│ ├── static
│ │ └── openChrome.applescript
│ ├── tests
│ │ ├── __snapshots__
│ │ │ └── module-graph.test.ts.snap
│ │ ├── fixture
│ │ │ └── module-graph-basic.json
│ │ ├── module-graph.test.ts
│ │ ├── sdk
│ │ │ └── core
│ │ │ │ └── hooks.test.ts
│ │ ├── server
│ │ │ ├── apis
│ │ │ │ ├── data.test.ts
│ │ │ │ ├── fs.test.ts
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── project.test.ts
│ │ │ │ └── renderer.test.ts
│ │ │ └── utils.test.ts
│ │ └── utils.ts
│ └── tsconfig.json
├── types
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── babel.ts
│ │ ├── client.ts
│ │ ├── common.ts
│ │ ├── constants.ts
│ │ ├── emo.ts
│ │ ├── error.ts
│ │ ├── esbuild.ts
│ │ ├── index.ts
│ │ ├── linter
│ │ │ ├── diagnostic.ts
│ │ │ ├── index.ts
│ │ │ └── rule.ts
│ │ ├── logger.ts
│ │ ├── manifest.ts
│ │ ├── modules.ts
│ │ ├── plugin
│ │ │ ├── baseCompiler.ts
│ │ │ ├── baseLoader.ts
│ │ │ ├── baseStats.ts
│ │ │ ├── index.ts
│ │ │ ├── plugin.ts
│ │ │ └── rspack.ts
│ │ ├── rule
│ │ │ ├── code
│ │ │ │ ├── E1001.ts
│ │ │ │ ├── E1002.ts
│ │ │ │ ├── E1003.ts
│ │ │ │ ├── E1004.ts
│ │ │ │ ├── E1005.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── type.ts
│ │ │ ├── data.ts
│ │ │ └── index.ts
│ │ ├── sdk
│ │ │ ├── chunk.ts
│ │ │ ├── config.ts
│ │ │ ├── context.ts
│ │ │ ├── envinfo.ts
│ │ │ ├── hooks.ts
│ │ │ ├── index.ts
│ │ │ ├── instance.ts
│ │ │ ├── loader.ts
│ │ │ ├── module.ts
│ │ │ ├── package.ts
│ │ │ ├── plugin.ts
│ │ │ ├── process.ts
│ │ │ ├── resolver.ts
│ │ │ ├── result.ts
│ │ │ ├── server
│ │ │ │ ├── apis
│ │ │ │ │ ├── alerts.ts
│ │ │ │ │ ├── graph.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── loader.ts
│ │ │ │ │ ├── pagination.ts
│ │ │ │ │ ├── plugin.ts
│ │ │ │ │ ├── project.ts
│ │ │ │ │ └── resolver.ts
│ │ │ │ └── index.ts
│ │ │ ├── statement.ts
│ │ │ ├── summary.ts
│ │ │ └── treeShaking.ts
│ │ └── thirdparty.ts
│ └── tsconfig.json
├── utils
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── build
│ │ │ ├── envinfo.ts
│ │ │ ├── file
│ │ │ │ ├── cache.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── sharding.ts
│ │ │ ├── index.ts
│ │ │ ├── json.ts
│ │ │ ├── process.ts
│ │ │ └── server.ts
│ │ ├── common
│ │ │ ├── alerts.ts
│ │ │ ├── algorithm.ts
│ │ │ ├── bundle.ts
│ │ │ ├── crypto.ts
│ │ │ ├── data
│ │ │ │ └── index.ts
│ │ │ ├── global-config.ts
│ │ │ ├── graph
│ │ │ │ ├── assets.ts
│ │ │ │ ├── chunk.ts
│ │ │ │ ├── dependency.ts
│ │ │ │ ├── entrypoints.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── modules.ts
│ │ │ ├── index.ts
│ │ │ ├── loader.ts
│ │ │ ├── lodash.ts
│ │ │ ├── manifest.ts
│ │ │ ├── package.ts
│ │ │ ├── plugin.ts
│ │ │ ├── resolver.ts
│ │ │ ├── rspack.ts
│ │ │ ├── summary.ts
│ │ │ ├── time.ts
│ │ │ └── url.ts
│ │ ├── error
│ │ │ ├── error.ts
│ │ │ ├── index.ts
│ │ │ ├── transform.ts
│ │ │ └── utils.ts
│ │ ├── index.ts
│ │ ├── logger.ts
│ │ ├── rule-utils
│ │ │ ├── document
│ │ │ │ ├── document.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── server.ts
│ │ │ │ └── types.ts
│ │ │ ├── index.ts
│ │ │ └── parser
│ │ │ │ ├── asserts.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── parser.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ └── typings
│ │ │ └── index.d.ts
│ ├── tests
│ │ ├── __snapshots__
│ │ │ ├── crypto.test.ts.snap
│ │ │ └── json.test.ts.snap
│ │ ├── build
│ │ │ └── time.test.ts
│ │ ├── common
│ │ │ ├── algorithm.test.ts
│ │ │ ├── bundle.test.ts
│ │ │ ├── data.test.ts
│ │ │ ├── graph.test.ts
│ │ │ ├── manifest.test.ts
│ │ │ ├── plugin.test.ts
│ │ │ ├── resolver.test.ts
│ │ │ ├── time.test.ts
│ │ │ └── url.test.ts
│ │ ├── crypto.test.ts
│ │ ├── file
│ │ │ └── sharding.test.ts
│ │ ├── json.test.ts
│ │ ├── parser
│ │ │ └── parser.test.ts
│ │ └── server.test.ts
│ └── tsconfig.json
└── webpack-plugin
│ ├── LICENSE
│ ├── README.md
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ ├── constants.ts
│ ├── index.ts
│ ├── multiple.ts
│ ├── plugin.ts
│ └── plugins
│ │ └── resolver.ts
│ ├── tests
│ ├── multiple.test.ts
│ ├── multipleWithStage.test.ts
│ ├── test-utils.ts
│ └── tsconfig.json
│ ├── tsconfig.build.json
│ └── tsconfig.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── scripts
├── dictionary.txt
├── modern.base.config.ts
├── requireShims.js
├── skipCI.js
├── test-helper
│ ├── modern.config.ts
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ ├── path.ts
│ │ ├── pathSerializer.ts
│ │ ├── rsbuild.ts
│ │ ├── rspack.ts
│ │ └── webpack.ts
│ └── tsconfig.json
├── tsconfig
│ ├── base.json
│ └── package.json
└── vitest.setup.ts
└── vitest.workspace.ts
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json",
3 | "changelog": false,
4 | "commit": false,
5 | "linked": [],
6 | "access": "restricted",
7 | "baseBranch": "main",
8 | "fixed": [["@rsdoctor/*", "!@rsdoctor/mcp-server"]],
9 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
10 | "onlyUpdatePeerDependentsWhenOutOfRange": true,
11 | "updateInternalDependents": "always"
12 | },
13 | "updateInternalDependencies": "patch",
14 | "ignore": []
15 | }
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | pnpm-lock.yaml merge=ours
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Ask a question
4 | url: https://github.com/web-infra-dev/rsdoctor/discussions
5 | about: Ask a question about Rsdoctor
6 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Summary
2 |
3 | ## Related Links
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.github/pr-labeler.yml:
--------------------------------------------------------------------------------
1 | "change: feat":
2 | - "/^(feat|types|style)/"
3 | "change: fix":
4 | - "/^fix/"
5 | "change: perf":
6 | - "/^perf/"
7 | "change: breaking":
8 | - "/^breaking change/"
9 | "change: docs":
10 | - "/^docs/"
11 |
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | # .github/release.yml
2 |
3 | changelog:
4 | exclude:
5 | authors:
6 | # Ignore the release PR created by github-actions
7 | - github-actions
8 | categories:
9 | - title: Breaking Changes 🍭
10 | labels:
11 | - "change: breaking"
12 | - title: New Features 🎉
13 | labels:
14 | - "change: feat"
15 | - title: Performance 🚀
16 | labels:
17 | - "change: perf"
18 | - title: Bug Fixes 🐞
19 | labels:
20 | - "change: fix"
21 | - title: Document 📖
22 | labels:
23 | - "change: docs"
24 | - title: Other Changes
25 | labels:
26 | - "*"
27 |
--------------------------------------------------------------------------------
/.github/workflows/pr-label.yaml:
--------------------------------------------------------------------------------
1 | name: PR Labeler
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | - edited
8 |
9 | permissions:
10 | pull-requests: write
11 | contents: read
12 |
13 | jobs:
14 | change-labeling:
15 | name: Labeling for changes
16 | runs-on: ubuntu-latest
17 | if: github.repository == 'web-infra-dev/rsdoctor'
18 | steps:
19 | - uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4
20 | with:
21 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
22 | configuration-path: .github/pr-labeler.yml
23 | enable-versioned-regex: 0
24 | include-title: 1
25 | sync-labels: 1
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log*
3 | *.cpuprofile
4 | node_modules/
5 | *.tsbuildinfo
6 |
7 | dist/
8 | dist-*
9 | !**/rslog/dist
10 | coverage/
11 | doc_build/
12 | playwright-report/
13 | tsconfig.tsbuildinfo
14 |
15 | .vscode/**/*
16 | !.vscode/settings.json
17 | !.vscode/extensions.json
18 | .idea/
19 | .nx/
20 | .history/
21 | .env.local
22 | .env.*.local
23 |
24 | log/
25 |
26 | .cursor/
27 |
--------------------------------------------------------------------------------
/.husky/post-checkout:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ -f "$HUSKY_SCRIPT" ]; then
4 | . "$HUSKY_SCRIPT"
5 | # avoid conflicts in pnpm lock
6 | # https://7tonshark.com/posts/avoid-conflicts-in-pnpm-lock/
7 | git config merge.ours.driver true
8 | else
9 | exit 0
10 | fi
11 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | npx --no-install nano-staged
4 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry = 'https://registry.npmjs.org/'
2 | strict-peer-dependencies=false
3 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/jod
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore artifacts:
2 | dist
3 | compiled
4 | doc_build
5 | pnpm-lock.yaml
6 |
7 | **/doctor-core/**/tests
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "biomejs.biome",
4 | "esbenp.prettier-vscode",
5 | "streetsidesoftware.code-spell-checker"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.useIgnoreFiles": true,
3 | "search.exclude": {
4 | "**/.git": true,
5 | "**/dist": true,
6 | "**/coverage": true,
7 | "**/compiled": true,
8 | "**/doc_build": true,
9 | "**/node_modules": true,
10 | "**/tsconfig.tsbuildinfo": true
11 | },
12 | "files.exclude": {
13 | "**/.DS_Store": true
14 | },
15 | "editor.defaultFormatter": "biomejs.biome",
16 | "editor.defaultFoldingRangeProvider": "biomejs.biome",
17 | "[yaml]": {
18 | "editor.defaultFormatter": "esbenp.prettier-vscode"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | ## Reporting a vulnerability in Rsdoctor
4 |
5 | Report a security vulnerability in Rsdoctor via web-infra-security@bytedance.com.
6 |
7 | Normally, your report will be acknowledged within 24 hours, and you'll receive a more detailed response to your report within 5 days indicating the next steps in handling your submission.
8 |
9 | After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement, and may ask for additional information or guidance surrounding the reported issue.
10 |
--------------------------------------------------------------------------------
/cspell.config.cjs:
--------------------------------------------------------------------------------
1 | const { banWords } = require('cspell-ban-words');
2 |
3 | module.exports = {
4 | version: '0.2',
5 | language: 'en',
6 | files: ['**/*.{ts,tsx,js,jsx,md,mdx}'],
7 | enableFiletypes: ['mdx'],
8 | ignoreRegExpList: [
9 | // ignore markdown anchors such as [fooBar](#foobar)
10 | '#.*?\\)',
11 | ],
12 | ignorePaths: [
13 | 'dist',
14 | 'dist-*',
15 | 'compiled',
16 | 'coverage',
17 | 'doc_build',
18 | 'node_modules',
19 | 'pnpm-lock.yaml',
20 | ],
21 | flagWords: banWords,
22 | dictionaries: ['dictionary'],
23 | dictionaryDefinitions: [
24 | {
25 | name: 'dictionary',
26 | path: './scripts/dictionary.txt',
27 | addWords: true,
28 | },
29 | ],
30 | };
31 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rsbuild/fixtures/a.js:
--------------------------------------------------------------------------------
1 | console.log('a');
2 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rsbuild/fixtures/b.js:
--------------------------------------------------------------------------------
1 | const ll = 1;
2 |
3 | console.log('a');
4 |
5 | function kk() {
6 | console.log('hhe: ', ll);
7 | return '111';
8 | }
9 |
10 | kk();
11 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rsbuild/fixtures/loaders/serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.query)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rsbuild/fixtures/loaders/serialize-resource-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.resourceQuery)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.resourceQuery !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.resourceQuery))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rsbuild/fixtures/port.js:
--------------------------------------------------------------------------------
1 | const { RsdoctorWebpackPlugin } = require('../../dist/index');
2 |
3 | const plugin = new RsdoctorWebpackPlugin({});
4 |
5 | plugin.sdk.bootstrap().then(() => {
6 | console.log(plugin.sdk.server.port);
7 | });
8 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/a.js:
--------------------------------------------------------------------------------
1 | console.log('a');
2 |
3 | const { a } = require('./index');
4 | console.log(a);
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/b.js:
--------------------------------------------------------------------------------
1 | const ll = 1;
2 |
3 | console.log('a');
4 |
5 | function kk() {
6 | console.log('hhe: ', ll);
7 | return '111';
8 | }
9 |
10 | kk();
11 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/c.js:
--------------------------------------------------------------------------------
1 | const c = 1;
2 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: 18;
3 | }
4 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/index.ts:
--------------------------------------------------------------------------------
1 | export const a = 1;
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/loaders/esm-serialize-query-to-comment.mjs:
--------------------------------------------------------------------------------
1 | import { parseQuery } from 'loader-utils';
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | const loader = (input) => {
7 | const res = [input, `// ${JSON.stringify(this?.query || '')}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this?.query && this?.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this?.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
18 | export default loader;
19 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/loaders/esm/esm-serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | import { parseQuery } from 'loader-utils';
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | const loader = (input) => {
7 | const res = [input, `// ${JSON.stringify(this?.query || '')}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this?.query && this?.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this?.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
18 | export default loader;
19 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/loaders/esm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@test/rsdoctor-rspack",
4 | "version": "0.1.0",
5 | "type": "module"
6 | }
7 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/loaders/serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.query)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-rspack/fixtures/port.js:
--------------------------------------------------------------------------------
1 | const { RsdoctorRspackPlugin } = require('../../../dist/index');
2 |
3 | const plugin = new RsdoctorRspackPlugin({});
4 |
5 | plugin.sdk.bootstrap().then(() => {
6 | console.log(plugin.sdk.server.port);
7 | });
8 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures/a.js:
--------------------------------------------------------------------------------
1 | console.log('a');
2 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures/b.js:
--------------------------------------------------------------------------------
1 | const ll = 1;
2 |
3 | console.log('a');
4 |
5 | function kk() {
6 | console.log('hhe: ', ll);
7 | return '111';
8 | }
9 |
10 | kk();
11 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures/loaders/serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.query)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures/loaders/serialize-resource-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.resourceQuery)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.resourceQuery !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.resourceQuery))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures/port.js:
--------------------------------------------------------------------------------
1 | const { RsdoctorWebpackPlugin } = require('../../dist/index');
2 |
3 | const plugin = new RsdoctorWebpackPlugin({});
4 |
5 | plugin.sdk.bootstrap().then(() => {
6 | console.log(plugin.sdk.server.port);
7 | });
8 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/a.js:
--------------------------------------------------------------------------------
1 | console.log('a');
2 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/b.js:
--------------------------------------------------------------------------------
1 | import './index.less';
2 |
3 | const ll = 1;
4 |
5 | console.log('a');
6 |
7 | function kk() {
8 | console.log('hhe: ', ll);
9 | return '111';
10 | }
11 |
12 | kk();
13 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/index.less:
--------------------------------------------------------------------------------
1 | .nav {
2 | color: antiquewhite;
3 | }
4 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/loaders/serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.query)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/loaders/serialize-resource-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.resourceQuery)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.resourceQuery !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.resourceQuery))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/e2e/cases/doctor-webpack/fixtures2/port.js:
--------------------------------------------------------------------------------
1 | const { RsdoctorWebpackPlugin } = require('../../dist/index');
2 |
3 | const plugin = new RsdoctorWebpackPlugin({});
4 |
5 | plugin.sdk.bootstrap().then(() => {
6 | console.log(plugin.sdk.server.port);
7 | });
8 |
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/envinfo/0:
--------------------------------------------------------------------------------
1 | eJxVy70KwjAUBtBXuXyTQrgmoaZpNjvoFEf3YjMI5ofUQov47uKkrgfOE9cyw2Gj9JYW09ChlHsgr8kPCwRiiLmucDC6ZduS72lHpmEp6dRDIOUxXEKdbjnBQVlWHUsIrENNXz/nBx3znMbPKPEnSLasIVD+2LLac4fXG5saLO4=
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/errors/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/loader/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/moduleCodeMap/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/moduleGraph/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/otherReports/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/packageGraph/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/plugin/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/resolver/0:
--------------------------------------------------------------------------------
1 | eJyLjgUAARUAuQ==
--------------------------------------------------------------------------------
/e2e/fixtures/rsdoctor/summary/0:
--------------------------------------------------------------------------------
1 | eJx90E0KwjAQBeC7ZKXQQtK/NFkUxGOIi7ROMWibkBkRrb27CNVWELdveB+PGVjjkJDp3cB60wHTrHaOkILxcVVD6wJsXeftGVjEkEygDTEtZFKIlPMiL7MsehtCFEqM0Swt63FlWoLwB5MyT4sPlohSJQts2Y6rg+t/GkplSTkbnKcLorO9bW+rK9TeNKdMO0+2s3fYHi/9aYMIhI/pmGsfXAOIUxzwlX6H658DBJfzR6SSfNyPTzUAdNU=
--------------------------------------------------------------------------------
/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@playwright/test';
2 |
3 | export default defineConfig({
4 | testMatch: ['/cases/**/**.test.ts'],
5 | timeout: 60000,
6 | });
7 |
--------------------------------------------------------------------------------
/e2e/test-kit/launch.ts:
--------------------------------------------------------------------------------
1 | import { chromium } from '@playwright/test';
2 |
3 | export async function launchPlaywright() {
4 | const browser = await chromium.launch();
5 |
6 | const page = await browser.newPage();
7 |
8 | return {
9 | browser,
10 | page,
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/e2e/test-kit/path.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path';
2 |
3 | export function getFixtures(name: string) {
4 | return resolve(__dirname, '../fixtures', name);
5 | }
6 |
7 | export function getRsdoctorManifestPath() {
8 | const testManifestUrl = getFixtures('rsdoctor/manifest.json');
9 | return testManifestUrl;
10 | }
11 |
--------------------------------------------------------------------------------
/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "jsx": "react-jsx",
5 | "baseUrl": "./",
6 | "outDir": "./dist",
7 | "paths": {
8 | "@/*": ["./src/*"],
9 | "@scripts/*": ["./scripts/*"]
10 | }
11 | },
12 | "include": ["src", "scripts", "cases", "playwright.config.ts", "test-kit"]
13 | }
14 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp/routes/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp/routes/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Outlet } from '@modern-js/runtime/router';
2 |
3 | const { Radio } = await import('antd');
4 |
5 | const Layout = (): JSX.Element => (
6 |
7 |
8 | Radio
9 |
10 | );
11 |
12 | export default Layout;
13 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp/routes/page.tsx:
--------------------------------------------------------------------------------
1 | import { Helmet } from '@modern-js/runtime/head';
2 | import './index.css';
3 |
4 | const Index = (): JSX.Element => (
5 |
6 |
7 | Hello world
8 |
9 | );
10 |
11 | export default Index;
12 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp2/routes/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp2/routes/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Outlet } from '@modern-js/runtime/router';
2 |
3 | const { Radio } = await import('antd');
4 |
5 | const Layout = (): JSX.Element => (
6 |
7 |
8 | Radio
9 |
10 | );
11 |
12 | export default Layout;
13 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/myapp2/routes/page.tsx:
--------------------------------------------------------------------------------
1 | import { Helmet } from '@modern-js/runtime/head';
2 | import './index.css';
3 |
4 | const Index = (): JSX.Element => (
5 |
6 |
7 | Hello world
8 |
9 | );
10 |
11 | export default Index;
12 |
--------------------------------------------------------------------------------
/examples/modern-minimal/src/utils/utils.ts:
--------------------------------------------------------------------------------
1 | export const key1 = '123';
2 | export const key2 = '123';
3 |
4 | console.log(key2);
5 |
--------------------------------------------------------------------------------
/examples/modern-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "outDir": "dist",
6 | "baseUrl": ".",
7 | "module": "ESNext"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/multiple-minimal/src/app.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/multiple-minimal/src/declaration.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | const content: React.FunctionComponent>;
3 | export default content;
4 | }
5 |
6 | declare module '*.less' {
7 | const classes: { [className: string]: string };
8 | export default classes;
9 | }
10 |
11 | declare module '*/settings.json' {
12 | const value: {
13 | colorWeek: boolean;
14 | navbar: boolean;
15 | menu: boolean;
16 | footer: boolean;
17 | themeColor: string;
18 | menuWidth: number;
19 | };
20 |
21 | export default value;
22 | }
23 |
24 | declare module '*.png' {
25 | const value: string;
26 | export default value;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/multiple-minimal/src/index.module.less:
--------------------------------------------------------------------------------
1 | .header {
2 | background: var(--color-bg-2);
3 | padding: 20px;
4 | }
5 |
--------------------------------------------------------------------------------
/examples/multiple-minimal/src/index.ts:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import { createElement } from 'react';
3 |
4 | import { App } from './app';
5 |
6 | render(
7 | createElement(App, { name: 'Taylor' }),
8 | document.getElementById('root')!,
9 | );
10 |
--------------------------------------------------------------------------------
/examples/multiple-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src", "webpack.config.ts"],
4 | "compilerOptions": {
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "baseUrl": ".",
8 | "module": "NodeNext",
9 | "jsx": "react",
10 | "lib": ["DOM"]
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | color: #fff;
4 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
5 | background-image: linear-gradient(to bottom, #020917, #101725);
6 | }
7 |
8 | .content {
9 | display: flex;
10 | min-height: 100vh;
11 | line-height: 1.1;
12 | text-align: center;
13 | flex-direction: column;
14 | justify-content: center;
15 | }
16 |
17 | .content h1 {
18 | font-size: 3.6rem;
19 | font-weight: 700;
20 | }
21 |
22 | .content p {
23 | font-size: 1.2rem;
24 | font-weight: 400;
25 | opacity: 0.5;
26 | }
27 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/App.tsx:
--------------------------------------------------------------------------------
1 | import './App.css';
2 | import './semver';
3 | import './semver7';
4 |
5 | const App = () => {
6 | return (
7 | <>
8 |
9 |
Rsbuild with React
10 |
Start building amazing things with Rsbuild.
11 |
12 |
15 | >
16 | );
17 | };
18 |
19 | export default App;
20 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/button.css:
--------------------------------------------------------------------------------
1 | .button {
2 | display: flex;
3 | min-height: 100vh;
4 | line-height: 1.1;
5 | text-align: center;
6 | flex-direction: column;
7 | justify-content: center;
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 |
5 | const root = ReactDOM.createRoot(document.getElementById('root')!);
6 | root.render(
7 |
8 |
9 | ,
10 | );
11 |
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/semver.ts:
--------------------------------------------------------------------------------
1 | import semver from 'semver6';
2 |
3 | semver.valid('1.2.3') // '1.2.3'
4 | semver.valid('a.b.c') // null
5 | semver.clean(' =v1.2.3 ') // '1.2.3'
6 | semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
7 | semver.gt('1.2.3', '9.8.7') // false
8 | semver.lt('1.2.3', '9.8.7') // true
9 | semver.minVersion('>=1.0.0') // '1.0.0'
10 | semver.valid(semver.coerce('v2')) // '2.0.0'
11 | semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/src/semver7.ts:
--------------------------------------------------------------------------------
1 | import semver from 'semver7';
2 |
3 | semver.valid('1.2.3') // '1.2.3'
4 | semver.valid('a.b.c') // null
5 | semver.clean(' =v1.2.3 ') // '1.2.3'
6 | semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
7 | semver.gt('1.2.3', '9.8.7') // false
8 | semver.lt('1.2.3', '9.8.7') // true
9 | semver.minVersion('>=1.0.0') // '1.0.0'
10 | semver.valid(semver.coerce('v2')) // '2.0.0'
11 | semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
--------------------------------------------------------------------------------
/examples/rsbuild-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "outDir": "dist",
6 | "baseUrl": ".",
7 | "module": "ESNext"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-banner-minimal/public/favicon.ico
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-banner-minimal/public/logo192.png
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-banner-minimal/public/logo512.png
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | Title:{name}
12 | Content
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/Footer/index.tsx:
--------------------------------------------------------------------------------
1 | import { Layout } from '@arco-design/web-react';
2 | import { FooterProps } from '@arco-design/web-react/es/Layout/interface';
3 | import cs from 'classnames';
4 | import React from 'react';
5 | import styles from './style/index.module.less';
6 |
7 | function Footer(props: FooterProps = {}) {
8 | const { className, ...restProps } = props;
9 | return (
10 |
11 | Arco Design Pro
12 |
13 | );
14 | }
15 |
16 | export default Footer;
17 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/Footer/style/index.module.less:
--------------------------------------------------------------------------------
1 | .footer {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | height: 40px;
6 | text-align: center;
7 | color: var(--color-text-2);
8 | }
9 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/app1.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/declaration.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | const content: React.FunctionComponent>;
3 | export default content;
4 | }
5 |
6 | declare module '*.less' {
7 | const classes: { [className: string]: string };
8 | export default classes;
9 | }
10 |
11 | declare module '*/settings.json' {
12 | const value: {
13 | colorWeek: boolean;
14 | navbar: boolean;
15 | menu: boolean;
16 | footer: boolean;
17 | themeColor: string;
18 | menuWidth: number;
19 | };
20 |
21 | export default value;
22 | }
23 |
24 | declare module '*.png' {
25 | const value: string;
26 | export default value;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/index.module.less:
--------------------------------------------------------------------------------
1 | .header {
2 | background: var(--color-bg-2);
3 | padding: 20px;
4 | }
5 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/index.ts:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import { createElement } from 'react';
3 |
4 | import { App } from './app1';
5 |
6 | render(
7 | createElement(App, { name: 'Taylor' }),
8 | document.getElementById('root')!,
9 | );
10 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import { App } from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(
8 | document.getElementById('root') as HTMLElement,
9 | );
10 | root.render(
11 |
12 |
13 | ,
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
--------------------------------------------------------------------------------
/examples/rspack-banner-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "outDir": "dist",
6 | "baseUrl": ".",
7 | "module": "ESNext"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/legacy-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = function legacyLoader(content) {
2 | return `// legacy!\n${content}`;
3 | };
4 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-layers-minimal/public/favicon.ico
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-layers-minimal/public/logo192.png
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-layers-minimal/public/logo512.png
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/Footer/index.tsx:
--------------------------------------------------------------------------------
1 | import { Layout } from '@arco-design/web-react';
2 | import { FooterProps } from '@arco-design/web-react/es/Layout/interface';
3 | import cs from 'classnames';
4 | import React from 'react';
5 | import styles from './style/index.module.less';
6 |
7 | function Footer(props: FooterProps = {}) {
8 | const { className, ...restProps } = props;
9 | return (
10 |
11 | Arco Design Pro
12 |
13 | );
14 | }
15 |
16 | export default Footer;
17 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/Footer/style/index.module.less:
--------------------------------------------------------------------------------
1 | .footer {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | height: 40px;
6 | text-align: center;
7 | color: var(--color-text-2);
8 | }
9 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/app1.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/declaration.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | const content: React.FunctionComponent>;
3 | export default content;
4 | }
5 |
6 | declare module '*.less' {
7 | const classes: { [className: string]: string };
8 | export default classes;
9 | }
10 |
11 | declare module '*/settings.json' {
12 | const value: {
13 | colorWeek: boolean;
14 | navbar: boolean;
15 | menu: boolean;
16 | footer: boolean;
17 | themeColor: string;
18 | menuWidth: number;
19 | };
20 |
21 | export default value;
22 | }
23 |
24 | declare module '*.png' {
25 | const value: string;
26 | export default value;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/index.module.less:
--------------------------------------------------------------------------------
1 | .header {
2 | background: var(--color-bg-2);
3 | padding: 20px;
4 | }
5 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/index.ts:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import { createElement } from 'react';
3 |
4 | import { App } from './app1';
5 |
6 | render(
7 | createElement(App, { name: 'Taylor' }),
8 | document.getElementById('root')!,
9 | );
10 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import { App } from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(
8 | document.getElementById('root') as HTMLElement,
9 | );
10 | root.render(
11 |
12 |
13 | ,
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
--------------------------------------------------------------------------------
/examples/rspack-layers-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "outDir": "dist",
8 | "baseUrl": ".",
9 | "module": "ESNext"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-minimal/public/favicon.ico
--------------------------------------------------------------------------------
/examples/rspack-minimal/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-minimal/public/logo192.png
--------------------------------------------------------------------------------
/examples/rspack-minimal/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspack-minimal/public/logo512.png
--------------------------------------------------------------------------------
/examples/rspack-minimal/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/Footer/index.tsx:
--------------------------------------------------------------------------------
1 | import { Layout } from '@arco-design/web-react'
2 | import { FooterProps } from '@arco-design/web-react/es/Layout/interface'
3 | import cs from 'classnames'
4 | import React from 'react'
5 | import styles from './style/index.module.less'
6 |
7 | function Footer(props: FooterProps = {}) {
8 | const { className, ...restProps } = props
9 | return (
10 |
11 | Arco Design Pro
12 |
13 | )
14 | }
15 |
16 | export default Footer
17 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/Footer/style/index.module.less:
--------------------------------------------------------------------------------
1 | .footer {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | height: 40px;
6 | text-align: center;
7 | color: var(--color-text-2);
8 | }
9 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/app1.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button } from '@arco-design/web-react';
3 | import '@arco-design/web-react/dist/css/arco.css';
4 | import styles from './index.module.less';
5 |
6 | export function App({ name }: any) {
7 | return (
8 | <>
9 | Hello {name}. Welcome!
10 | <>
11 | 标题{name}
12 | 内容
13 | ,
14 | >
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/declaration.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | const content: React.FunctionComponent>;
3 | export default content;
4 | }
5 |
6 | declare module '*.less' {
7 | const classes: { [className: string]: string };
8 | export default classes;
9 | }
10 |
11 | declare module '*/settings.json' {
12 | const value: {
13 | colorWeek: boolean;
14 | navbar: boolean;
15 | menu: boolean;
16 | footer: boolean;
17 | themeColor: string;
18 | menuWidth: number;
19 | };
20 |
21 | export default value;
22 | }
23 |
24 | declare module '*.png' {
25 | const value: string;
26 | export default value;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/index.module.less:
--------------------------------------------------------------------------------
1 | .header {
2 | background: var(--color-bg-2);
3 | padding: 20px;
4 | }
5 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/index.ts:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import { createElement } from 'react';
3 |
4 | import { App } from './app1';
5 |
6 | render(
7 | createElement(App, { name: 'Taylor' }),
8 | document.getElementById('root')!,
9 | );
10 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import { App } from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(
8 | document.getElementById('root') as HTMLElement,
9 | );
10 | root.render(
11 |
12 |
13 | ,
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from "web-vitals";
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import "@testing-library/jest-dom";
6 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
17 |
--------------------------------------------------------------------------------
/examples/rspack-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "outDir": "dist",
8 | "baseUrl": ".",
9 | "module": "ESNext"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/.gitignore:
--------------------------------------------------------------------------------
1 | # Local
2 | .DS_Store
3 | *.local
4 | *.log*
5 |
6 | # Dist
7 | node_modules
8 | dist/
9 | doc_build/
10 |
11 | # IDE
12 | .vscode/*
13 | !.vscode/extensions.json
14 | .idea
15 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/README.md:
--------------------------------------------------------------------------------
1 | # Rspress website
2 |
3 | ## Setup
4 |
5 | Install the dependencies:
6 |
7 | ```bash
8 | npm install
9 | ```
10 |
11 | ## Get started
12 |
13 | Start the dev server:
14 |
15 | ```bash
16 | npm run dev
17 | ```
18 |
19 | Build the website for production:
20 |
21 | ```bash
22 | npm run build
23 | ```
24 |
25 | Preview the production build locally:
26 |
27 | ```bash
28 | npm run preview
29 | ```
30 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Guide",
4 | "link": "/guide/",
5 | "activeMatch": "/guide/"
6 | },
7 | {
8 | "text": "Hello world",
9 | "link": "/hello/",
10 | "activeMatch": "/hello/"
11 | },
12 | {
13 | "text": "API",
14 | "link": "https://rspress.rs/api/index.html"
15 | }
16 | ]
17 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/guide/_meta.json:
--------------------------------------------------------------------------------
1 | ["index"]
2 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/hello.md:
--------------------------------------------------------------------------------
1 | # Hello world!
2 |
3 | ## Start
4 |
5 | Write something to build your own docs! 🎁
6 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/public/rspress-dark-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspress-minimal/docs/public/rspress-dark-logo.png
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/public/rspress-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspress-minimal/docs/public/rspress-icon.png
--------------------------------------------------------------------------------
/examples/rspress-minimal/docs/public/rspress-light-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/examples/rspress-minimal/docs/public/rspress-light-logo.png
--------------------------------------------------------------------------------
/examples/rspress-minimal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rspress-minimal",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "rspress build",
7 | "build:analysis": "RSDOCTOR=true rspress build",
8 | "dev": "rspress dev",
9 | "preview": "rspress preview"
10 | },
11 | "dependencies": {
12 | "rspress": "2.0.0-alpha.3"
13 | },
14 | "devDependencies": {
15 | "@rsdoctor/rspack-plugin": "workspace:*",
16 | "@types/node": "^22.8.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/rspress-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "lib": ["DOM", "ES2020"],
5 | "module": "ESNext",
6 | "jsx": "react-jsx",
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "resolveJsonModule": true,
12 | "moduleResolution": "bundler",
13 | "useDefineForClassFields": true,
14 | "allowImportingTsExtensions": true
15 | },
16 | "include": ["docs", "theme", "rspress.config.ts"],
17 | "mdx": {
18 | "checkMdx": true
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/html.ts:
--------------------------------------------------------------------------------
1 | import Parser from 'htmlparser2';
2 | import svg from "./images/file.svg";
3 | import { createImageElement } from './utils/utils';
4 |
5 |
6 | export function getHtmlText(code: string) {
7 | let context = '';
8 |
9 | const parser = new Parser.Parser({
10 | ontext(data) {
11 | context += data;
12 | },
13 | });
14 | [svg].forEach(src => {
15 | createImageElement(src.split(".").pop(), src);
16 | });
17 | parser.write(code);
18 |
19 | return context;
20 | }
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/images/file.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Chalk } from 'chalk';
2 | import { highlight } from './utils';
3 | import { getHtmlText } from './html';
4 | import { key6 } from './utils2';
5 | import './style.css';
6 |
7 | const print = new Chalk();
8 |
9 | print(key6);
10 | print(getHtmlText('Test Text
'));
11 | print(highlight?.('const abc = 123;'));
12 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: green;
3 | font-family: "Open Sans";
4 | }
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/types.ts:
--------------------------------------------------------------------------------
1 | declare module '@babel/highlight';
2 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
17 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils.ts:
--------------------------------------------------------------------------------
1 | import highlight from '@babel/highlight';
2 |
3 | export { highlight };
4 | export const key1 = '123';
5 | export const key2 = '123';
6 |
7 | console.log(key2);
8 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | import { Linter } from '@rsdoctor/types';
2 |
3 | export function toSeverity(input: Linter.SeverityInput, defaultLevel: Linter.Severity): Linter.Severity {
4 | if (input === 'off') {
5 | return Linter.Severity.Ignore;
6 | }
7 |
8 | if (input === 'on') {
9 | return defaultLevel;
10 | }
11 |
12 | const key = `${input[0].toUpperCase()}${input.slice(1)}` as Linter.SeverityString;
13 | return Linter.Severity[key] as Linter.Severity;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils/utils.js:
--------------------------------------------------------------------------------
1 | const container = document.createElement("div");
2 | Object.assign(container.style, {
3 | display: "flex",
4 | justifyContent: "center"
5 | });
6 | document.body.appendChild(container);
7 |
8 | export function createImageElement(title, src) {
9 | const div = document.createElement("div");
10 | div.style.textAlign = "center";
11 |
12 | const h2 = document.createElement("h2");
13 | h2.textContent = title;
14 | div.appendChild(h2);
15 |
16 | const img = document.createElement("img");
17 | img.setAttribute("src", src);
18 | img.setAttribute("width", "150");
19 | div.appendChild(img);
20 |
21 | container.appendChild(div);
22 | }
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils2.ts:
--------------------------------------------------------------------------------
1 | export * as utils6 from './utils6';
2 |
3 | export * from './utils';
4 | export * from './utils4';
5 | export * from './html';
6 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils3.ts:
--------------------------------------------------------------------------------
1 | import { key1 } from './utils';
2 |
3 | export const key3 = key1 + 1;
4 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils4.ts:
--------------------------------------------------------------------------------
1 | export * from './utils5';
2 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils5.ts:
--------------------------------------------------------------------------------
1 | export * from './utils6';
2 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/src/utils6.ts:
--------------------------------------------------------------------------------
1 | export const key6 = 'key6';
2 |
--------------------------------------------------------------------------------
/examples/webpack-minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "include": ["src", "webpack.config.ts"],
4 | "compilerOptions": {
5 | "outDir": "dist",
6 | "baseUrl": ".",
7 | "module": "ESNext"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/nx/schemas/nx-schema.json",
3 | "namedInputs": {
4 | "default": ["{projectRoot}/src/**/*"],
5 | "build": [
6 | "default",
7 | "!{projectRoot}/**/*.{md,mdx}",
8 | "{projectRoot}/tsconfig.json",
9 | "{projectRoot}/package.json",
10 | "{projectRoot}/modern.config.*",
11 | "{projectRoot}/scripts/**/*"
12 | ]
13 | },
14 | "targetDefaults": {
15 | "build": {
16 | "cache": true,
17 | "dependsOn": ["^build"],
18 | "inputs": ["build", "^build"]
19 | }
20 | },
21 | "defaultBase": "main"
22 | }
23 |
--------------------------------------------------------------------------------
/packages/ai/.env.sample:
--------------------------------------------------------------------------------
1 | ## openai
2 | OPENAI_API_KEY="xxx"
3 | OPENAI_BASE_URL="xxx"
4 | OPENAI_MODEL_NAME="gpt-4o-2024-08-06"
5 |
6 | ## coze
7 | COZE_API_TOKEN="yyy"
8 | COZE_BOT_ID="yyy"
9 | COZE_COM_BASE_URL="yyy"
--------------------------------------------------------------------------------
/packages/ai/.gitignore:
--------------------------------------------------------------------------------
1 | # Local
2 | .DS_Store
3 | *.local
4 | *.log*
5 | logs/
6 |
7 | # Dist
8 | node_modules
9 | dist/
10 |
11 | # IDE
12 | .vscode/*
13 | !.vscode/extensions.json
14 | .idea
15 |
16 | # env
17 | .env
18 | .env.*
19 | !.env.sample
20 |
--------------------------------------------------------------------------------
/packages/ai/bin/rsdoctor-mcp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import { runServer } from '../dist/index.js';
4 |
5 |
6 | runServer().catch((error) => {
7 | console.error('Fatal error running server:', error);
8 | process.exit(1);
9 | });
10 |
--------------------------------------------------------------------------------
/packages/ai/rslib.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@rslib/core';
2 |
3 | export default defineConfig({
4 | lib: [
5 | {
6 | source: {
7 | entry: {
8 | index: './src/server/server.ts',
9 | },
10 | tsconfigPath: './tsconfig.build.json',
11 | },
12 | output: {
13 | distPath: {
14 | root: './dist/',
15 | },
16 | },
17 | bundle: true,
18 | dts: false,
19 | format: 'esm',
20 | syntax: 'es2021',
21 | },
22 | ],
23 | output: {
24 | copy: {
25 | patterns: [{ from: 'resources', to: 'resources' }],
26 | },
27 | },
28 | });
29 |
--------------------------------------------------------------------------------
/packages/ai/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './server/index.js';
2 |
--------------------------------------------------------------------------------
/packages/ai/src/prompt/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/packages/ai/src/prompt/index.ts
--------------------------------------------------------------------------------
/packages/ai/src/schema.ts:
--------------------------------------------------------------------------------
1 | import z from 'zod';
2 |
3 | export const SizeSchema = z.object({
4 | sourceSize: z.number(),
5 | transformedSize: z.number(),
6 | parsedSize: z.number(),
7 | });
8 |
9 | export const DependenciesSchema = z.object({
10 | name: z.string(),
11 | root: z.string(),
12 | version: z.string(),
13 | size: SizeSchema,
14 | });
15 |
--------------------------------------------------------------------------------
/packages/ai/src/server/index.ts:
--------------------------------------------------------------------------------
1 | import { runServer } from './server.js';
2 |
3 | runServer().catch((error) => {
4 | console.error('Fatal error running server:', error);
5 | process.exit(1);
6 | });
7 |
--------------------------------------------------------------------------------
/packages/ai/src/utils/env.ts:
--------------------------------------------------------------------------------
1 | export const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? undefined;
2 | export const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL ?? undefined;
3 | export const OPENAI_MODEL_NAME = process.env.OPENAI_MODEL_NAME ?? undefined;
4 | export const OPENAI_INIT_OPTIONS = JSON.parse(
5 | process.env.OPENAI_INIT_OPTIONS ?? '{}',
6 | );
7 |
--------------------------------------------------------------------------------
/packages/ai/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chunks.js';
2 |
--------------------------------------------------------------------------------
/packages/ai/tests/index.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from 'vitest';
2 | import { ChatGPT } from './model/openai';
3 |
4 | test('openai chat', async () => {
5 | const instance = new ChatGPT();
6 | const data1 = await import('./fixtures/deps.json');
7 | });
8 |
--------------------------------------------------------------------------------
/packages/ai/tests/model/coze.ts:
--------------------------------------------------------------------------------
1 | // Langchain does not provide a nodejs version of the coze sdk.
2 | // Only python version: https://python.langchain.com/docs/integrations/chat/coze
3 | // So use coze sdk first.
4 |
--------------------------------------------------------------------------------
/packages/ai/tests/socket.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from 'vitest';
2 | import { createSocket, sendRequest } from '../src/server/socket';
3 | import { SDK } from '@rsdoctor/types';
4 |
5 | test('createSocket', async () => {
6 | const res = await sendRequest(SDK.ServerAPI.API.GetChunkGraph, {});
7 | console.log(res);
8 | });
9 |
--------------------------------------------------------------------------------
/packages/ai/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [".", "../vitest.setup.ts"],
4 | "exclude": ["fixtures/**/*"]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/ai/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "Node16",
5 | "moduleResolution": "Node16",
6 | "strict": true,
7 | "esModuleInterop": true,
8 | "skipLibCheck": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "resolveJsonModule": true,
11 | "outDir": "./dist",
12 | "rootDir": "./src",
13 | "paths": {
14 | "@/*": ["./src/*"]
15 | }
16 | },
17 | "include": ["src/**/*.ts"],
18 | "exclude": ["node_modules", "dist", "src/resources/**/*"]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/ai/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["ES2021"],
4 | "module": "ESNext",
5 | "noEmit": true,
6 | "strict": true,
7 | "skipLibCheck": true,
8 | "isolatedModules": true,
9 | "resolveJsonModule": true,
10 | "moduleResolution": "bundler",
11 | "useDefineForClassFields": true,
12 | "allowImportingTsExtensions": true,
13 | "paths": {
14 | "@/*": ["./src/*"]
15 | }
16 | },
17 | "include": ["src"]
18 | }
19 |
--------------------------------------------------------------------------------
/packages/ai/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import path from 'node:path';
2 | import { defineConfig } from 'vitest/config';
3 |
4 | export default defineConfig({
5 | // Configure Vitest (https://vitest.dev/config/)
6 | test: {
7 | testTimeout: 500000,
8 | setupFiles: ['dotenv/config'],
9 | alias: {
10 | '@': path.resolve(__dirname, 'src'),
11 | },
12 | },
13 | });
14 |
--------------------------------------------------------------------------------
/packages/cli/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/cli
2 |
3 | This is the CLI of Rsdoctor, you can use the capabilities of this package to open the analysis page without building.
4 |
5 | ```bash
6 | npx @rsdoctor/cli analyze --profile [.rsdoctor/manifest.json filepath]
7 | ```
8 |
9 | ## Documentation
10 |
11 | https://rsdoctor.rs/
12 |
13 | ## Contributing
14 |
15 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
16 |
17 | ## License
18 |
19 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
20 |
--------------------------------------------------------------------------------
/packages/cli/bin/rsdoctor:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const { execute } = require('../dist/index.js');
4 |
5 | execute();
6 |
--------------------------------------------------------------------------------
/packages/cli/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { baseBuildConfig } from '../../scripts/modern.base.config';
2 |
3 | export default baseBuildConfig;
4 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/index.ts:
--------------------------------------------------------------------------------
1 | export * from './analyze';
2 | export * from './bundle-diff';
3 |
--------------------------------------------------------------------------------
/packages/cli/src/constants.ts:
--------------------------------------------------------------------------------
1 | export enum Commands {
2 | Analyze = 'analyze',
3 | BundleDiff = 'bundle-diff',
4 | }
5 |
6 | export const pkg: {
7 | name: string;
8 | version: string;
9 | bin: Record;
10 | } = require('../package.json');
11 |
12 | export const bin = Object.keys(pkg.bin)[0];
13 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "experimentalDecorators": true,
5 | "outDir": "./dist",
6 | "baseUrl": "./",
7 | "paths": {
8 | "@/*": ["./src/*"]
9 | },
10 | "rootDir": "src"
11 | },
12 | "include": ["src"],
13 | "exclude": ["**/node_modules"],
14 | "references": [
15 | {
16 | "path": "../types/tsconfig.json"
17 | },
18 | {
19 | "path": "../utils/tsconfig.json"
20 | },
21 | {
22 | "path": "../sdk/tsconfig.json"
23 | },
24 | {
25 | "path": "../client/tsconfig.json"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/packages/client/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/client
2 |
3 | This package is the Rsdoctor reporting platform.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/client/config/constants.ts:
--------------------------------------------------------------------------------
1 | import { Constants } from '@rsdoctor/types';
2 |
3 | import path from 'path';
4 |
5 | export const DistPath = path.resolve(__dirname, '../dist');
6 |
7 | export const DistResourcePath = path.resolve(__dirname, '../dist/resource');
8 |
9 | export const WebpackRsdoctorDirPath = path.resolve(__dirname, `../dist/${Constants.RsdoctorOutputFolder}`);
10 |
11 | export const WebpackStatsFilePath = path.resolve(__dirname, '../dist/stats.json');
12 |
13 | export const PortForWeb = 8681;
14 |
15 | export const PortForCLI = 8123;
16 |
17 | export const ClientEntry = path.resolve(__dirname, '../src/index.tsx');
18 |
19 | export const RsdoctorWebpackPluginMain = path.resolve(__dirname, '../../webpack-plugin/dist');
20 |
--------------------------------------------------------------------------------
/packages/client/src/common/styles/base.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:meta';
2 | @import 'normalize.css';
3 | @include meta.load-css('./theme.scss');
4 |
5 | .body {
6 | font-size: 12px;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/client/src/common/styles/theme.scss:
--------------------------------------------------------------------------------
1 | // body {
2 | // background-color: rgb(247, 245, 245);
3 | // }
4 |
--------------------------------------------------------------------------------
/packages/client/src/index.tsx:
--------------------------------------------------------------------------------
1 | import '@rsdoctor/components/i18n';
2 | import App from './App';
3 | import ReactDOM from 'react-dom/client';
4 | import './common/styles/base.scss';
5 |
6 | const rootElement = document.getElementById('root');
7 | const root = ReactDOM.createRoot(rootElement!);
8 |
9 | root.render();
10 |
11 | const link = document.createElement('link');
12 | link.setAttribute('type', 'image/x-icon');
13 | link.setAttribute('rel', 'icon');
14 | link.setAttribute(
15 | 'href',
16 | 'https://assets.rspack.rs/rsdoctor/rsdoctor-logo-960x960.png',
17 | );
18 | document.head.appendChild(link);
19 |
--------------------------------------------------------------------------------
/packages/client/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
17 |
--------------------------------------------------------------------------------
/packages/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "jsx": "react-jsx",
6 | "isolatedModules": true,
7 | "declaration": true,
8 | "declarationMap": false,
9 | "composite": true,
10 | "outDir": "dist"
11 | },
12 | "include": ["src", "config"],
13 | "exclude": ["**/node_modules"],
14 | "references": [
15 | {
16 | "path": "../types/tsconfig.json"
17 | },
18 | {
19 | "path": "../components/tsconfig.json"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/components/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/components
2 |
3 | This package is the Rsdoctor reporting platform’s components.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/components/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, moduleTools } from '@modern-js/module-tools';
2 |
3 | export default defineConfig({
4 | plugins: [moduleTools()],
5 | buildConfig: {
6 | buildType: 'bundleless',
7 | format: 'esm',
8 | target: 'es2020',
9 | outDir: './dist',
10 | sourceMap: true,
11 | minify: false,
12 | asset: {
13 | svgr: {
14 | include: /\.svg$/,
15 | },
16 | },
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/packages/components/src/common/imgs/rsdoctor-navbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/packages/components/src/common/imgs/rsdoctor-navbar.png
--------------------------------------------------------------------------------
/packages/components/src/common/imgs/webpack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/components/src/common/svg/file.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/packages/components/src/common/svg/navbar/compile-analysis-active.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/packages/components/src/common/svg/navbar/compile-analysis-inactive.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/packages/components/src/common/svg/source-size.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/packages/components/src/common/svg/total-size.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alert/ecma-version-check.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | justify-content: space-between;
4 | align-items: center;
5 | padding: 10px 20px;
6 |
7 | .box {
8 | width: 290px;
9 | display: flex;
10 | }
11 |
12 | .title {
13 | font-size: 12px;
14 | font-weight: 400;
15 | line-height: 16px;
16 | margin-bottom: 5px;
17 | color: #00000073;
18 | }
19 |
20 | .content {
21 | font-size: 14px;
22 | font-weight: 400;
23 | line-height: 16px;
24 | margin-left: 5px;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alert/file-relation.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Alert } from 'antd';
3 | import { FileRelationAlertProps } from './types';
4 |
5 | export const FileRelationAlert: React.FC = ({ data }) => {
6 | const { description = '', level } = data;
7 | return ;
8 | };
9 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alert/index.scss:
--------------------------------------------------------------------------------
1 | // can del
2 | .file-inline-decoration {
3 | cursor: pointer;
4 | text-decoration: underline;
5 | background: rgb(77, 112, 151);
6 | }
7 |
8 | .alert-space,
9 | .full-space {
10 | width: 100%;
11 | height: 100%;
12 |
13 | > *:last-child {
14 | flex-grow: 1;
15 | }
16 | }
17 | .full-space {
18 | flex-grow: 1;
19 | }
20 |
21 | .code-change-tag-list {
22 | margin-left: 10px;
23 | }
24 |
25 | .tabs-space {
26 | width: 100%;
27 | height: 100%;
28 |
29 | .ant-tabs-content,
30 | .ant-tabs-tabpane {
31 | width: 100%;
32 | height: 100%;
33 | }
34 | }
35 |
36 | .ant-alert-warning {
37 | border: none;
38 | }
39 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alert/package-relation.module.scss:
--------------------------------------------------------------------------------
1 | .dot {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: center;
6 | }
7 |
8 | .filePath {
9 | display: flex;
10 | justify-content: space-between;
11 | align-items: center;
12 | border: 1px solid #eaedf1;
13 | padding: 5px 10px;
14 | border-radius: 10px;
15 | }
16 |
17 | .arrow {
18 | position: relative;
19 | top: 8px;
20 | left: 50%;
21 | transform: translateX(-50%) rotate(90deg);
22 | color: #2994ff;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alerts/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './bundle';
2 | export * from './compile';
3 | export * from './overlay';
4 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alerts/list.module.scss:
--------------------------------------------------------------------------------
1 | .description {
2 | font-size: 14px;
3 | font-weight: 400;
4 | line-height: 16px;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/components/src/components/Alerts/overlay.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | top: 4px;
4 |
5 | .badgeContainer {
6 | display: flex;
7 | justify-content: center;
8 | align-items: center;
9 | width: 32px;
10 | height: 32px;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/components/src/components/Card/size.module.scss:
--------------------------------------------------------------------------------
1 | .dataContainer {
2 | display: flex;
3 | flex-direction: column;
4 |
5 | .title {
6 | font-size: 12px;
7 | font-weight: 400;
8 | line-height: 20px;
9 | margin-bottom: 2px;
10 | color: #000000a6;
11 | }
12 | }
13 |
14 | .description {
15 | font-size: 18px;
16 |
17 | @media (max-width: 1500px) {
18 | font-size: 14px;
19 | }
20 |
21 | font-weight: 500;
22 | line-height: 28px;
23 | color: #000000d9;
24 | }
25 |
26 | .percentContainer {
27 | display: flex;
28 | flex-direction: column;
29 | font-size: 20px;
30 |
31 | .percentDescription {
32 | font-size: 12px;
33 | font-weight: 400;
34 | line-height: 20px;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/components/src/components/Charts/constants.ts:
--------------------------------------------------------------------------------
1 | export const PALETTE_COLORS = [
2 | '#F2793D',
3 | '#F28B24',
4 | '#F2A200',
5 | '#F5CC00',
6 | '#F5E000',
7 | '#A3D900',
8 | '#66CC00',
9 | '#0AC419',
10 | '#0AC496',
11 | '#0AC7D1',
12 | '#00A8E0',
13 | '#1471F5',
14 | '#4060FF',
15 | '#7559FF',
16 | '#884DFF',
17 | '#A526FF',
18 | '#BA39E5',
19 | '#C700D9',
20 | '#D900B5',
21 | '#E50099',
22 | '#E52E6B',
23 | '#F24957',
24 | '#30B2F2',
25 | '#00BF70',
26 | '#5959FF',
27 | '#9F40FF',
28 | '#528BFF',
29 | ];
30 |
31 | export enum ChartTypes {
32 | Bootstrap,
33 | Compile,
34 | Done,
35 | Minify,
36 | Loader,
37 | Normal,
38 | }
39 |
--------------------------------------------------------------------------------
/packages/components/src/components/Configuration/builder.module.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | font-size: 13px;
3 | font-weight: 400;
4 | line-height: 22px;
5 | text-align: right;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/components/src/components/Configuration/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './builder';
2 |
--------------------------------------------------------------------------------
/packages/components/src/components/Keyword/style.module.scss:
--------------------------------------------------------------------------------
1 | .text {
2 | font-size: 14px;
3 | font-weight: 400;
4 | color: rgba(0, 0, 0, 0.85);
5 | }
6 |
--------------------------------------------------------------------------------
/packages/components/src/components/Layout/compile-icon.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/packages/components/src/components/Layout/constants.ts:
--------------------------------------------------------------------------------
1 | export const CompileName = 'Compile Analysis';
2 |
--------------------------------------------------------------------------------
/packages/components/src/components/Layout/header.scss:
--------------------------------------------------------------------------------
1 | .header-switch {
2 | .ant-switch-handle {
3 | top: 1px !important;
4 | }
5 | }
6 |
7 | .header-icon {
8 | user-select: none;
9 |
10 | &:hover {
11 | color: #1668dc;
12 | }
13 | &:active {
14 | color: #40a9ff;
15 | }
16 | }
17 |
18 | .rsdoctor-logo {
19 | cursor: pointer;
20 | height: 30px;
21 |
22 | &:active {
23 | opacity: 0.8;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/components/src/components/Manifest/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './data';
2 | export * from './api';
3 |
--------------------------------------------------------------------------------
/packages/components/src/components/Opener/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './code';
2 | export * from './vscode';
3 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/card.module.scss:
--------------------------------------------------------------------------------
1 | .card {
2 | width: 100%;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/compile.module.scss:
--------------------------------------------------------------------------------
1 | .progress {
2 | :global(.ant-progress-text) {
3 | opacity: 0.8;
4 | font-size: 13px;
5 | }
6 | }
7 |
8 | .title {
9 | font-size: 16px;
10 | font-weight: 500;
11 | line-height: 20px;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './bundle';
2 | export * from './compile';
3 | export * from './project';
4 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/list.module.scss:
--------------------------------------------------------------------------------
1 | .projectOverall {
2 | :global(.ant-descriptions-item-label),
3 | :global(.ant-descriptions-item-content) {
4 | font-size: 13px;
5 | color: #000000a6;
6 | }
7 |
8 | :global(.ant-descriptions-item) {
9 | padding-bottom: 10px !important;
10 | }
11 | }
12 |
13 | .bundleOverall {
14 | :global(.ant-descriptions-item-label),
15 | :global(.ant-descriptions-item-content) {
16 | font-size: 13px;
17 | color: #000000a6;
18 | }
19 |
20 | :global(.ant-descriptions-item) {
21 | padding-bottom: 0px !important;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/overview.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | display: flex;
4 | background: #f6f8fa;
5 | align-items: center;
6 | justify-content: space-between;
7 | border-radius: 8px;
8 | padding: 8px 20px 8px 20px;
9 | margin-right: 10px;
10 | white-space: nowrap;
11 |
12 | .content {
13 | flex: 1;
14 |
15 | .title {
16 | font-size: 12px;
17 | font-weight: 400;
18 | line-height: 20px;
19 | color: #000000a6;
20 | }
21 |
22 | .description {
23 | font-size: 24px;
24 | font-weight: 500;
25 | line-height: 32px;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/overview.tsx:
--------------------------------------------------------------------------------
1 | import styles from './overview.module.scss';
2 |
3 | interface OverviewProps {
4 | title?: string | React.ReactNode;
5 | description?: string | React.ReactNode;
6 | icon?: React.ReactNode;
7 | style?: React.CSSProperties;
8 | }
9 |
10 | export const Overview = (props: OverviewProps) => {
11 | const { title, description, icon, style } = props;
12 | return (
13 |
14 |
15 |
{title}
16 |
{description}
17 |
18 | {icon}
19 |
20 | );
21 | };
22 |
23 | export default Overview;
24 |
--------------------------------------------------------------------------------
/packages/components/src/components/Overall/project.module.scss:
--------------------------------------------------------------------------------
1 | .overview {
2 | display: flex;
3 | margin-bottom: 19px;
4 | }
5 |
6 | .title {
7 | display: flex;
8 | justify-content: space-between;
9 | align-items: center;
10 | padding-bottom: 20px;
11 |
12 | .left {
13 | font-size: 16px;
14 | font-weight: 500;
15 | line-height: 24px;
16 | text-align: left;
17 | text-underline-position: from-font;
18 | text-decoration-skip-ink: none;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/components/src/components/Select/index.scss:
--------------------------------------------------------------------------------
1 | .loader-select {
2 | .ant-select-selector {
3 | width: 300px;
4 | }
5 | }
6 |
7 | .layer-select {
8 | .ant-select-selector {
9 | width: 150px;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/components/src/components/Status/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './failed';
2 |
--------------------------------------------------------------------------------
/packages/components/src/components/base/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 业务无关的基础组件
3 | */
4 |
5 | export * from './CodeViewer';
6 | export * from './DiffViewer';
7 |
--------------------------------------------------------------------------------
/packages/components/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Alerts';
2 | export * from './Badge';
3 | export * from './base';
4 | export * from './Card';
5 | export { TimelineCom } from './Charts/TimelineCharts';
6 | export * from './Form/keyword';
7 | export * from './Layout';
8 | export * from './Manifest';
9 | export * from './Overall';
10 | export * from './TextDrawer';
11 |
--------------------------------------------------------------------------------
/packages/components/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components';
2 | export * from './utils';
3 | export * as Constants from './constants';
--------------------------------------------------------------------------------
/packages/components/src/modern-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/packages/components/src/pages/BundleSize/components/index.scss:
--------------------------------------------------------------------------------
1 | $prefixCls: 'bundle-size';
2 |
3 | .monaco-hover .markdown-hover.hover-row hr {
4 | margin: 2px;
5 | background-color: gray;
6 | }
7 |
8 | .#{$prefixCls}-editor {
9 | margin-left: 40px;
10 | flex-grow: 1;
11 | height: 700px;
12 |
13 | .ant-card-body {
14 | width: auto;
15 | height: calc(100% - 48px);
16 | padding: 0;
17 | }
18 | }
19 |
20 | .#{$prefixCls}-module-bunton {
21 | margin-left: 4em;
22 | }
23 |
24 | .ant-tabs-nav {
25 | width: 100%;
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/packages/components/src/pages/BundleSize/config.tsx:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react';
2 |
3 | interface config {
4 | setModuleJumpList(ids: number[]): void;
5 | moduleJumpList: number[];
6 | }
7 |
8 | export const ModuleGraphListContext = createContext({
9 | setModuleJumpList(_ids: number[]): void {},
10 | moduleJumpList: [] as number[],
11 | });
12 |
--------------------------------------------------------------------------------
/packages/components/src/pages/BundleSize/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const maxModuleSize = 5000;
4 |
5 | export const name = 'BundleSize';
6 |
7 | export const route = Client.RsdoctorClientRoutes.BundleSize;
8 |
9 | export type GraphType = 'tile' | 'tree';
10 |
--------------------------------------------------------------------------------
/packages/components/src/pages/BundleSize/index.tsx:
--------------------------------------------------------------------------------
1 | import { Col, Row } from 'antd';
2 | import React from 'react';
3 |
4 | import { Size } from '../../constants';
5 | import { WebpackModulesOverall } from './components';
6 |
7 | export const Page: React.FC = () => {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | };
16 |
17 | export * from './constants';
18 |
--------------------------------------------------------------------------------
/packages/components/src/pages/ModuleAnalyze/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Module Analyze';
4 |
5 | export const route = Client.RsdoctorClientRoutes.ModuleAnalyze;
6 |
7 | export enum DevtoolsRuleClientConstant {
8 | UrlQueryForModuleAnalyze = 'curModuleId',
9 | }
10 |
11 | export const clsNamePrefix = 'module-analyze';
12 |
--------------------------------------------------------------------------------
/packages/components/src/pages/ModuleAnalyze/index.scss:
--------------------------------------------------------------------------------
1 | $prefixCls: 'module-analyze';
2 |
3 | .#{$prefixCls}-file-tree {
4 | width: '100%';
5 | min-height: 50em;
6 |
7 | .#{$prefixCls}-empty {
8 | margin-top: 20%;
9 | }
10 | }
11 |
12 | .module-analyze-box {
13 | display: flex;
14 | flex-direction: column;
15 | }
16 |
17 | .file-tree-com-titles-box {
18 | line-height: 30px;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/components/src/pages/ModuleResolve/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'ModuleResolve';
4 |
5 | export const route = Client.RsdoctorClientRoutes.ModuleResolve;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/ModuleResolve/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Card } from 'antd';
3 | import { ResolverAnalysis } from '../../components/Resolver/analysis';
4 | import { WebpackConfigurationViewer } from '../../components/Configuration';
5 |
6 | export const Page: React.FC = () => {
7 | return (
8 |
9 | }
12 | bodyStyle={{ paddingTop: 0 }}
13 | >
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | export * from './constants';
21 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Overall/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Overall';
4 |
5 | export const route = Client.RsdoctorClientRoutes.Overall;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Overall/responsiveLayout.tsx:
--------------------------------------------------------------------------------
1 | import { Flex } from 'antd';
2 | import React from 'react';
3 |
4 | import style from './index.module.scss';
5 |
6 | interface Props {
7 | children: React.ReactNode[];
8 | }
9 |
10 | export const ResponsiveLayout = ({ children }: Props) => {
11 | return (
12 |
13 | {children.map((e) => (
14 | {e}
15 | ))}
16 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Resources/BundleDiff/DiffContainer/constants.ts:
--------------------------------------------------------------------------------
1 | export enum UpdateType {
2 | New = 'New',
3 | Changed = 'Changed',
4 | Deleted = 'Deleted',
5 | NotChanged = 'Not Changed',
6 | }
7 |
8 | export enum SortType {
9 | Name = 'Sorted by Name',
10 | Size = 'Sorted by Size',
11 | Delta = 'Sorted by Delta',
12 | }
13 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Resources/BundleDiff/constants.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Client, Manifest } from '@rsdoctor/types';
3 |
4 | export const name = 'Bundle Diff';
5 |
6 | export const route = Client.RsdoctorClientRoutes.BundleDiff;
7 |
8 | export const BundleDiffContext = React.createContext({
9 | manifests: [] as Manifest.RsdoctorManifest[],
10 | setManifests(_manifests: Manifest.RsdoctorManifest[]): void {},
11 | loading: false,
12 | setLoading(_loading: boolean): void {},
13 | async withLoading(
14 | _func: (...args: unknown[]) => Promise | unknown,
15 | ) {},
16 | });
17 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Resources/BundleDiff/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { DiffContainer } from './DiffContainer';
3 |
4 | export * from './constants';
5 | export * from './DiffContainer';
6 |
7 | export const Page: React.FC = () => {
8 | return ;
9 | };
10 |
--------------------------------------------------------------------------------
/packages/components/src/pages/Resources/RuleIndex/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Rule Index';
4 |
5 | export const route = Client.RsdoctorClientRoutes.RuleIndex;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/TreeShaking/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'TreeShaking';
4 |
5 | export const route = Client.RsdoctorClientRoutes.TreeShaking;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/TreeShaking/space.tsx:
--------------------------------------------------------------------------------
1 | import { Card, Empty } from 'antd';
2 |
3 | export function Space() {
4 | return (
5 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/src/pages/TreeShaking/types.ts:
--------------------------------------------------------------------------------
1 | import { SDK } from '@rsdoctor/types';
2 |
3 | export type TableKind = 'side-effect' | 'export';
4 | export type SetEditorStatus = (
5 | module: SDK.ModuleInstance,
6 | ranges: SDK.SourceRange[],
7 | line?: number,
8 | ) => void;
9 |
--------------------------------------------------------------------------------
/packages/components/src/pages/WebpackLoaders/Analysis/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Loaders Analysis';
4 |
5 | export const route = Client.RsdoctorClientRoutes.WebpackLoaderAnalysis;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/WebpackLoaders/Overall/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Loaders Timeline';
4 |
5 | export const route = Client.RsdoctorClientRoutes.WebpackLoaderOverall;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/WebpackLoaders/constants.ts:
--------------------------------------------------------------------------------
1 | export const name = 'Loaders';
2 |
3 | export const route = '/webpack/loaders';
4 |
--------------------------------------------------------------------------------
/packages/components/src/pages/WebpackPlugins/constants.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '@rsdoctor/types';
2 |
3 | export const name = 'Plugins Analysis';
4 |
5 | export const route = Client.RsdoctorClientRoutes.WebpackPlugins;
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/WebpackPlugins/index.scss:
--------------------------------------------------------------------------------
1 | .plugin-select {
2 | .ant-select-selector {
3 | width: 300px;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/components/src/pages/index.ts:
--------------------------------------------------------------------------------
1 | export * as Overall from './Overall';
2 | export * as BundleSize from './BundleSize';
3 | export * as ModuleAnalyze from './ModuleAnalyze';
4 | export * as LoaderTimeline from './WebpackLoaders/Overall';
5 | export * as LoaderFiles from './WebpackLoaders/Analysis';
6 | export * as PluginsAnalyze from './WebpackPlugins';
7 | export * as ModuleResolve from './ModuleResolve';
8 | export * as RuleIndex from './Resources/RuleIndex';
9 | export * as TreeShaking from './TreeShaking';
10 | export * as BundleDiff from './Resources/BundleDiff';
11 |
--------------------------------------------------------------------------------
/packages/components/src/typings/assetsDefinition.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png';
2 | declare module '*.jpg';
3 | declare module '*.svg';
4 | declare module '*.jpeg';
5 | declare module '*.gif';
6 | declare module '*.webp';
7 | declare module '*.ttf';
8 | declare module '*.woff';
9 | declare module '*.woff2';
10 | declare module '*.scss';
11 | declare module '*.less';
12 | declare module '*.css';
13 | declare module '*?__inline';
14 | declare module '*?__inline=true';
15 | declare module '*?__inline=false';
16 |
--------------------------------------------------------------------------------
/packages/components/src/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | interface Window {
2 | [key: string]: any;
3 | __RSDOCTOR__: any;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/components/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './data';
2 | export * from './file';
3 | export * from './hooks';
4 | export * from './loader';
5 | export * from './locale';
6 | export * from './manifest';
7 | export * from './request';
8 | export * from './routes';
9 | export * from './size';
10 | export * from './socket';
11 | export * from './storage';
12 | export * from './string';
13 | export * from './time';
14 | export * from './url';
15 | export * from './worker';
16 |
--------------------------------------------------------------------------------
/packages/components/src/utils/locale.ts:
--------------------------------------------------------------------------------
1 | import cn from 'antd/es/locale/zh_CN';
2 | import en from 'antd/es/locale/en_GB';
3 | import type { Locale } from 'antd/es/locale';
4 | import { Language } from '../constants';
5 |
6 | export function getLocale(locale: string): Locale {
7 | const res = locale === 'cn' || locale === 'zh-CN' ? cn : en;
8 | return res;
9 | }
10 |
11 | export function getLanguage(locale: string): Language {
12 | const res = locale === 'cn' || locale === 'zh' ? Language.Cn : Language.En;
13 | return res;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/components/src/utils/size.ts:
--------------------------------------------------------------------------------
1 | export function formatSize(bytes: number) {
2 | let res: string;
3 |
4 | if (bytes >= 1000000000) {
5 | res = `${(bytes / 1000000000).toFixed(2)} GB`;
6 | } else if (bytes >= 1000000) {
7 | res = `${(bytes / 1000000).toFixed(2)} MB`;
8 | } else if (bytes >= 1000) {
9 | res = `${(bytes / 1000).toFixed(2)} KB`;
10 | } else if (bytes > 1) {
11 | res = `${bytes} bytes`;
12 | } else if (bytes === 1) {
13 | res = `${bytes} byte`;
14 | } else {
15 | res = '0 bytes';
16 | }
17 | return res;
18 | }
19 |
20 | export function formatPercent(percent: number) {
21 | return `${+percent.toFixed(2)}%`;
22 | }
23 |
--------------------------------------------------------------------------------
/packages/components/src/utils/string.ts:
--------------------------------------------------------------------------------
1 | export function ensurePrefix(str: string, prefix: string): string {
2 | return str.slice(0, prefix.length) === prefix ? str : `${str}${prefix}`;
3 | }
4 |
5 | export function removePrefix(str: string, prefix: string): string {
6 | let res = str;
7 |
8 | while (res.slice(0, prefix.length) === prefix) {
9 | res = res.slice(prefix.length);
10 | }
11 |
12 | return res;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/components/src/utils/time.ts:
--------------------------------------------------------------------------------
1 | import { Time } from '@rsdoctor/utils/common';
2 |
3 | const { toFixedDigits, getUnit, formatCosts } = Time;
4 |
5 | export { toFixedDigits as toFixed, getUnit, formatCosts };
6 |
--------------------------------------------------------------------------------
/packages/components/src/utils/worker/index.ts:
--------------------------------------------------------------------------------
1 | export * from './utils';
2 | export * from './types';
3 | export * from './master';
4 | export * from './worker';
5 |
--------------------------------------------------------------------------------
/packages/components/src/utils/worker/master.ts:
--------------------------------------------------------------------------------
1 | import { CreateWorker } from './types';
2 | import { ChildWorker } from './worker';
3 |
4 | class Master {
5 | private _workerMap = new WeakMap();
6 |
7 | public detectWorker(create: CreateWorker) {
8 | if (this._workerMap.has(create)) return this._workerMap.get(create)!;
9 |
10 | const worker = create();
11 | const child = new ChildWorker(worker);
12 | this._workerMap.set(create, child);
13 |
14 | return child;
15 | }
16 | }
17 |
18 | export const master = new Master();
19 |
--------------------------------------------------------------------------------
/packages/components/src/utils/worker/types.ts:
--------------------------------------------------------------------------------
1 | export type CreateWorker = () => Worker;
2 |
3 | export type NativeWorkerMessage = MessageEvent>;
4 |
5 | export type WorkerMessage = {
6 | id: number | string;
7 | data: T;
8 | };
9 |
10 | export type InternalWorkerEventCallback = (message: WorkerMessage) => unknown;
11 |
12 | export type UserWorkerEventCallback = (data: T) => unknown;
13 |
14 | export type UserWorkerEventHandler = (data: T) => R | Promise;
15 |
--------------------------------------------------------------------------------
/packages/components/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "jsx": "react-jsx",
6 | "isolatedModules": true,
7 | "declaration": true,
8 | "declarationMap": false,
9 | "composite": true,
10 | "rootDir": "src",
11 | "outDir": "dist",
12 | "paths": {
13 | "src": ["./src"]
14 | }
15 | },
16 | "include": ["src"],
17 | "exclude": ["**/node_modules"],
18 | "references": [
19 | {
20 | "path": "../types/tsconfig.json"
21 | },
22 | {
23 | "path": "../utils/tsconfig.json"
24 | },
25 | {
26 | "path": "../graph/tsconfig.json"
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/packages/core/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/core
2 |
3 | This is the core package of Rsdoctor, providing core tools and analysis capabilities for Rsdoctor plugins.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/core/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { baseBuildConfig } from '../../scripts/modern.base.config';
2 |
3 | export default baseBuildConfig;
4 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/chunks/assetsModules.ts:
--------------------------------------------------------------------------------
1 | import {
2 | getAssetsModulesData as transform,
3 | ParsedModuleSizeData,
4 | } from '@/build-utils/common/chunks';
5 | import { parseBundle } from '../utils';
6 | import { SDK } from '@rsdoctor/types';
7 |
8 | export async function getAssetsModulesData(
9 | moduleGraph: SDK.ModuleGraphInstance,
10 | chunkGraph: SDK.ChunkGraphInstance,
11 | bundleDir: string,
12 | hasParseBundle = true,
13 | ): Promise {
14 | return transform(
15 | moduleGraph,
16 | chunkGraph,
17 | bundleDir,
18 | hasParseBundle ? { parseBundle } : {},
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/chunks/chunkTransform.ts:
--------------------------------------------------------------------------------
1 | import { Plugin } from '@rsdoctor/types';
2 | import { chunkTransform as transform } from '@/build-utils/common/chunks';
3 |
4 | export function chunkTransform(
5 | assetMap: Map,
6 | bundleStats: Plugin.StatsCompilation,
7 | ) {
8 | return transform(assetMap, bundleStats);
9 | }
10 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/chunks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './assetsModules';
2 | export * from './chunkTransform';
3 | export * from './generateTileGraph';
4 | export * from './rspack/transform';
5 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/index.ts:
--------------------------------------------------------------------------------
1 | export * as Chunks from './chunks';
2 | export * as Utils from './utils';
3 | export * as Loader from './loader';
4 | export * as Types from '../../types';
5 | export * as ModuleGraph from './module-graph';
6 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/loader/index.ts:
--------------------------------------------------------------------------------
1 | export * from './probeLoaderPlugin';
2 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/module-graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './webpack/transform';
2 | export * from './transform';
3 | export * from './treeShaking';
4 | export * from './rspack/transform';
5 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/build/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './loader';
2 | export * from './plugin';
3 | export * from './parseBundle';
4 | export * from '../loader/probeLoader';
5 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/common/chunks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './assetsModules';
2 | export * from './chunkTransform';
3 | export * from './assetsContent';
4 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/common/index.ts:
--------------------------------------------------------------------------------
1 | export * as Chunks from './chunks';
2 | export * as Types from '../../types';
3 | export * as ModuleGraph from './module-graph';
4 | export * as TransUtils from './trans-utils';
5 | export * as Webpack from './webpack/compatible';
6 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/common/module-graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './transform';
2 | export * from './compatible';
3 | export * from './utils';
4 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/common/trans-utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './transStats';
2 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/common/trans-utils/transStats.ts:
--------------------------------------------------------------------------------
1 | import { Plugin, SDK } from '@rsdoctor/types';
2 | import { Chunks, ModuleGraph } from '..';
3 |
4 | export async function transStats(json: Plugin.StatsCompilation) {
5 | const chunkGraph: SDK.ChunkGraphInstance = Chunks.chunkTransform(
6 | new Map(),
7 | json,
8 | );
9 | const moduleGraph = ModuleGraph.getModuleGraphByStats(json, '.', chunkGraph);
10 | const assetsModuleMap =
11 | (await Chunks.getAssetsModulesData(
12 | moduleGraph,
13 | chunkGraph,
14 | json.outputPath || '',
15 | {},
16 | )) || {};
17 | Chunks.transformAssetsModulesData(assetsModuleMap, moduleGraph);
18 | return { chunkGraph, moduleGraph };
19 | }
20 |
--------------------------------------------------------------------------------
/packages/core/src/build-utils/index.ts:
--------------------------------------------------------------------------------
1 | export * as Build from './build';
2 | export * as Common from './common';
3 |
--------------------------------------------------------------------------------
/packages/core/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './build-utils';
2 | export * as InnerPlugins from './inner-plugins';
3 | export * from './types';
4 |
--------------------------------------------------------------------------------
/packages/core/src/inner-plugins/constants.ts:
--------------------------------------------------------------------------------
1 | import type { Tap } from 'tapable';
2 |
3 | export const pluginTapName = 'RsdoctorWebpackPlugin';
4 |
5 | export const pluginTapPostOptions: Tap = {
6 | name: pluginTapName,
7 | stage: 999,
8 | };
9 |
10 | export const pluginTapPreOptions: Tap = {
11 | name: pluginTapName,
12 | stage: -999,
13 | };
14 |
15 | export const internalPluginTapPreOptions = (namespace: string): Tap => ({
16 | name: `${pluginTapName}:${namespace}`,
17 | stage: -998,
18 | });
19 |
20 | export const internalPluginTapPostOptions = (namespace: string): Tap => ({
21 | name: `${pluginTapName}:${namespace}`,
22 | stage: 1000,
23 | });
24 |
--------------------------------------------------------------------------------
/packages/core/src/inner-plugins/index.ts:
--------------------------------------------------------------------------------
1 | export * from './plugins';
2 | export * from './utils';
3 |
--------------------------------------------------------------------------------
/packages/core/src/inner-plugins/plugins/index.ts:
--------------------------------------------------------------------------------
1 | export * from './loader';
2 | export * from './plugins';
3 | export * from './errors';
4 | export * from './progress';
5 | export * from './summary';
6 | export * from './base';
7 | export * from './bundle';
8 | export * from './ensureModulesChunkGraph';
9 | export * from './rules';
10 | export * from './bundleTagPlugin';
11 |
--------------------------------------------------------------------------------
/packages/core/src/inner-plugins/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './loader';
2 | export * from './plugin';
3 | export * from './sdk';
4 | export * from './config';
5 | export * from './circleDetect';
--------------------------------------------------------------------------------
/packages/core/src/inner-plugins/utils/sdk.ts:
--------------------------------------------------------------------------------
1 | import { RsdoctorPrimarySDK, RsdoctorSDK } from '@rsdoctor/sdk';
2 |
3 | let sdks: RsdoctorSDK[] = [];
4 | let sdk: RsdoctorSDK;
5 |
6 | export function setSDK(t: RsdoctorSDK) {
7 | sdks.push(t);
8 | sdk = t;
9 | }
10 |
11 | export function getSDK(builderName?: string) {
12 | if (sdk && sdk.name !== builderName) {
13 | sdk = builderName ? sdks.find((s) => s.name === builderName) || sdk : sdk;
14 | }
15 | if (sdk && builderName && 'parent' in sdk) {
16 | const _sdk = sdk as RsdoctorPrimarySDK;
17 | const slaveSDK = _sdk.parent.slaves.find(
18 | (_sdk: { name: string }) => _sdk.name === builderName,
19 | );
20 | return slaveSDK || sdk;
21 | }
22 | return sdk;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/core/src/rules/index.ts:
--------------------------------------------------------------------------------
1 | export * from './linter';
2 | export * from './rule';
3 |
4 | export { rules } from './rules';
5 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/cross-chunks-package/types.ts:
--------------------------------------------------------------------------------
1 | export interface Config {
2 | ignore: string[];
3 | }
4 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/cross-chunks-package/utils.ts:
--------------------------------------------------------------------------------
1 | export function getErrorMsgForDupPckChunks(
2 | chunks: String[],
3 | pkgName: String,
4 | ): string {
5 | let message = `The same module of Package ${pkgName} was bundled into different chunks:\n`;
6 |
7 | for (const chunkName of chunks) {
8 | message += ` ${chunkName}\n`;
9 | }
10 |
11 | return message.slice(0, -1);
12 | }
13 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/default-import-check/types.ts:
--------------------------------------------------------------------------------
1 | export interface Config {
2 | /** Packages that need to be ignored */
3 | ignore: string[];
4 | }
5 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/ecma-version-check/types.ts:
--------------------------------------------------------------------------------
1 | import type { PluginCheckSyntaxOptions } from '@rsbuild/plugin-check-syntax';
2 |
3 | export interface Config extends PluginCheckSyntaxOptions {}
4 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/ecma-version-check/utils.ts:
--------------------------------------------------------------------------------
1 | import type { ECMAVersion } from '@rsdoctor/utils/ruleUtils';
2 |
3 | export function getVersionNumber(ECMAString: ECMAVersion) {
4 | const version = ECMAString.match(/\d/);
5 |
6 | return version?.length ? Number(version[0]) : undefined;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/index.ts:
--------------------------------------------------------------------------------
1 | import { rule as duplicatePackage } from './duplicate-package';
2 | import { rule as defaultImportCheck } from './default-import-check';
3 | import { rule as loaderPerformanceOptimization } from './loader-performance-optimization';
4 | import { rule as ecmaVersionCheck } from './ecma-version-check';
5 | import { rule as crossChunksPackage } from './cross-chunks-package';
6 |
7 | export const rules = [
8 | duplicatePackage,
9 | defaultImportCheck,
10 | loaderPerformanceOptimization,
11 | ecmaVersionCheck,
12 | crossChunksPackage,
13 | ];
14 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/loader-performance-optimization/types.ts:
--------------------------------------------------------------------------------
1 | import type { SDK } from '@rsdoctor/types';
2 |
3 | export interface Config {
4 | /**
5 | * loaders which should be ignore.
6 | */
7 | ignore?: (string | RegExp)[];
8 | /**
9 | * threshold which the loader total costs.
10 | * @unit millisecond
11 | * @default 5000
12 | */
13 | threshold?: number;
14 | /**
15 | * the file extensions which will be match in rule check.
16 | * @default ["js", "css", "jpg", "jpeg", "png", "gif", "webp", "svg"]
17 | */
18 | extensions?: (string | RegExp)[];
19 | }
20 |
21 | export interface LoaderMapValue extends SDK.LoaderTransformData {
22 | __resource__: SDK.ResourceData;
23 | __costs__: number;
24 | }
25 |
--------------------------------------------------------------------------------
/packages/core/src/rules/rules/loader-performance-optimization/utils.ts:
--------------------------------------------------------------------------------
1 | export function match(str: string, patterns: (string | RegExp)[]) {
2 | if (patterns.length === 0) return false;
3 |
4 | return patterns.some((p) => {
5 | if (typeof p === 'string') return str === p;
6 | if (p instanceof RegExp) return p.test(str);
7 | return false;
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/packages/core/src/rules/utils.ts:
--------------------------------------------------------------------------------
1 | import { Linter } from '@rsdoctor/types';
2 |
3 | export function toSeverity(
4 | input: Linter.SeverityInput,
5 | defaultLevel: Linter.Severity,
6 | ): Linter.Severity {
7 | if (input === 'off') {
8 | return Linter.Severity.Ignore;
9 | }
10 |
11 | if (input === 'on') {
12 | return defaultLevel;
13 | }
14 |
15 | const key = `${input[0].toUpperCase()}${input.slice(
16 | 1,
17 | )}` as Linter.SeverityString;
18 | return Linter.Severity[key] as Linter.Severity;
19 | }
20 |
21 | export function noop() {}
22 |
--------------------------------------------------------------------------------
/packages/core/src/types/chunks.ts:
--------------------------------------------------------------------------------
1 | import { Plugin, SDK } from '@rsdoctor/types';
2 |
3 | export type AssetsModules = {
4 | label?: string;
5 | isAsset?: boolean;
6 | modules?: Plugin.StatsModule[];
7 | };
8 |
9 | export type ParseBundle = (
10 | assetFile: string,
11 | modules: Pick[],
12 | ) => {
13 | modules?: Record;
14 | src?: string;
15 | runtimeSrc?: string;
16 | };
17 |
--------------------------------------------------------------------------------
/packages/core/src/types/declare.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'webpack-bundle-analyzer/lib/viewer' {
2 | export function generateReport(bundleStats: any, opts: any): Promise;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/core/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chunks';
2 | export * from './rules';
3 | export * from './webpack';
4 | export * from './loader';
5 | export * from './plugin';
6 |
--------------------------------------------------------------------------------
/packages/core/src/types/loader.ts:
--------------------------------------------------------------------------------
1 | import { Loader } from '@rsdoctor/utils/common';
2 |
3 | export interface ProxyLoaderInternalOptions {
4 | cwd: string;
5 | /**
6 | * the url host of http server(which used to collect data).
7 | */
8 | host: string;
9 | /**
10 | * correct loader path.
11 | */
12 | loader: string;
13 | /** include the loader option */
14 | hasOptions: boolean;
15 | skipLoaders: string[];
16 | }
17 |
18 | export interface ProxyLoaderOptions {
19 | [key: string]: any;
20 | [Loader.LoaderInternalPropertyName]: ProxyLoaderInternalOptions;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/core/src/types/rules.ts:
--------------------------------------------------------------------------------
1 | import { RuleSetRule } from 'webpack';
2 |
3 | export interface Rule extends RuleSetRule {
4 | /**
5 | * https://webpack.js.org/configuration/module/#ruleloaders
6 | */
7 | loaders: RuleSetRule['use'];
8 | }
9 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/bundles/validBundleWithArrowFunction.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([0],[(t,e,r)=>{
2 | console.log('Hello world!');
3 | }]);
4 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/bundles/validBundleWithArrowFunction.modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "modules": {
3 | "0": {
4 | "size": 43,
5 | "sizeConvert": "43 B",
6 | "content": "(t,e,r)=>{\n console.log('Hello world!');\n}"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/bundles/validBundleWithEsNextFeatures.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([2],[function(t,e,r){
2 | async function asyncFn() {
3 | return await Promise.resolve(1);
4 | }
5 |
6 | const arrowFn = arg => arg * 2;
7 |
8 | function* generatorFn() {
9 | yield 1;
10 | }
11 |
12 | class TestClass {
13 | static staticMethod() {}
14 | constructor() {}
15 | testMethod() {}
16 | }
17 |
18 | for (const i of [1, 2, 3]) {
19 | console.log(i);
20 | }
21 |
22 | let obj = {
23 | ['a' + 'b']: 1,
24 | func() {}
25 | };
26 |
27 | const [var1, var2] = [1, 2];
28 | }]);
29 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/bundles/validBundleWithEsNextFeatures.modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "modules": {
3 | "0": {
4 | "content": "function(t,e,r){\n async function asyncFn() {\n return await Promise.resolve(1);\n }\n\n const arrowFn = arg => arg * 2;\n\n function* generatorFn() {\n yield 1;\n }\n\n class TestClass {\n static staticMethod() {}\n constructor() {}\n testMethod() {}\n }\n\n for (const i of [1, 2, 3]) {\n console.log(i);\n }\n\n let obj = {\n ['a' + 'b']: 1,\n func() {}\n };\n\n const [var1, var2] = [1, 2];\n}",
5 | "size": 406,
6 | "sizeConvert": "406 B"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/bundles/validCommonBundleWithModulesAsArray.modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "modules": {
3 | "0": {
4 | "size": 95,
5 | "sizeConvert": "95 B",
6 | "content": "function(e,t,n){n(1),n(21),n(96),n(306),n(23),n(150),n(57),n(56),n(34),n(138),e.exports=n(348)}"
7 | },
8 | "5": {
9 | "size": 15,
10 | "sizeConvert": "15 B",
11 | "content": "function(e,t){}"
12 | },
13 | "33": {
14 | "size": 46,
15 | "sizeConvert": "46 B",
16 | "content": "function(e,t,n){\"use strict\";e.exports=n(680)}"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/core/tests/build/utils/loader/basic.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest';
2 | import { extractLoaderName } from '@/build-utils/build/utils';
3 |
4 | describe('test src/build/utils/loader.ts basic functions', () => {
5 | it('extractLoaderName()', () => {
6 | expect(extractLoaderName('cache-loader')).toEqual('cache-loader');
7 | expect(
8 | extractLoaderName('/Users/node_modules/cache-loader/lib/index.js'),
9 | ).toEqual('cache-loader');
10 | expect(
11 | extractLoaderName('/Users/node_modules/cache-loader/lib/loader.js'),
12 | ).toEqual('cache-loader/lib/loader');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/packages/core/tests/common/utils.ts:
--------------------------------------------------------------------------------
1 | import { relative } from 'path';
2 | import { SDK } from '@rsdoctor/types';
3 | export function removeAbsModulePath(
4 | graph: SDK.ModuleGraphInstance,
5 | root: string,
6 | ) {
7 | for (const mod of graph.getModules()) {
8 | (mod as any).path = relative(root, mod.path);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/expression/index.js:
--------------------------------------------------------------------------------
1 | import utils from './utils';
2 |
3 | console.log(utils);
4 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/expression/utils.js:
--------------------------------------------------------------------------------
1 | const a = 0;
2 |
3 | export const ab = 123;
4 |
5 | export default a + 1;
6 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/literal/index.js:
--------------------------------------------------------------------------------
1 | import utils from './utils';
2 |
3 | console.log(utils);
4 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/literal/utils.js:
--------------------------------------------------------------------------------
1 | export default 'utils';
2 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/variable/index.js:
--------------------------------------------------------------------------------
1 | import utils from './utils';
2 |
3 | console.log(utils);
4 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/default-export/variable/utils.js:
--------------------------------------------------------------------------------
1 | const abc = 123;
2 |
3 | export const abcd = 1234;
4 |
5 | export default abc;
6 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/basic-loader-esm.js:
--------------------------------------------------------------------------------
1 | Object.defineProperty(exports, '__esModule', { value: true });
2 |
3 | exports.default = loader;
4 |
5 | function loader(code) {
6 | return code;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/basic-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = loader;
2 |
3 | function loader(code) {
4 | return code;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/pitch-loader-esm.js:
--------------------------------------------------------------------------------
1 | Object.defineProperty(exports, '__esModule', { value: true });
2 |
3 | exports.default = loader;
4 |
5 | exports.default.pitch = pitch;
6 |
7 | function loader(code) {
8 | return code;
9 | }
10 |
11 | function pitch() {
12 | return 'pitch';
13 | }
14 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/pitch-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = loader;
2 |
3 | module.exports.pitch = pitch;
4 |
5 | function loader(code) {
6 | return code;
7 | }
8 |
9 | function pitch() {
10 | return 'pitch';
11 | }
12 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/raw-loader-esm.js:
--------------------------------------------------------------------------------
1 | Object.defineProperty(exports, '__esModule', { value: true });
2 |
3 | exports.default = loader;
4 |
5 | exports.default.raw = true;
6 |
7 | function loader(code) {
8 | return code;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/loaders/raw-loader.js:
--------------------------------------------------------------------------------
1 | module.exports = loader;
2 |
3 | module.exports.raw = true;
4 |
5 | function loader(code) {
6 | return code;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/normal-module-in-multi-concatenation/common.js:
--------------------------------------------------------------------------------
1 | export const key1 = 'key1';
2 | export const key2 = 'key2';
3 | export const key3 = 'key3';
4 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/normal-module-in-multi-concatenation/entry1.js:
--------------------------------------------------------------------------------
1 | import { key1, key3 } from './common';
2 |
3 | console.log(key1);
4 | console.log(key3);
5 |
--------------------------------------------------------------------------------
/packages/core/tests/fixtures/normal-module-in-multi-concatenation/entry2.js:
--------------------------------------------------------------------------------
1 | import { key2, key3 } from './common';
2 |
3 | console.log(key2);
4 | console.log(key3);
5 |
--------------------------------------------------------------------------------
/packages/core/tests/plugins/__snapshots__/circle-check.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`test checkCirclePath function > makeRulesSerializable() 1`] = `
4 | [
5 | [
6 | "foo",
7 | "a",
8 | ],
9 | [
10 | "foo",
11 | "x",
12 | "foo",
13 | ],
14 | ]
15 | `;
16 |
17 | exports[`test checkCirclePath function > makeRulesSerializable() 2`] = `
18 | {
19 | "a": {
20 | "b": "b",
21 | },
22 | "foo": "[Circular]",
23 | }
24 | `;
25 |
--------------------------------------------------------------------------------
/packages/core/tests/plugins/__snapshots__/config.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`test src/utils/config.ts > makeRulesSerializable() 1`] = `
4 | "[
5 | {
6 | \\"test\\": \\"/rule1/\\"
7 | },
8 | {
9 | \\"test\\": \\"/rule2/\\",
10 | \\"oneOf\\": [
11 | {
12 | \\"test\\": \\"/oneof1/\\"
13 | },
14 | {
15 | \\"test\\": \\"aaa\\"
16 | }
17 | ],
18 | \\"exclude\\": {
19 | \\"and\\": [
20 | \\"/exclude_and1/\\",
21 | \\"/exclude_and2/\\"
22 | ],
23 | \\"or\\": [
24 | \\"/exclude_or/\\"
25 | ],
26 | \\"not\\": \\"/exclude_not/\\"
27 | }
28 | }
29 | ]"
30 | `;
31 |
--------------------------------------------------------------------------------
/packages/core/tests/plugins/fixtures/a.js:
--------------------------------------------------------------------------------
1 | console.log('a');
2 |
--------------------------------------------------------------------------------
/packages/core/tests/plugins/fixtures/b.js:
--------------------------------------------------------------------------------
1 | const ll = 1;
2 |
3 | console.log('a');
4 |
5 | function kk() {
6 | console.log('hhe: ', ll);
7 | return '111';
8 | }
9 |
10 | kk();
11 |
--------------------------------------------------------------------------------
/packages/core/tests/plugins/fixtures/loaders/serialize-query-to-comment.js:
--------------------------------------------------------------------------------
1 | const { parseQuery } = require('loader-utils');
2 |
3 | /**
4 | * @type {import("webpack").LoaderDefinitionFunction<{}, {}>}
5 | */
6 | module.exports = function (input) {
7 | const res = [input, `// ${JSON.stringify(this.query)}`];
8 |
9 | // Based on https://github.com/windicss/windicss-webpack-plugin/blob/main/src/loaders/windicss-template.ts#L42
10 | // test the loader query
11 | if (this.query !== '') {
12 | res.push(`// ${JSON.stringify(parseQuery(this.query))}`);
13 | }
14 |
15 | return res.join('\n');
16 | };
17 |
--------------------------------------------------------------------------------
/packages/core/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "paths": {
6 | "@/*": ["../src/*"],
7 | }
8 | },
9 | "include": ["./**/*.ts"],
10 | "exclude": ["../**/node_modules"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "experimentalDecorators": true,
5 | "outDir": "./dist",
6 | "baseUrl": "./",
7 | "paths": {
8 | "@/*": ["./src/*"]
9 | },
10 | "rootDir": "src"
11 | },
12 | "include": ["src"],
13 | "exclude": ["**/node_modules"],
14 | "references": [
15 | {
16 | "path": "../types/tsconfig.json"
17 | },
18 | {
19 | "path": "../utils/tsconfig.json"
20 | },
21 | {
22 | "path": "../graph/tsconfig.json"
23 | },
24 | {
25 | "path": "../sdk/tsconfig.json"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/packages/document/README.md:
--------------------------------------------------------------------------------
1 | # Rsdoctor website
2 |
3 | ## Writing style guide
4 |
5 | The same as Rspack: [Writing style guide](https://github.com/web-infra-dev/rspack/tree/main/website#writing-style-guide).
6 |
--------------------------------------------------------------------------------
/packages/document/docs/en/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Guide",
4 | "link": "/guide/start/intro",
5 | "activeMatch": "/guide/"
6 | },
7 | {
8 | "text": "Config",
9 | "link": "/config/options/options",
10 | "activeMatch": "/config/"
11 | },
12 | {
13 | "text": "Blog",
14 | "link": "/blog/release/release-note-1_0",
15 | "activeMatch": "/blog/"
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/packages/document/docs/en/blog/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "release",
5 | "label": "Release Note"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "topic",
10 | "label": "Topic"
11 | }
12 | ]
13 |
--------------------------------------------------------------------------------
/packages/document/docs/en/blog/release/_meta.json:
--------------------------------------------------------------------------------
1 | ["release-note-1_0", "release-note-0_4", "release-note-0_3", "release-note-0_1"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/blog/topic/_meta.json:
--------------------------------------------------------------------------------
1 | ["loader-optimization", "duplicate-pkg-problem"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/config/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "options",
5 | "label": "Config Instruction"
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/packages/document/docs/en/config/options/_meta.json:
--------------------------------------------------------------------------------
1 | ["options", "term"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/config/options/term.mdx:
--------------------------------------------------------------------------------
1 | # Terminology
2 |
3 | ## Common terminology
4 |
5 | ### manifest.json
6 |
7 | When your project integrates with plugins provided by **Rsdoctor** (such as `@rsdoctor/webpack-plugin`, etc.), Rsdoctor will write **build-related data information** into a local JSON file:
8 |
9 | - The **filename is `manifest.json`**
10 | - The output path of this file is `output directory of the project/.rsdoctor/manifest.json`
11 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "start",
5 | "label": "Getting Started"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "usage",
10 | "label": "Usage"
11 | },
12 | {
13 | "type": "dir",
14 | "name": "rules",
15 | "label": "Scan Rules"
16 | },
17 | {
18 | "type": "dir",
19 | "name": "more",
20 | "label": "More"
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/more/_meta.json:
--------------------------------------------------------------------------------
1 | ["faq", "rules"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/more/rules.mdx:
--------------------------------------------------------------------------------
1 | # Rule index
2 |
3 | import RuleIndex from '@components/RuleIndex';
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/rules/_meta.json:
--------------------------------------------------------------------------------
1 | ["rules", "rule-custom", "upload-data"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/start/_meta.json:
--------------------------------------------------------------------------------
1 | ["intro", "quick-start", "features", "cicd", "cli"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/en/guide/usage/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | "project-overall",
3 | "bundle-overall",
4 | "compile-overall",
5 | "compile-alerts",
6 | "bundle-alerts",
7 | "loaders-timeline",
8 | "loaders-analysis",
9 | "plugins-analysis",
10 | "bundle-size",
11 | "module-analysis",
12 | "resolver",
13 | "rule-config",
14 | "bundle-diff"
15 | ]
16 |
--------------------------------------------------------------------------------
/packages/document/docs/en/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageType: home
3 | titleSuffix: ' - Build Analyzer'
4 | ---
5 |
--------------------------------------------------------------------------------
/packages/document/docs/en/shared/features-rspack.md:
--------------------------------------------------------------------------------
1 | ```ts
2 | interface RsdoctorRspackPluginFeatures {
3 | /**
4 | * turn off it if you need not to analyze the executions of webpack loaders.
5 | * @default true
6 | */
7 | loader?: boolean;
8 | /**
9 | * turn off it if you need not to analyze the executions of webpack plugins.
10 | * @default true
11 | */
12 | plugins?: boolean;
13 | /**
14 | * turn off it if you need not to analyze the output bundle.
15 | * @default true
16 | */
17 | bundle?: boolean;
18 | /**
19 | * turn on it if you just use lite mode. This mode do not have source codes.
20 | * @default false
21 | * @deprecated
22 | */
23 | lite?: boolean;
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/packages/document/docs/public/netlify.toml:
--------------------------------------------------------------------------------
1 | # Redirect rsdoctor.dev to rsdoctor.rs
2 | [[redirects]]
3 | from = "https://rsdoctor.dev/*"
4 | to = "https://rsdoctor.rs/:splat"
5 | status = 301
6 | force = true
7 |
8 | [[redirects]]
9 | from = "/*"
10 | to = "/404.html"
11 | status = 404
12 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "指南",
4 | "link": "/guide/start/intro",
5 | "activeMatch": "/guide/"
6 | },
7 | {
8 | "text": "配置",
9 | "link": "/config/options/options",
10 | "activeMatch": "/config/"
11 | },
12 | {
13 | "text": "博客",
14 | "link": "/blog/release/release-note-1_0",
15 | "activeMatch": "/blog/"
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/blog/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "release",
5 | "label": "Release 公告"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "topic",
10 | "label": "专题"
11 | }
12 | ]
13 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/blog/release/_meta.json:
--------------------------------------------------------------------------------
1 | ["release-note-1_0", "release-note-0_4", "release-note-0_3", "release-note-0_1"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/blog/topic/_meta.json:
--------------------------------------------------------------------------------
1 | ["loader-optimization", "duplicate-pkg-problem"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/config/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "options",
5 | "label": "配置说明"
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/config/options/_meta.json:
--------------------------------------------------------------------------------
1 | ["options", "term"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/config/options/term.mdx:
--------------------------------------------------------------------------------
1 | # 术语
2 |
3 | ## 通用术语
4 |
5 | ### manifest.json
6 |
7 | 当你的项目集成 **Rsdoctor** 提供的插件(比如 `@rsdoctor/webpack-plugin` 等)之后,Rsdoctor 会将项目**构建相关的数据信息**写入到一个本地的 JSON 文件中:
8 |
9 | - 其**文件名为 `manifest.json`**
10 | - 该文件的输出**路径为 `项目产物目录/.rsdoctor/manifest.json`**
11 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "start",
5 | "label": "快速开始"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "usage",
10 | "label": "功能介绍"
11 | },
12 | {
13 | "type": "dir",
14 | "name": "rules",
15 | "label": "扫描规则"
16 | },
17 | {
18 | "type": "dir",
19 | "name": "more",
20 | "label": "更多"
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/more/_meta.json:
--------------------------------------------------------------------------------
1 | ["faq", "rules"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/more/rules.mdx:
--------------------------------------------------------------------------------
1 | # Rule index
2 |
3 | import RuleIndex from '@components/RuleIndex';
4 |
5 |
6 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/rules/_meta.json:
--------------------------------------------------------------------------------
1 | ["rules", "rule-custom", "upload-data"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/start/_meta.json:
--------------------------------------------------------------------------------
1 | ["intro", "quick-start", "features", "cicd", "cli"]
2 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/start/quick-start.mdx:
--------------------------------------------------------------------------------
1 | # 快速开始
2 |
3 | 本文档将介绍如何接入 Rsdoctor 能力。
4 |
5 | ## 第一步:安装依赖
6 |
7 | import { PackageManagerTabs } from '@theme';
8 |
9 | ### Rspack 项目
10 |
11 | 基于 Rspack 或 Rsbuild 的项目,安装以下依赖:
12 |
13 |
14 |
15 | ### Webpack 项目
16 |
17 | :::tip
18 | Rsdoctor 仅支持 webpack >= 5。
19 | :::
20 |
21 | 基于 webpack 的项目,安装以下依赖:
22 |
23 |
24 |
25 | ---
26 |
27 | import QuickStartShared from './quick-start-shared.mdx';
28 |
29 |
30 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/usage/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | "project-overall",
3 | "bundle-overall",
4 | "compile-overall",
5 | "compile-alerts",
6 | "bundle-alerts",
7 | "loaders-timeline",
8 | "loaders-analysis",
9 | "plugins-analysis",
10 | "bundle-size",
11 | "module-analysis",
12 | "resolver",
13 | "rule-config",
14 | "bundle-diff"
15 | ]
16 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/usage/bundle-alerts.mdx:
--------------------------------------------------------------------------------
1 | # 产物预警
2 |
3 | ## 功能介绍
4 |
5 | Overall 页面中的 `Alerts` 部分用于展示「构建规则」及「编译规则」结果,如下图。规则展示除了展示在页面中,还会展示在终端日志中。
6 |
7 |
8 |
9 | 可以查看下方的产物预警内置规则了解各个规则详情。
10 |
11 | ### 内置规则
12 |
13 | 1. [[E1001] Duplicate Packages](../../guide/rules/rules#e1001-duplicate-packages)
14 | 2. [[E1002] Cross Chunks Package](../../guide/rules/rules#e1002-cross-chunks-package)
15 | 3. [[E1004] ECMA Version Check](../../guide/rules/rules#e1004-ecma-version-check)
16 |
17 | 具体可以查看[内置规则](../../guide/rules/rules)。
18 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/guide/usage/compile-alerts.mdx:
--------------------------------------------------------------------------------
1 | # 编译预警
2 |
3 | 我们还集成了一些基于编译数据做检测的能力,如果本次编译结果中,存在命中了我们定义的[规则](../more/rules)的数据,则会在 **Rsdoctor** 主界面下方出现 `Compile Alerts` 模块,参考下图所示:
4 |
5 |
6 |
7 | 通过该模块可以比较直观的看到我们项目在编译方面的一些预警信息,有助于我们可以更进一步优化项目的编译性能。
8 |
9 | ## 规则
10 |
11 | 目前编译规则有:
12 |
13 | :::tip
14 | [规则列表](../more/rules)
15 | :::
16 |
17 | - `E1003` Loader 性能检查。[[E1003] Loader Performance Optimization](/guide/rules/rules#e1003-loader-performance-optimization)
18 | - `E1005` 默认导入检查。[[E1005] Default Import Check](/guide/rules/rules#e1005-default-import-check)
19 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageType: home
3 | titleSuffix: ' - 构建分析工具'
4 | ---
5 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/shared/features-rspack.md:
--------------------------------------------------------------------------------
1 | ```ts
2 | interface RsdoctorRspackPluginFeatures {
3 | /**
4 | * turn off it if you need not to analyze the executions of webpack loaders.
5 | * @default true
6 | */
7 | loader?: boolean;
8 | /**
9 | * turn off it if you need not to analyze the executions of webpack plugins.
10 | * @default true
11 | */
12 | plugins?: boolean;
13 | /**
14 | * turn off it if you need not to analyze the output bundle.
15 | * @default true
16 | */
17 | bundle?: boolean;
18 | /**
19 | * turn on it if you just use lite mode. This mode do not have source codes.
20 | * @default false
21 | * @deprecated
22 | */
23 | lite?: boolean;
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/packages/document/docs/zh/shared/mode-intro.md:
--------------------------------------------------------------------------------
1 | - **normal 模式:** 在构建产物目录中生成一个 `.rsdoctor` 文件夹,其中包含各种数据文件,并在报告页面中展示代码。输出目录可以通过 [reportDir](/config/options/options#reportdir) 进行配置。
2 |
3 | - **brief 模式:** 在构建产物目录的 `.rsdoctor` 文件夹中生成一个 HTML 报告文件,所有构建分析数据会整合注入到这个 HTML 文件中,可以通过浏览器打开该 HTML 文件查看报告。brief 模式还有更多配置项,详细信息请参阅:[brief](/config/options/options#brief).
4 |
5 | - **lite 模式:** 基于普通模式,不展示源码和产物代码,仅显示打包后的代码信息。
6 |
--------------------------------------------------------------------------------
/packages/document/theme/components/Copyright.module.scss:
--------------------------------------------------------------------------------
1 | @media (min-width: 640px) {
2 | .copyRight {
3 | padding: 2rem;
4 | }
5 | }
6 |
7 | .copyRight {
8 | bottom: 0;
9 | margin-top: 6rem;
10 | padding-top: 2rem;
11 | padding-bottom: 2rem;
12 | padding-left: 1.5rem;
13 | padding-right: 1.5rem;
14 |
15 | width: 100%;
16 | border-top: 1px solid var(--rp-c-divider-light);
17 | }
18 |
19 | .copyRightInner {
20 | margin: 0 auto;
21 | width: 100%;
22 | text-align: center;
23 | }
24 |
25 | .copyRightText {
26 | font-weight: 400;
27 | font-size: 0.875rem;
28 | color: var(--rp-c-text-2);
29 | }
30 |
--------------------------------------------------------------------------------
/packages/document/theme/components/Copyright.tsx:
--------------------------------------------------------------------------------
1 | import styles from './Copyright.module.scss';
2 |
3 | export const CopyRight = () => {
4 | return (
5 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/packages/document/theme/components/Features.module.scss:
--------------------------------------------------------------------------------
1 | :global {
2 | .max-w-6xl.flex.m-auto {
3 | max-width: 1200px;
4 | }
5 | html.dark {
6 | --rp-home-feature-bg: linear-gradient(
7 | 135deg,
8 | rgba(255, 255, 255, 0),
9 | rgba(255, 255, 255, 0.03)
10 | );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/document/theme/components/Hero.module.scss:
--------------------------------------------------------------------------------
1 | :global {
2 | .rs-oval {
3 | width: 70% !important;
4 | height: 70% !important;
5 | top: calc(50% + 20px) !important;
6 | left: calc(50% + 5px) !important;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/document/theme/components/NextSteps.module.scss:
--------------------------------------------------------------------------------
1 | .next-steps {
2 | display: flex;
3 | flex-wrap: wrap;
4 | justify-content: space-between;
5 | margin-top: 3rem;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/document/theme/components/NextSteps.tsx:
--------------------------------------------------------------------------------
1 | import styles from './NextSteps.module.scss';
2 |
3 | const NextSteps = (props: { children?: React.ReactNode }) => {
4 | return {props.children}
;
5 | };
6 |
7 | export default NextSteps;
8 |
--------------------------------------------------------------------------------
/packages/document/theme/components/Step.tsx:
--------------------------------------------------------------------------------
1 | import { useUrl } from '../utils';
2 | import styles from './Step.module.scss';
3 |
4 | const Step = (props: { href: string; title: string; description: string }) => {
5 | return (
6 |
7 | {props.title}
8 | {props.description}
9 |
10 | );
11 | };
12 |
13 | export default Step;
14 |
--------------------------------------------------------------------------------
/packages/document/theme/components/ToolStack.tsx:
--------------------------------------------------------------------------------
1 | import { containerStyle } from '@rstack-dev/doc-ui/section-style';
2 | import { ToolStack as BaseToolStack } from '@rstack-dev/doc-ui/tool-stack';
3 | import { useLang } from 'rspress/runtime';
4 |
5 | export function ToolStack() {
6 | const lang = useLang();
7 | return (
8 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/packages/document/theme/components/utils.ts:
--------------------------------------------------------------------------------
1 | import { useCallback } from 'react';
2 | import { useLang, usePageData, withBase } from 'rspress/runtime';
3 |
4 | export function useI18nUrl() {
5 | const lang = useLang();
6 | const {
7 | siteData: { lang: defaultLang },
8 | } = usePageData();
9 | return useCallback(
10 | (url: string) => withBase(lang === defaultLang ? url : `/${lang}${url}`),
11 | [lang, defaultLang],
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/packages/document/theme/global.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.module.scss' {
2 | const classes: { readonly [key: string]: string };
3 | export default classes;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/document/theme/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --rp-c-brand: #ff5e00;
3 | --rp-c-brand-dark: #ff704d;
4 | --rp-c-brand-darker: #ff704d;
5 | --rp-c-brand-light: #ff7524;
6 | --rp-c-brand-lighter: #ff7524;
7 | --rp-c-link: var(--rp-c-brand);
8 | --rp-c-brand-tint: rgba(255, 94, 0, 0.07);
9 | }
10 |
11 | .dark {
12 | --rp-c-link: var(--rp-c-brand-light);
13 | }
14 |
15 | button:focus,
16 | button:focus-visible {
17 | outline: none;
18 | }
19 |
20 | [disabled] {
21 | cursor: not-allowed;
22 | }
23 |
24 | [role='tablist'] {
25 | max-width: 100vw;
26 | padding: 0 10px;
27 | }
28 |
--------------------------------------------------------------------------------
/packages/document/theme/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { BackgroundImage } from '@rstack-dev/doc-ui/background-image';
2 | import { CopyRight } from '../components/Copyright';
3 | import { Hero } from '../components/Hero';
4 | import { Features } from '../components/Features';
5 | import { ToolStack } from '../components/ToolStack';
6 |
7 | export function HomeLayout() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/packages/document/theme/types.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.module.scss' {
2 | const classes: { [key: string]: string };
3 | export default classes;
4 | }
5 |
6 | declare module '*.png' {
7 | const value: string;
8 | export default value;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/document/theme/utils.ts:
--------------------------------------------------------------------------------
1 | import { useLang, withBase, usePageData } from 'rspress/runtime';
2 |
3 | export function useUrl(url: string) {
4 | const lang = useLang();
5 | const {
6 | siteData: { lang: defaultLang },
7 | } = usePageData();
8 | return withBase(lang === defaultLang ? url : `/${lang}${url}`);
9 | }
10 |
--------------------------------------------------------------------------------
/packages/document/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "jsx": "react-jsx",
6 | "isolatedModules": true,
7 | "declaration": true,
8 | "composite": true,
9 | "outDir": "dist",
10 | "paths": {
11 | "@zh/*": ["./docs/zh/*"],
12 | "@en/*": ["./docs/en/*"],
13 | "@components/*": ["./theme/components/*"],
14 | "i18n": ["./i18n.json"]
15 | }
16 | },
17 | "mdx": {
18 | "checkMdx": true
19 | },
20 | "include": ["src", "theme", "i18n.json"],
21 | "exclude": ["**/node_modules"],
22 | "references": [
23 | {
24 | "path": "../types/tsconfig.json"
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/packages/graph/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/graph
2 |
3 | This package is the intermediate data layer of Rsdoctor.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/graph/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { configWithEsm } from '../../scripts/modern.base.config';
2 |
3 | export default configWithEsm;
4 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/chunk-graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chunk';
2 | export * from './graph';
3 | export * from './asset';
4 | export * from './entrypoint';
5 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './chunk-graph';
2 | export * from './module-graph';
3 | export * from './package-graph';
4 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/module-graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './dependency';
2 | export * from './module';
3 | export * from './graph';
4 | export * from './statement';
5 | export * from './tree-shaking';
6 | export * from './types';
7 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/module-graph/tree-shaking/index.ts:
--------------------------------------------------------------------------------
1 | export * from './module';
2 | export * from './export';
3 | export * from './variable';
4 | export * from './sideEffect';
5 | export * from './types';
6 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/module-graph/tree-shaking/types.ts:
--------------------------------------------------------------------------------
1 | import type { SDK } from '@rsdoctor/types';
2 |
3 | export type ExportData = SDK.ExportData;
4 | export type ModuleGraphModuleData = SDK.ModuleGraphModuleData;
5 | export type SideEffectData = SDK.SideEffectData;
6 | export type VariableData = SDK.VariableData;
7 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/module-graph/types.ts:
--------------------------------------------------------------------------------
1 | import type { SDK } from '@rsdoctor/types';
2 |
3 | export type ModuleBuildMeta = SDK.ModuleBuildMeta;
4 | export type ModuleSize = SDK.ModuleSize;
5 | export type ModuleSource = SDK.ModuleSource;
6 | export type DependencyBuildMeta = SDK.DependencyBuildMeta;
7 | export type SourcePosition = SDK.SourcePosition;
8 | export type SourceRange = SDK.SourceRange;
9 | export type StatementPosition = SDK.StatementPosition;
10 | export type ModuleData = SDK.ModuleData;
11 | export type DependencyData = SDK.DependencyData;
12 | export type StatementData = SDK.StatementData;
13 | export type ModuleGraphData = SDK.ModuleGraphData;
14 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/package-graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './dependency';
2 | export * from './graph';
3 | export * from './package';
4 | export * from './types';
5 |
--------------------------------------------------------------------------------
/packages/graph/src/graph/package-graph/types.ts:
--------------------------------------------------------------------------------
1 | import type { SDK } from '@rsdoctor/types';
2 |
3 | export type PackageData = SDK.PackageData;
4 | export type PackageJSONData = SDK.PackageJSONData;
5 | export type PackageBasicData = SDK.PackageBasicData;
6 | export type PackageDependencyData = SDK.PackageDependencyData;
7 | export type GetPackageFile = SDK.GetPackageFile;
8 |
--------------------------------------------------------------------------------
/packages/graph/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './graph';
2 |
--------------------------------------------------------------------------------
/packages/graph/tests/__snapshots__/utils.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`readPackageJson util > readPackageJson util 1`] = `
4 | {
5 | "name": "@lodash/es",
6 | "private": true,
7 | "root": "/packages/graph/tests/fixture",
8 | "type": "module",
9 | "version": "0.1.0",
10 | }
11 | `;
12 |
--------------------------------------------------------------------------------
/packages/graph/tests/fixture/index/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/web-infra-dev/rsdoctor/4b7a0d6a991fa2c1affa09428fb50e2a1f742c5d/packages/graph/tests/fixture/index/index.js
--------------------------------------------------------------------------------
/packages/graph/tests/fixture/index/package.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/packages/graph/tests/fixture/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@lodash/es",
4 | "version": "0.1.0",
5 | "type": "module"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/graph/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import { beforeAll, afterAll, afterEach, beforeEach } from 'vitest';
2 | import { File, Server } from '@rsdoctor/utils/build';
3 | import { Common, SDK } from '@rsdoctor/types';
4 | import { request } from 'http';
5 | import { tmpdir } from 'os';
6 | import path from 'path';
7 |
--------------------------------------------------------------------------------
/packages/graph/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "experimentalDecorators": true,
5 | "noUnusedLocals": false,
6 | "outDir": "./dist",
7 | "baseUrl": "./",
8 | "paths": {
9 | "@/*": ["./src/*"]
10 | },
11 | "rootDir": "src"
12 | },
13 | "include": ["src"],
14 | "exclude": ["**/node_modules"],
15 | "references": [
16 | {
17 | "path": "../types/tsconfig.json"
18 | },
19 | {
20 | "path": "../utils/tsconfig.json"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/rspack-plugin
2 |
3 | An Rspack plugin for integrating Rsdoctor.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@modern-js/module-tools';
2 | import { baseBuildConfig } from '../../scripts/modern.base.config';
3 | import { merge } from 'lodash';
4 |
5 | const modernConfig = defineConfig({
6 | ...merge(baseBuildConfig, {
7 | buildConfig: { tsconfig: 'tsconfig.build.json' },
8 | }),
9 | });
10 |
11 | export default modernConfig;
12 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/src/constants.ts:
--------------------------------------------------------------------------------
1 | import type { Tap } from 'tapable';
2 |
3 | export const pluginTapName = 'RsdoctorRspackPlugin';
4 |
5 | export const pluginTapPostOptions: Tap = {
6 | name: pluginTapName,
7 | stage: 999,
8 | };
9 |
10 | export const pluginTapPreOptions: Tap = {
11 | name: pluginTapName,
12 | stage: -999,
13 | };
14 |
15 | export const internalPluginTapPreOptions = (namespace: string): Tap => ({
16 | name: `${pluginTapName}:${namespace}`,
17 | stage: -998,
18 | });
19 |
20 | export const internalPluginTapPostOptions = (namespace: string): Tap => ({
21 | name: `${pluginTapName}:${namespace}`,
22 | stage: 1000,
23 | });
24 |
25 | export const pkg = require('../package.json');
26 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './plugin';
2 | export * from './multiple';
3 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["src"],
4 | "exclude": ["**/node_modules"]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/rspack-plugin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "outDir": "./dist",
6 | "rootDir": "src"
7 | },
8 | "include": ["src"],
9 | "exclude": ["**/node_modules"],
10 | "references": [
11 | {
12 | "path": "../core/tsconfig.json"
13 | },
14 | {
15 | "path": "../graph/tsconfig.json"
16 | },
17 | {
18 | "path": "../sdk/tsconfig.json"
19 | },
20 | {
21 | "path": "../types/tsconfig.json"
22 | },
23 | {
24 | "path": "../utils/tsconfig.json"
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/packages/sdk/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/sdk
2 |
3 | This package is the intermediate data layer of Rsdoctor.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/sdk/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { configWithEsm } from '../../scripts/modern.base.config';
2 |
3 | export default configWithEsm;
4 |
--------------------------------------------------------------------------------
/packages/sdk/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sdk';
2 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sdk';
2 | export * from './multiple';
3 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/multiple/index.ts:
--------------------------------------------------------------------------------
1 | export * from './controller';
2 | export * from './primary';
3 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/multiple/server.ts:
--------------------------------------------------------------------------------
1 | import { Server } from '@rsdoctor/utils/build';
2 | import { RsdoctorServer } from '../server';
3 | import type { RsdoctorPrimarySDK } from './primary';
4 |
5 | export class RsdoctorSlaveServer extends RsdoctorServer {
6 | protected sdk: RsdoctorPrimarySDK;
7 |
8 | constructor(sdk: RsdoctorPrimarySDK, port = Server.defaultPort) {
9 | super(sdk, port);
10 | this.sdk = sdk;
11 | }
12 |
13 | async openClientPage(...args: unknown[]) {
14 | if (this.sdk.isMaster) {
15 | return super.openClientPage(...(args as ['homepage']));
16 | }
17 |
18 | return Promise.resolve();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/server/apis/fs.ts:
--------------------------------------------------------------------------------
1 | import { SDK } from '@rsdoctor/types';
2 |
3 | import { BaseAPI } from './base';
4 | import { Router } from '../router';
5 |
6 | export class FileSystemAPI extends BaseAPI {
7 | @Router.post(SDK.ServerAPI.API.ApplyErrorFix)
8 | public async applyErrorFix(): Promise<
9 | SDK.ServerAPI.InferResponseType
10 | > {
11 | const { body } = this.ctx.req;
12 | const data = body as { id: number };
13 |
14 | await this.ctx.sdk.applyErrorFix(data.id);
15 |
16 | return 'success';
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/server/apis/index.ts:
--------------------------------------------------------------------------------
1 | export * from './alerts';
2 | export * from './data';
3 | export * from './fs';
4 | export * from './loader';
5 | export * from './graph';
6 | export * from './plugin';
7 | export * from './project';
8 | export * from './renderer';
9 | export * from './resolver';
10 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/server/fakeServer.ts:
--------------------------------------------------------------------------------
1 | import { SDK } from '@rsdoctor/types';
2 | import { Server } from '@rsdoctor/utils/build';
3 | import { RsdoctorServer } from '.';
4 |
5 | export class RsdoctorFakeServer extends RsdoctorServer {
6 | constructor(
7 | protected sdk: SDK.RsdoctorBuilderSDKInstance,
8 | port = Server.defaultPort,
9 | ) {
10 | super(sdk, port);
11 | this.sdk = sdk;
12 | }
13 |
14 | async openClientPage() {}
15 | }
16 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/utils/constant.ts:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 | export const CLOUD_DIR = `rsdoctor/manifests/${dayjs().format(
4 | 'YYYYMMDD',
5 | )}`;
6 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './constant';
2 | export * from './upload';
3 |
--------------------------------------------------------------------------------
/packages/sdk/src/sdk/utils/upload.ts:
--------------------------------------------------------------------------------
1 | import { DataWithUrl } from '../sdk/types';
2 |
3 | export const transformDataUrls = (
4 | d: DataWithUrl[],
5 | ): Record => {
6 | return d.reduce((t: { [key: string]: string[] | string }, item) => {
7 | t[item.name] = Array.isArray(item.files)
8 | ? item.files.map((e) => e.path).concat(t[item.name] || [])
9 | : item.files;
10 | return t;
11 | }, {});
12 | };
13 |
--------------------------------------------------------------------------------
/packages/sdk/tests/server/apis/data.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect, vi } from 'vitest';
2 | import { SDK } from '@rsdoctor/types';
3 | import { setupSDK } from '../../utils';
4 |
5 | vi.setConfig({ testTimeout: 50000 });
6 |
7 | describe('test server/apis/data.ts', () => {
8 | const target = setupSDK();
9 |
10 | it(`test api: ${SDK.ServerAPI.API.ReportLoader}`, async () => {
11 | const spy = vi
12 | .spyOn(target.sdk, 'reportLoader')
13 | .mockImplementation(() => {});
14 |
15 | await target.post(SDK.ServerAPI.API.ReportLoader, { a: 1 } as any);
16 |
17 | expect(spy).toBeCalledTimes(1);
18 | expect(spy).toHaveBeenCalledWith({ a: 1 });
19 |
20 | spy.mockRestore();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/packages/sdk/tests/server/apis/fs.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, vi, expect } from 'vitest';
2 | import { SDK } from '@rsdoctor/types';
3 | import { setupSDK } from '../../utils';
4 |
5 | describe('test server/apis/fs.ts', () => {
6 | const target = setupSDK();
7 |
8 | it(`test api: ${SDK.ServerAPI.API.ApplyErrorFix}`, async () => {
9 | const spy = vi
10 | .spyOn(target.sdk, 'applyErrorFix')
11 | .mockImplementation(async () => {});
12 |
13 | await target.post(SDK.ServerAPI.API.ApplyErrorFix, { id: 111 } as any);
14 |
15 | expect(spy).toBeCalledTimes(1);
16 | expect(spy).toHaveBeenCalledWith(111);
17 |
18 | spy.mockRestore();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/packages/sdk/tests/server/apis/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest';
2 | import { SDK } from '@rsdoctor/types';
3 | import { Router } from '../../../src/sdk/server/router';
4 |
5 | // make sure the decorators work.
6 | import '../../../src/sdk/server/apis';
7 |
8 | describe('ensure all of the apis implementation for server', () => {
9 | const apis = Object.values(SDK.ServerAPI.API);
10 |
11 | it(`ensure server`, async () => {
12 | const { get, post } = Router.routes;
13 |
14 | const list = [...get, ...post].map((e) => e[1].map((el) => el[1])).flat();
15 |
16 | list.forEach((api) => {
17 | expect(apis).toContain(api);
18 | });
19 | expect(list.length).toBeGreaterThan(30);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/sdk/tests/server/apis/renderer.test.ts:
--------------------------------------------------------------------------------
1 | import { File } from '@rsdoctor/utils/build';
2 | import { describe, it, expect } from 'vitest';
3 | import { SDK } from '@rsdoctor/types';
4 | import { setupSDK } from '../../utils';
5 |
6 | describe('test server/apis/data.ts', () => {
7 | const target = setupSDK();
8 |
9 | it(`test api: ${SDK.ServerAPI.API.EntryHtml}`, async () => {
10 | const { text } = await target.get(SDK.ServerAPI.API.EntryHtml);
11 | expect(text).toBeDefined();
12 | // const clientHtmlPath = require.resolve('@rsdoctor/client'); // TODO: add doctor client.
13 | // const clientHtml = await File.fse.readFile(clientHtmlPath, 'utf-8');
14 |
15 | // expect(text).toEqual(clientHtml);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/packages/sdk/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "experimentalDecorators": true,
5 | "outDir": "./dist",
6 | "baseUrl": "./",
7 | "paths": {
8 | "@/*": ["./src/*"]
9 | },
10 | "rootDir": "src"
11 | },
12 | "include": ["src"],
13 | "exclude": ["**/node_modules"],
14 | "references": [
15 | {
16 | "path": "../types/tsconfig.json"
17 | },
18 | {
19 | "path": "../utils/tsconfig.json"
20 | },
21 | {
22 | "path": "../graph/tsconfig.json"
23 | },
24 | {
25 | "path": "../client/tsconfig.json"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/packages/types/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/types
2 |
3 | This package is the Rsdoctor's types package.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/types/src/babel.ts:
--------------------------------------------------------------------------------
1 | /** Babel Error */
2 | export interface Error {
3 | code: string;
4 | reasonCode: string;
5 | message: string;
6 | name: string;
7 | stack: string;
8 | pos?: number;
9 | loc?: {
10 | line: number;
11 | column: number;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/packages/types/src/index.ts:
--------------------------------------------------------------------------------
1 | export * as Manifest from './manifest';
2 | export * as Esbuild from './esbuild';
3 | export * as Babel from './babel';
4 | export * as Common from './common';
5 |
6 | export * as Err from './error';
7 | export * as Logger from './logger';
8 | export * as SDK from './sdk';
9 | export * as Modules from './modules';
10 | export * as Linter from './linter';
11 |
12 | export * as Rule from './rule';
13 | export * as Thirdparty from './thirdparty';
14 |
15 | export * as Client from './client';
16 | export * as Constants from './constants';
17 |
18 | export * as Plugin from './plugin';
19 |
--------------------------------------------------------------------------------
/packages/types/src/linter/index.ts:
--------------------------------------------------------------------------------
1 | export * from './diagnostic';
2 | export * from './rule';
3 |
--------------------------------------------------------------------------------
/packages/types/src/logger.ts:
--------------------------------------------------------------------------------
1 | export enum LogLevel {
2 | Silent,
3 | Error,
4 | Warning,
5 | Info,
6 | Debug,
7 | Verbose,
8 | }
9 |
10 | export type LogLevelName = keyof typeof LogLevel;
11 |
--------------------------------------------------------------------------------
/packages/types/src/modules.ts:
--------------------------------------------------------------------------------
1 | import { StatsModule } from './plugin/baseStats';
2 |
3 | export type ChunkModuleMap = {
4 | isAsset: boolean;
5 | label: string;
6 | modules: StatsModule[];
7 | };
8 |
9 | export type Modules = Record;
10 |
--------------------------------------------------------------------------------
/packages/types/src/plugin/index.ts:
--------------------------------------------------------------------------------
1 | export * from './baseCompiler';
2 | export * from './baseStats';
3 | export * from './plugin';
4 | export * from './baseLoader';
5 | export * from './rspack';
6 |
--------------------------------------------------------------------------------
/packages/types/src/rule/code/E1004.ts:
--------------------------------------------------------------------------------
1 | import { RuleMessage } from './type';
2 |
3 | export const code = 'E1004';
4 |
5 | export const message: RuleMessage = {
6 | code,
7 | title: 'ECMA Version Check',
8 | type: 'markdown',
9 | category: 'bundle',
10 | description: `
11 | #### Description
12 |
13 | Detect if there is a newer version of ECMA syntax in the js bundle file
14 | `,
15 | };
16 |
--------------------------------------------------------------------------------
/packages/types/src/rule/index.ts:
--------------------------------------------------------------------------------
1 | export * from './code';
2 | export * from './data';
3 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/config.ts:
--------------------------------------------------------------------------------
1 | import type { Configuration } from 'webpack';
2 | import type { Configuration as RspackConfiguration } from '@rspack/core';
3 |
4 | type RspackConfigurationWrapper = any extends RspackConfiguration
5 | ? never
6 | : RspackConfiguration;
7 |
8 | export interface WebpackConfigData {
9 | name: 'webpack' | 'rspack';
10 | version: string | number;
11 | bin?: string;
12 | config: Configuration | RspackConfigurationWrapper;
13 | }
14 |
15 | export type ConfigData = WebpackConfigData[];
16 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/envinfo.ts:
--------------------------------------------------------------------------------
1 | export interface EnvInfo {
2 | /**
3 | * @example "macOS 11.4"
4 | */
5 | os: string;
6 | /**
7 | * @example "(12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz"
8 | */
9 | cpu: string;
10 | /**
11 | * @example "1.07 GB / 32.00 GB"
12 | */
13 | memory: string;
14 | nodeVersion: string;
15 | yarnVersion: string;
16 | npmVersion: string;
17 | pnpmVersion: string;
18 |
19 | [key: string]: string;
20 | }
21 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/hooks.ts:
--------------------------------------------------------------------------------
1 | import type { AsyncSeriesHook } from 'tapable';
2 | import { RsdoctorManifestWithShardingFiles } from '../manifest';
3 |
4 | /**
5 | * sdk hooks map
6 | */
7 | export interface Hooks {
8 | afterSaveManifest: AsyncSeriesHook<
9 | [
10 | {
11 | manifestWithShardingFiles: RsdoctorManifestWithShardingFiles;
12 | manifestDiskPath: string;
13 | manifestCloudPath?: string;
14 | },
15 | ]
16 | >;
17 | }
18 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/index.ts:
--------------------------------------------------------------------------------
1 | export * from './loader';
2 | export * from './resolver';
3 | export * from './plugin';
4 | export * from './module';
5 | export * from './chunk';
6 | export * from './result';
7 | export * from './summary';
8 | export * from './package';
9 | export * from './context';
10 | export * from './config';
11 | export * from './server';
12 | export * from './statement';
13 | export * from './treeShaking';
14 | export * from './envinfo';
15 | export * from './instance';
16 | export * from './hooks';
17 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/plugin.ts:
--------------------------------------------------------------------------------
1 | import { DevToolErrorInstance } from '../error';
2 |
3 | export interface PluginHookData {
4 | /** hook tap name */
5 | tapName: string;
6 | /** hook call time-consuming */
7 | costs: number;
8 | startAt: number;
9 | endAt: number;
10 | /** hook function type */
11 | type: 'sync' | 'async' | 'promise';
12 |
13 | /** hook function result */
14 | result: any;
15 |
16 | /** hook function running error */
17 | error: DevToolErrorInstance[];
18 | }
19 |
20 | /**
21 | * Plugin data
22 | * - Key name Hook name
23 | * - Key value is the hook data array
24 | */
25 | export type PluginData = Record;
26 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/process.ts:
--------------------------------------------------------------------------------
1 | export interface ProcessData {
2 | /**
3 | * process id
4 | */
5 | pid: number;
6 | /**
7 | * parent process id
8 | */
9 | ppid: number | null;
10 | }
11 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/server/apis/pagination.ts:
--------------------------------------------------------------------------------
1 | export interface PaginationRequest {
2 | page?: number;
3 | pageSize?: number;
4 | }
5 |
6 | export interface PaginationResponse extends Required {
7 | hasNextPage: boolean;
8 | }
9 |
10 | export interface EnhanceWithPaginationResponse {
11 | data: T;
12 | pagination: PaginationResponse;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/server/apis/plugin.ts:
--------------------------------------------------------------------------------
1 | import { API } from './index';
2 | import { PluginHookData } from '../../plugin';
3 |
4 | export interface PluginAPIResponse {
5 | [API.GetPluginSummary]: {
6 | hooks: string[];
7 | tapNames: string[];
8 | };
9 |
10 | [API.GetPluginData]: {
11 | hook: string;
12 | tapName: string;
13 | data: Pick[];
14 | }[];
15 | }
16 |
17 | export interface PluginAPIRequestBody {
18 | [API.GetPluginData]: {
19 | hooks?: string[];
20 | tapNames?: string[];
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/server/apis/project.ts:
--------------------------------------------------------------------------------
1 | import {
2 | RsdoctorManifestClientRoutes,
3 | RsdoctorManifestData,
4 | } from '../../../manifest';
5 | import { API, APIExtends } from './index';
6 |
7 | export interface ProjectAPIResponse {
8 | [API.Env]: {
9 | ip: string;
10 | port: number;
11 | };
12 | [API.GetProjectInfo]: Pick<
13 | RsdoctorManifestData,
14 | 'hash' | 'root' | 'pid' | 'summary' | 'configs' | 'envinfo' | 'errors'
15 | >;
16 | [API.GetClientRoutes]: RsdoctorManifestClientRoutes[];
17 | [APIExtends.GetCompileProgress]: {
18 | percentage: number;
19 | message: string;
20 | };
21 | }
22 |
23 | export interface ProjectAPIRequestBody {}
24 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/server/apis/resolver.ts:
--------------------------------------------------------------------------------
1 | import { API } from './index';
2 | import { PathResolverData } from '../../resolver';
3 |
4 | export interface ResolverAPIResponse {
5 | [API.GetResolverFileTree]: Array>;
6 | [API.GetResolverFileDetails]: {
7 | filepath: string;
8 | before: string;
9 | after: string;
10 | resolvers: (PathResolverData & { costs: number })[];
11 | };
12 | }
13 |
14 | export interface ResolverAPIRequestBody {
15 | [API.GetResolverFileDetails]: { filepath: string };
16 | }
17 |
--------------------------------------------------------------------------------
/packages/types/src/sdk/summary.ts:
--------------------------------------------------------------------------------
1 | interface SummaryCostsData {
2 | /**
3 | * such as 'bootstrap' / 'compile' / 'minify' or else.
4 | */
5 | name: string;
6 | /**
7 | * the start timestamp of the data.
8 | */
9 | startAt: number;
10 | costs: number;
11 | }
12 |
13 | export interface SummaryData {
14 | /**
15 | * costs of different data.
16 | */
17 | costs: SummaryCostsData[];
18 | }
19 |
--------------------------------------------------------------------------------
/packages/types/src/thirdparty.ts:
--------------------------------------------------------------------------------
1 | import type connect from 'connect';
2 |
3 | export type { connect };
4 |
--------------------------------------------------------------------------------
/packages/types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "module": "Node16",
5 | "moduleResolution": "Node16",
6 | "outDir": "./dist",
7 | "baseUrl": "./",
8 | "rootDir": "src",
9 | "paths": {
10 | "@/*": ["./src/*"]
11 | }
12 | },
13 | "include": ["src"],
14 | "exclude": ["**/node_modules"]
15 | }
16 |
--------------------------------------------------------------------------------
/packages/utils/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/utils
2 |
3 | This package is the Rsdoctor's tools package.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/utils/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { configWithEsm } from '../../scripts/modern.base.config';
2 |
3 | export default configWithEsm;
4 |
--------------------------------------------------------------------------------
/packages/utils/src/build/file/index.ts:
--------------------------------------------------------------------------------
1 | export * from './sharding';
2 |
3 | export * as fse from 'fs-extra';
4 | export * as cache from './cache';
5 |
--------------------------------------------------------------------------------
/packages/utils/src/build/index.ts:
--------------------------------------------------------------------------------
1 | export * as File from './file';
2 | export * as Json from './json';
3 | export * as Server from './server';
4 | export * as EnvInfo from './envinfo';
5 | export * as Process from './process';
6 |
--------------------------------------------------------------------------------
/packages/utils/src/common/crypto.ts:
--------------------------------------------------------------------------------
1 | const sep = '!';
2 |
3 | export function encode(str: string) {
4 | let res = `${str.charCodeAt(0)}`;
5 |
6 | for (let i = 1; i < str.length; i++) {
7 | res += `${sep}${str.charCodeAt(i)}`;
8 | }
9 |
10 | return res;
11 | }
12 |
13 | export function decode(str: string) {
14 | let res = '';
15 | let tmp = '';
16 |
17 | for (let i = 0; i < str.length; i++) {
18 | if (str[i] === sep) {
19 | res += String.fromCharCode(+tmp);
20 | tmp = '';
21 | } else {
22 | // 'number'
23 | tmp += str[i];
24 | }
25 | }
26 |
27 | // end of str
28 | if (tmp) {
29 | res += String.fromCharCode(+tmp);
30 | }
31 |
32 | return res;
33 | }
34 |
--------------------------------------------------------------------------------
/packages/utils/src/common/graph/entrypoints.ts:
--------------------------------------------------------------------------------
1 | import { SDK } from '@rsdoctor/types';
2 |
3 | export function getEntryPoints(
4 | entrypoints: SDK.EntryPointData[],
5 | ): SDK.ServerAPI.InferResponseType {
6 | return entrypoints;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/utils/src/common/graph/index.ts:
--------------------------------------------------------------------------------
1 | export * from './assets';
2 | export * from './chunk';
3 | export * from './modules';
4 | export * from './dependency';
5 | export * from './entrypoints';
6 |
--------------------------------------------------------------------------------
/packages/utils/src/common/index.ts:
--------------------------------------------------------------------------------
1 | export * as Summary from './summary';
2 | export * as Crypto from './crypto';
3 | export * as Manifest from './manifest';
4 | export * as Loader from './loader';
5 | export * as Time from './time';
6 | export * as Algorithm from './algorithm';
7 | export * as Resolver from './resolver';
8 | export * as Graph from './graph';
9 | export * as Bundle from './bundle';
10 | export * as Url from './url';
11 | export * as Plugin from './plugin';
12 | export * as Data from './data';
13 | export * as Alerts from './alerts';
14 | export * as Rspack from './rspack';
15 | export * as Package from './package';
16 | export * as Lodash from './lodash';
17 | export * as GlobalConfig from './global-config';
18 |
--------------------------------------------------------------------------------
/packages/utils/src/common/rspack.ts:
--------------------------------------------------------------------------------
1 | export const RspackLoaderInternalPropertyName = '__l__';
2 |
3 | export enum RspackSummaryCostsDataName {
4 | Bootstrap = 'bootstrap->rspack:beforeCompile',
5 | Compile = 'rspack:beforeCompile->afterCompile',
6 | Done = 'rspack:afterCompile->done',
7 | Minify = 'rspack:minify(rspack:optimizeChunkAssets)',
8 | }
9 |
--------------------------------------------------------------------------------
/packages/utils/src/common/summary.ts:
--------------------------------------------------------------------------------
1 | export enum SummaryCostsDataName {
2 | Bootstrap = 'bootstrap->beforeCompile',
3 | Compile = 'beforeCompile->afterCompile',
4 | Done = 'afterCompile->done',
5 | Minify = 'minify(processAssets)',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/utils/src/common/url.ts:
--------------------------------------------------------------------------------
1 | import { isAbsolute } from 'path';
2 |
3 | export function isUrl(uri: string) {
4 | return /^https?:\/\//.test(uri);
5 | }
6 |
7 | export function isFilePath(uri: string) {
8 | return isAbsolute(uri);
9 | }
10 |
11 | export function isRemoteUrl(uri: unknown) {
12 | if (typeof uri === 'string') {
13 | if (isUrl(uri) || isFilePath(uri)) {
14 | return true;
15 | }
16 | }
17 |
18 | return false;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/utils/src/error/index.ts:
--------------------------------------------------------------------------------
1 | export * from './error';
2 |
3 | export { printErrors } from './utils';
4 |
--------------------------------------------------------------------------------
/packages/utils/src/index.ts:
--------------------------------------------------------------------------------
1 | export * as RuleUtils from './rule-utils';
2 | export * as Logger from './logger';
3 |
--------------------------------------------------------------------------------
/packages/utils/src/rule-utils/document/index.ts:
--------------------------------------------------------------------------------
1 | export * from './document';
2 | export * from './types';
3 | export * from './server';
4 |
--------------------------------------------------------------------------------
/packages/utils/src/rule-utils/document/server.ts:
--------------------------------------------------------------------------------
1 | import { Document } from './document';
2 |
3 | const store = new Map();
4 |
5 | /** Create Document */
6 | export function getDocument(content: string) {
7 | if (store.has(content)) {
8 | return store.get(content)!;
9 | }
10 |
11 | const doc = new Document(content);
12 | store.set(content, doc);
13 | return doc;
14 | }
15 |
16 | export function clearDocument() {
17 | store.clear();
18 | }
19 |
--------------------------------------------------------------------------------
/packages/utils/src/rule-utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './document';
2 | export * from './parser';
3 |
--------------------------------------------------------------------------------
/packages/utils/src/rule-utils/parser/index.ts:
--------------------------------------------------------------------------------
1 | export * from './asserts';
2 | export * from './parser';
3 | export * from './utils';
4 | export * from './types';
5 |
--------------------------------------------------------------------------------
/packages/utils/src/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | interface Window {
2 | [key: string]: any;
3 | __RSDOCTOR__: any;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/utils/tests/__snapshots__/crypto.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`test src/crypto.ts > encode & decode > encode() 1`] = `
4 | ""00123sdfdkfkskfk" -> "48!48!49!50!51!115!100!102!100!107!102!107!115!107!102!107"
5 | "~!|.[]{}&……%()()\`·sdkf121" -> "126!33!65372!46!91!93!123!125!38!8230!8230!37!65288!65289!40!41!96!183!115!100!107!102!49!50!49"
6 | "~sd~d8哈哈哈😊" -> "126!115!100!65374!100!56!21704!21704!21704!55357!56842"
7 | "🔚🔜🌹👌" -> "55357!56602!55357!56604!55356!57145!55357!56396""
8 | `;
9 |
--------------------------------------------------------------------------------
/packages/utils/tests/build/time.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect, vi } from 'vitest';
2 | import { hrtime } from 'process';
3 | import { Time } from '../../src/common';
4 |
5 | vi.setConfig({ testTimeout: 100000 });
6 |
7 | describe('test src/build/time.ts', () => {
8 | it('getCurrentTimestamp', async () => {
9 | const start = Date.now();
10 | const startH = hrtime();
11 | const delay = 500;
12 |
13 | const value = await new Promise((r) => {
14 | setTimeout(() => {
15 | r(Time.getCurrentTimestamp(start, startH));
16 | }, delay);
17 | });
18 |
19 | expect(value).toBeGreaterThanOrEqual(start + delay);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/utils/tests/server.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, expect } from 'vitest';
2 | import { Server } from '../src/build';
3 | import { getPortSync } from '../src/build/server';
4 |
5 | describe('test src/server.ts', () => {
6 | it('getPort()', async () => {
7 | expect(await Server.getPort(6273)).toEqual(6273);
8 |
9 | const { close } = await Server.createServer(8292);
10 | expect(await Server.getPort(8292)).not.toEqual(8292);
11 | await close();
12 | });
13 |
14 | it('getPortSync()', async () => {
15 | expect(getPortSync(3543)).toEqual(3543);
16 |
17 | const { close } = await Server.createServer(8262);
18 | expect(getPortSync(8262)).not.toEqual(8262);
19 | await close();
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "baseUrl": ".",
6 | "rootDir": "src"
7 | },
8 | "include": ["src"],
9 | "exclude": ["**/node_modules"],
10 | "references": [
11 | {
12 | "path": "../types/tsconfig.json"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/README.md:
--------------------------------------------------------------------------------
1 | # @rsdoctor/webpack-plugin
2 |
3 | A webpack plugin for integrating Rsdoctor.
4 |
5 | ## Documentation
6 |
7 | https://rsdoctor.rs/
8 |
9 | ## Contributing
10 |
11 | Please read the [Contributing Guide](https://github.com/web-infra-dev/rsdoctor/blob/main/CONTRIBUTING.md).
12 |
13 | ## License
14 |
15 | Rsdoctor is [MIT licensed](https://github.com/web-infra-dev/rsdoctor/blob/main/LICENSE).
16 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/modern.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@modern-js/module-tools';
2 | import { baseBuildConfig } from '../../scripts/modern.base.config';
3 | import { merge } from 'lodash';
4 |
5 | const modernConfig = defineConfig({
6 | ...merge(baseBuildConfig, {
7 | buildConfig: { tsconfig: 'tsconfig.build.json' },
8 | }),
9 | });
10 |
11 | export default modernConfig;
12 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/src/constants.ts:
--------------------------------------------------------------------------------
1 | import type { Tap } from 'tapable';
2 |
3 | export const pluginTapName = 'RsdoctorWebpackPlugin';
4 |
5 | export const pluginTapPostOptions: Tap = {
6 | name: pluginTapName,
7 | stage: 999,
8 | };
9 |
10 | export const pluginTapPreOptions: Tap = {
11 | name: pluginTapName,
12 | stage: -999,
13 | };
14 |
15 | export const internalPluginTapPreOptions = (namespace: string): Tap => ({
16 | name: `${pluginTapName}:${namespace}`,
17 | stage: -998,
18 | });
19 |
20 | export const internalPluginTapPostOptions = (namespace: string): Tap => ({
21 | name: `${pluginTapName}:${namespace}`,
22 | stage: 1000,
23 | });
24 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './plugin';
2 | export * from './multiple';
3 |
4 | export { defineRule, LinterType } from '@rsdoctor/core/rules';
5 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "paths": {
6 | "@/*": ["../src/*"]
7 | }
8 | },
9 | "include": ["./**/*.ts"],
10 | "exclude": ["../**/node_modules"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["src"],
4 | "exclude": ["**/node_modules"]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/webpack-plugin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "outDir": "./dist",
6 | "rootDir": "src"
7 | },
8 | "include": ["src"],
9 | "exclude": ["**/node_modules"],
10 | "references": [
11 | {
12 | "path": "../core/tsconfig.json"
13 | },
14 | {
15 | "path": "../graph/tsconfig.json"
16 | },
17 | {
18 | "path": "../sdk/tsconfig.json"
19 | },
20 | {
21 | "path": "../types/tsconfig.json"
22 | },
23 | {
24 | "path": "../utils/tsconfig.json"
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'e2e/**'
3 | - 'scripts/**'
4 | - 'packages/**'
5 | - 'examples/**'
6 |
--------------------------------------------------------------------------------
/scripts/requireShims.js:
--------------------------------------------------------------------------------
1 | // If you declare a variable named 'require', esbuild will change it to 'require2'
2 | // Otherwise you use banner to add this code, import.meta.url will be replaced with source file's value by bundle-require
3 | // So we can only add it to global scope, and not pure
4 | import { createRequire } from 'module';
5 |
6 | global.require = createRequire(import.meta.url);
7 |
--------------------------------------------------------------------------------
/scripts/test-helper/modern.config.ts:
--------------------------------------------------------------------------------
1 | import baseConfig from '../../scripts/modern.base.config';
2 |
3 | export default baseConfig;
4 |
--------------------------------------------------------------------------------
/scripts/test-helper/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@rsdoctor/tsconfig/base",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "baseUrl": "./"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/scripts/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2019",
4 | "lib": ["DOM", "ESNext"],
5 | "allowJs": true,
6 | "module": "ES2020",
7 | "strict": true,
8 | "isolatedModules": true,
9 | "declarationMap": true,
10 | "declaration": true,
11 | "esModuleInterop": true,
12 | "skipLibCheck": true,
13 | "noUnusedLocals": true,
14 | "noUnusedParameters": true,
15 | "jsx": "preserve",
16 | "resolveJsonModule": true,
17 | "moduleResolution": "Bundler",
18 | "composite": true
19 | },
20 | "$schema": "https://json.schemastore.org/tsconfig",
21 | "display": "Base"
22 | }
23 |
--------------------------------------------------------------------------------
/scripts/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@rsdoctor/tsconfig",
3 | "private": true
4 | }
5 |
--------------------------------------------------------------------------------
/scripts/vitest.setup.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import { expect } from 'vitest';
3 | import { createSnapshotSerializer } from '@scripts/test-helper';
4 |
5 | expect.addSnapshotSerializer(
6 | createSnapshotSerializer({
7 | workspace: path.join(__dirname, '..'),
8 | }),
9 | );
10 |
--------------------------------------------------------------------------------