Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform): Add Bundle Size Page #46

Merged
merged 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fluffy-islands-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rsdoctor/components': patch
'@rsdoctor/client': patch
---

feat(platform): report platform add bundle size page
27 changes: 27 additions & 0 deletions examples/modern-minimal/modern.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import appTools, { defineConfig } from '@modern-js/app-tools';
import { RsdoctorWebpackPlugin } from '@rsdoctor/webpack-plugin';

const pluginName = 'Web Doctor';

export default defineConfig({
source: {
entries: {
main: './src/index.ts',
},
},
plugins: [appTools()],
builderPlugins: [
{
name: pluginName,
setup(builder) {
builder.modifyWebpackChain((chain) => {
chain.plugin(pluginName).use(RsdoctorWebpackPlugin, [
{
disableClientServer: !process.env.ENABLE_CLIENT_SERVER,
},
]);
});
},
},
],
});
31 changes: 31 additions & 0 deletions examples/modern-minimal/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@example/doctor-modern-minimal",
"version": "0.0.1",
"description": "",
"files": [
"dist",
"src",
"package.json"
],
"scripts": {
"start:analysis": "ENABLE_CLIENT_SERVER=true modern start",
"build:analysis": "ENABLE_CLIENT_SERVER=true modern build",
"build": "modern build"
},
"author": "",
"license": "MIT",
"dependencies": {
"@babel/highlight": "7.18.6",
"chalk": "4.1.2",
"htmlparser2": "7.2.0"
},
"devDependencies": {
"@rsdoctor/webpack-plugin": "workspace:*",
"@modern-js/app-tools": "2.41.0",
"@types/node": "14.18.26",
"eslint": "8.22.0",
"ts-loader": "9.4.2",
"tslib": "2.4.1",
"typescript": "4.9.4"
}
}
15 changes: 15 additions & 0 deletions examples/modern-minimal/src/html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Parser from 'htmlparser2';

export function getHtmlText(code: string) {
let context = '';

const parser = new Parser.Parser({
ontext(data) {
context += data;
},
});

parser.write(code);

return context;
}
8 changes: 8 additions & 0 deletions examples/modern-minimal/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Instance } from 'chalk';
import { highlight } from './utils';
import { getHtmlText } from './html';

const print = new Instance();

print(getHtmlText('<div>Test Text</div>'));
print(highlight('const abc = 123;'));
1 change: 1 addition & 0 deletions examples/modern-minimal/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module '@babel/highlight';
7 changes: 7 additions & 0 deletions examples/modern-minimal/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import highlight from '@babel/highlight';

export { highlight };
export const key1 = '123';
export const key2 = '123';

console.log(key2);
9 changes: 9 additions & 0 deletions examples/modern-minimal/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "@rsdoctor/tsconfig/base",
"include": ["src", "webpack.config.ts"],
"compilerOptions": {
"outDir": "dist",
"baseUrl": ".",
"module": "ESNext"
}
}
2 changes: 1 addition & 1 deletion examples/webpack-minimal/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import { key6 } from './utils2';
const print = new Instance();

print(key6);
print(getHtmlText('<div>测试文本</div>'));
print(getHtmlText('<div>Test Text</div>'));
print(highlight?.('const abc = 123;'));
2 changes: 1 addition & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"targetDefaults": {
"build": {
"cache": false,
"cache": true,
"dependsOn": ["^build"],
"inputs": [
"{projectRoot}/src/**/*",
Expand Down
10 changes: 1 addition & 9 deletions packages/client/modern.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ export default defineConfig<'webpack'>((env) => {
media: 'resource/media',
},
assetPrefix: IS_PRODUCTION
? // 此处不要修改!这里 production 的 publicPath 会和 sdk serve 的路径 以及 轻服务 部署的路径联动。
// OFFICAL_PREVIEW_PUBLIC_PATH 是提供给 轻服务 部署后域名关系
// "/" 是提供给 sdk 使用的
OFFICAL_PREVIEW_PUBLIC_PATH?.replace(/\/resource$/, '') || '/'
? OFFICAL_PREVIEW_PUBLIC_PATH?.replace(/\/resource$/, '') || '/'
: '/',
cleanDistPath: IS_PRODUCTION,
disableTsChecker: !IS_PRODUCTION,
Expand All @@ -62,11 +59,6 @@ export default defineConfig<'webpack'>((env) => {
strategy: 'custom',
splitChunks: {
cacheGroups: {
shadow: {
test: /node_modules\/@byted-shadow\/*/,
name: 'shadow',
chunks: 'all',
},
react: {
test: /node_modules\/react-*/,
name: 'react',
Expand Down
17 changes: 13 additions & 4 deletions packages/client/src/router.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import React from 'react';
import { Route, Routes } from 'react-router-dom';

import { OverallPage } from '@rsdoctor/components/pages';
import { Overall, BundleSize } from '@rsdoctor/components/pages';


export default function Router(): React.ReactElement {
const routes = [
/** bundle routes */
{
path: BundleSize.route,
element: <BundleSize.Page />,
},
].filter((e) => Boolean(e)) as { path: string; element: JSX.Element }[];

return (
<Routes>
<Route path="/" element={<OverallPage.default />} />
<Route path={OverallPage.route} element={<OverallPage.default />} />
<Route path="/" element={<Overall.Page />} />
<Route path={Overall.route} element={<Overall.Page />} />
{routes.map((e) => (
<Route key={e.path} path={e.path} element={e.element} />
))}
</Routes>
);
}
70 changes: 70 additions & 0 deletions packages/components/src/components/Form/keyword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { useEffect, useRef, useState } from 'react';
import { Button, Input, InputRef, Typography } from 'antd';

interface KeywordProps {
style?: React.CSSProperties;
labelStyle?: React.CSSProperties;
icon?: React.ReactNode;
label?: string;
placeholder?: string;
delay?: number;
className?: string;
width?: number;
onChange: (keyword: string) => void;
}

export const KeywordInput: React.FC<KeywordProps> = ({
icon: Icon,
label,
labelStyle: ls = {},
placeholder,
onChange,
style,
className,
width,
delay = 300,
}) => {
const labelWidth = 120;
const [filename, setFilename] = useState('');
const labelStyle: React.CSSProperties = { width: labelWidth, ...ls };

const ref = useRef<InputRef>(null);

let timer: NodeJS.Timeout;

useEffect(() => {
onChange(filename);
}, [filename]);

return (
<Input.Group compact style={style} className={className}>
{label || Icon ? (
<Button
style={labelStyle}
onClick={() => {
if (ref && ref.current) {
ref.current.focus();
}
}}
>
{Icon || null}
<Typography.Text>{label}</Typography.Text>
</Button>
) : null}
<Input
ref={ref}
allowClear
defaultValue={filename}
style={{ width: width ? width - labelWidth : 250 }}
placeholder={placeholder}
onChange={(e) => {
clearTimeout(timer);
const v = e.target.value.trim();
setTimeout(() => {
setFilename(v);
}, delay);
}}
/>
</Input.Group>
);
};
46 changes: 46 additions & 0 deletions packages/components/src/components/Keyword/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { Typography } from 'antd';
import { TextProps } from 'antd/es/typography/Text';

export const Keyword: React.FC<TextProps & { text: string; keyword: string }> = ({ text, keyword, ...rest }) => {
if (!keyword) {
return <Typography.Text {...rest}>{text}</Typography.Text>;
}

const idx = text.indexOf(keyword);
if (idx === -1) {
return <Typography.Text {...rest}>{text}</Typography.Text>;
}

const els: (string | React.ReactNode)[] = [];

let str = text;

while (str.length > 0) {
const idx = str.indexOf(keyword);
if (idx > -1) {
if (idx !== 0) {
els.push(
<Typography.Text key={els.length} style={{ fontSize: 'inherit' }}>
{str.slice(0, idx)}
</Typography.Text>,
);
}
els.push(
<Typography.Text mark key={els.length} style={{ fontSize: 'inherit' }}>
{keyword}
</Typography.Text>,
);
str = str.slice(idx + keyword.length);
} else {
els.push(
<Typography.Text key={els.length} style={{ fontSize: 'inherit' }}>
{str}
</Typography.Text>,
);
break;
}
}

return <Typography.Text {...rest}>{els}</Typography.Text>;
};
28 changes: 2 additions & 26 deletions packages/components/src/components/Layout/header.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { TranslationOutlined, UserOutlined } from '@ant-design/icons';
import { Avatar, Button, Col, Dropdown, Input, Layout, Row, Select, Switch, Typography } from 'antd';
import { Avatar, Col, Dropdown, Layout, Row, Switch, Typography } from 'antd';
import React from 'react';
import { APILoaderMode4Dev, Language, Size, Theme } from '../../constants';
import { Language, Size, Theme } from '../../constants';
import {
getAPILoaderModeFromStorage,
setAPILoaderModeToStorage,
useI18n,
useTheme
} from '../../utils';
Expand Down Expand Up @@ -63,28 +61,6 @@ export const Header: React.FC = () => {
wrap={false}
gutter={[Size.BasePadding / 3, 0]}
>
{process.env.NODE_ENV === 'development' ? (
<Col>
<Input.Group compact>
<Button size="small" style={{ borderTopRightRadius: 0, borderBottomRightRadius: 0 }}>
<Typography.Text>API 加载行为</Typography.Text>
</Button>
<Select
size="small"
value={getAPILoaderModeFromStorage()}
style={{ width: 90 }}
onChange={(v) => {
setAPILoaderModeToStorage(v as APILoaderMode4Dev);
location.reload();
}}
>
<Select.Option value={APILoaderMode4Dev.Local}>Local</Select.Option>
<Select.Option value={APILoaderMode4Dev.Remote}>Remote</Select.Option>
<Select.Option value={APILoaderMode4Dev.Default}>默认行为</Select.Option>
</Select>
</Input.Group>
</Col>
) : null}
<Col>
<OverlayAlertsWithButton />
</Col>
Expand Down
Loading