Commit 0246419f authored by dengxiaofeng's avatar dengxiaofeng

init component

parents
import React from 'react';
import PreView from 'dumi-theme-default/src/builtins/Previewer';
import LazyLoad from 'react-lazyload';
import ProSkeleton from '@ant-design/pro-skeleton';
export default ({ children, ...rest }) => {
return (
<LazyLoad height={500} offset={300} placeholder={<ProSkeleton type="descriptions" />} once>
<PreView {...rest}>{children}</PreView>
</LazyLoad>
);
};
\ No newline at end of file
#root {
& /deep/ {
.__dumi-default-navbar-logo {
padding-left: 86px!important;
}
}
}
\ No newline at end of file
import './global.less';
import 'moment/locale/zh-cn';
import React, { useEffect } from 'react';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import Layout from 'dumi-theme-default/src/layout';
import moment from 'moment';
moment.locale('zh-cn');
export default ({ children, ...props }) => {
useEffect(() => {
(function (h, o, t, j, a, r) {
h.hj =
h.hj ||
function () {
(h.hj.q = h.hj.q || []).push(arguments);
};
h._hjSettings = { hjid: 2036108, hjsv: 6 };
a = o.getElementsByTagName('head')[0];
r = o.createElement('script');
r.async = 1;
r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
a.appendChild(r);
})(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
}, []);
return (
<ConfigProvider locale={zhCN}>
<Layout {...props}>{children}</Layout>
</ConfigProvider>
);
};
\ No newline at end of file
module.exports = {
extends: [require.resolve('@umijs/fabric/dist/eslint')],
rules: {
'import/no-extraneous-dependencies': 0,
'import/no-unresolved': 0,
},
};
\ No newline at end of file
import { readdirSync } from 'fs';
import { join } from 'path';
// utils must build before core
const headPkgs = [];
const tailPkgs = readdirSync(join(__dirname, 'packages')).filter(
(pkg) => pkg.charAt(0) !== '.' && !headPkgs.includes(pkg),
);
export default {
cjs: { type: 'babel', lazy: true },
esm: {
type: 'babel',
importLibToEs: true,
},
pkgs: [...headPkgs, ...tailPkgs],
extraBabelPlugins: [
['babel-plugin-import', { libraryName: 'antd', libraryDirectory: 'es', style: true }, 'antd'],
],
};
\ No newline at end of file
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
**/node_modules
# roadhog-api-doc ignore
/src/utils/request-temp.js
_roadhog-api-doc
# production
**/dist
/.vscode
**/**/lib/**
**/**/es/**
# misc
.DS_Store
npm-debug.log*
yarn-error.log
/coverage
.idea
package-lock.json
*bak
.vscode
# visual studio code
.history
*.log
functions/mock
.temp/**
# umi
.umi
.umi-production
# screenshot
screenshot
.firebase
.eslintcache
.changelog
\ No newline at end of file
**/*.svg
package.json
.umi
.umi-production
**/dist
**/lib
**/es
**\__snapshots__\**
\ No newline at end of file
const fabric = require('@umijs/fabric');
module.exports = {
...fabric.prettier,
};
\ No newline at end of file
import chalk from 'chalk';
import { readdirSync } from 'fs';
import { join } from 'path';
const headPkgList = [];
// utils must build before core
// runtime must build before renderer-react
const pkgList = readdirSync(join(__dirname, 'packages')).filter(
(pkg) => pkg.charAt(0) !== '.' && !headPkgList.includes(pkg),
);
const alias = pkgList.reduce((pre, pkg) => {
pre[`@winsdom-components/pro-${pkg}`] = join(__dirname, 'packages', pkg, 'src');
return {
...pre,
};
}, {});
console.log(`🌼 alias list \n${chalk.blue(Object.keys(alias).join('\n'))}`);
const tailPkgList = pkgList
.map((path) => [join('packages', path, 'src')])
.reduce((acc, val) => acc.concat(val), []);
const isProduction = process.env.NODE_ENV === 'production';
export default {
title: 'winsdom-components',
mode: 'site',
logo: 'https://panda-water.cn/web4/assets/images/logo/单独图案-蓝绿色.svg',
extraBabelPlugins: [
[
'import',
{
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
},
],
],
alias,
resolve: { includes: [...tailPkgList, 'docs'] },
navs: [
null,
{
title: 'Gitlab',
path: 'https://g.civnet.cn:8443/test/winsdom-components',
},
],
analytics: isProduction
? {
ga: 'UA-173569162-1',
}
: false,
hash: true,
dynamicImport: {
loading: '@ant-design/pro-skeleton',
},
externals:
process.env.NODE_ENV === 'development'
? {
react: 'window.React',
'react-dom': 'window.ReactDOM',
moment: 'window.moment',
antd: 'window.antd',
}
: {},
targets: {
chrome: 80,
firefox: false,
safari: false,
edge: false,
ios: false,
},
links:
process.env.NODE_ENV === 'development'
? ['https://gw.alipayobjects.com/os/lib/antd/4.6.6/dist/antd.css']
: [],
scripts:
process.env.NODE_ENV === 'development'
? [
'https://gw.alipayobjects.com/os/lib/react/16.13.1/umd/react.development.js',
'https://gw.alipayobjects.com/os/lib/react-dom/16.13.1/umd/react-dom.development.js',
'https://gw.alipayobjects.com/os/lib/moment/2.29.0/min/moment-with-locales.js',
'https://gw.alipayobjects.com/os/lib/antd/4.6.6/dist/antd-with-locales.js',
]
: [],
};
\ No newline at end of file
---
title: 快速开始
order: 2
group:
path: /
nav:
title: 文档
path: /docs
---
## 安装
当前 winsdom-components 每一个组件都是一个独立的包,你需要在你的项目中安装对应的 npm 包并使用。
---
title: 介绍 - WinsDOM-Components
order: 10
sidebar: false
hero:
title: WinsDOM-Components
desc: 🏆 Use Ant Design like a Pro!
actions:
- text: 快速开始 →
link: /docs/getting-started
---
## 组件看板
| 组件 | 下载量 | 版本 |
| --- | --- | --- |
## 🖥 浏览器兼容性
---
title: 简介
order: 1
group:
path: /
nav:
title: 文档
order: 1
path: /docs
---
## ProComponents 的理念
Ant Design 定义了基础的设计规范,对应也提供了大量的基础组件。但是对于大量的中后台类应用,我们希望提供更高程度的抽象,提供更上层的设计规范,并且对应提供相应的组件使得开发者可以快速搭建出高质量的页面。
在 ProComponents 中我们内置了一系列的设计规范,预设了常用的逻辑。在这个基础上我们同样提供了灵活性的支持,比如对于 ProTable 来说你也可以把它完全当做 antd 的 Table 来用,对于 ProForm 来说你也可以直接使用 antd 的基础组件或者你的自定义组件。我们希望通过 Pro 系列组件提供快速高效大家高质量中后台应用的能力,进一步扩展 Ant Design 的能力,欢迎使用并提出宝贵的意见。
## 设计思路
对于几乎所有的业务来说,我们做的其实就是根据一个状态定义一系列的行为,以上面的 table 为例,首先我们需要一个状态
dataSource 用于存储从服务器请求的数据,为了优化体验,我们还需要一个 `loading`。于是我们就有了一系列的行为,我们需要先设置 `loading=true`,然后发起网络请求,网络请求完成之后就 设置 dataSource 为请求回来的数据,`loading=false`,一个网络请求就完成了, 虽然非常简单,但是一个业务系统有相当多的表格,每个表格都要完成这么一次,这个工作量就非常大了。
如果要重新网络,我们就需要封装一下行为,将以上的行为封装成一个 方法,点击一下重新加载数据,如果你有分页,那么就需要新的变量 page,我们在重新请求之前需要去根据需要来判断一下是否将页面重置为第一页,这又引入了一个变量。如果你的表格还要这只每页的数量,那么将会更加繁杂。这种重复性的劳动会浪费掉我们的很多时间。
### 一个状态加一系列行为
以上的逻辑几乎存在于所有开发中后台中,每增加一个状态我们就需要一系列的行为来进行管理,每个行为如果耦合了太多的状态也回复杂到无以复加。
碰上这种情况,几乎所有程序员都会想办法进行分层,基于同样的思路,ProTable 希望抽象出一层来解决掉复杂状态的问题,table 中最常用的状态就是 loading 和 dataSource,包括扩展的 page,pageSize 其实都是服务于网络状态,于是 table 抽象出了一个 `request` 的 api,在其中封装了 loading 和 dataSource 状态以及他们所有的行为,上一下,下一页,重新刷新,修改页容量等行为。
这种封装模式可以让前端从各种状态管理中脱身出来,专注于业务开发,也不需要 dva,redux 等数据流的方案,更加符合直觉。开发者只需要定义一个状态,重型组件会自动生成一系列行为。
> 为了降级我们也提供了与 antd 相同的 api,完全可以降级成为一个 antd 的 table 使用。
### 一个组件 ≈ 一个页面
重型组件区别于传统组件有个很大的不同,重型组件在抽象时是将其当成一个页面来进行处理,所以 ProTable 会支持网络请求和自动生成查询表单,而 ProLayout 会支持自动生成菜单,两者都基于同一个逻辑,期望提供页面级别的抽象。
一个列表页应该可以用 ProLayout + ProTable 完成,一个编辑页应该使用 ProLayout + ProForm 完成,详情页可以用 ProLayout + ProDescriptions 完成。 一个页面在开发工程中只需要关注几个重型组件,降低心智负担,专注于跟核心的业务逻辑。
### 设计与样式
在实际开发中我们也经常会碰到一些设计问题,比如经典的按钮应该放在左面还是右面,查询表单怎么布局,日期怎么格式化,数字对齐问题,在重型组件中都进行了抽象。对于各种行为我们都经过了设计师的讨论与设计。默认好看并且好用。
## 参与贡献
我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley::
- 在你的公司或个人项目中使用 Ant Design Pro,umi 和 ProComponents。
- 通过 [Issue](http://github.com/ant-design/pro-components/issues) 报告 bug 或进行咨询。
- 提交 [Pull Request](http://github.com/ant-design/pro-components/pulls) 改进 ProComponents 的代码。
### 脚手架概览
当我们 clone 完项目之后我们会看到如下的目录结构。
```bash
- .dumi * dumi 的相关配置,主要是主题等
- .github * github 的 action 和相关的 issue 配置
- docs * 存放公用的文档
- packages * 我们维护的包, 如果你想贡献代码,这里是你最需要关注的
- README.md * 展示在 github 主页的代码
- tests * 编写测试用例的地方
- public * 部署官网所用的静态文件
- scripts * 开发或者部署所用的脚本
- .prettierrc.js * prettier 的相关配置
- .eslintrc.js * eslint 的配置
- .fatherrc.ts * 编译脚手架的配置
- .umirc.js * dumi 的核心配置
- webpack.config.js * 编译 umd 包的配置文件
- jest.config.js * 测试环境的配置
- lerna.json * 多包的配置
- package.json * 项目的配置
- tsconfig.json * typescript 的配置
- yarn.lock * 依赖 lock 文件
```
`coverage``.umi` 这两个文件夹比较特殊,coverage 是测试覆盖率文件,在跑完测试覆盖率后才会出现,`.umi` 是运行时的一些临时文件,在执行 `npm run start` 时生成。
### 源码概览
在 packages 文件夹中包含了我们所有的组件,每个组件一般都有一个 `src``package.json``README.md``package.json``README.md` 可以在新建文件夹后通过执行 `npm run bootstrap` 来生成。
`src` 中就是我们真正的源码,我们约定 `src` 下会有 demos 文件夹里面会存储所有的 demo,并且 `${包名}.md` 的文件用于介绍这个组件,同时引入 demo 和 API 文档。
> 我们使用了 dumi 的语法,要求全部使用外置组件,用 code 引入,调试起来会更加方便。
### 风格指南
我们使用自动化代码格式化软件 [`Prettier`](https://prettier.io/)。 对代码做出更改后,运行 `npm run prettier`。当然我们更推荐 prettier 的插件,随时格式化代码。
> 我们的 CI 会检查代码是否被 prettier,在提交代码前最好执行一下 `npm run prettier`
之后,linter 会捕获代码中可能出现的多数问题。 你可以运行 `npm run lint` 来检查代码风格状态。
不过,linter 也有不能搞定的一些风格。如果有些东西不确定,请查看 [Airbnb’s Style Guide](https://github.com/airbnb/javascript) 来指导自己。
### 开发工作流
我们使用了 [monorepo](https://danluu.com/monorepo/) 的方式来管理我们的仓库,仓库中包含多个独立的包,以便于更改可以一起联调,这样可以一起跑测试用例,如果变更出现问题,我们可以很快的定位到问题。
因为使用了 monorepo ,我们要求必须要使用 yarn 来安装依赖。[`workspace`](https://classic.yarnpkg.com/en/docs/workspaces#search) 可以帮助我们在多个包中共享依赖。
安装完成后你可以使用以下命令:
- `yarn start` 预览你的改动
- `yarn lint` 检查代码风格
- `yarn tsc` 检查 TypeScript 是否符合规范
- `yarn test` 测试代码是否可以通过测试用例
- `yarn test:coverage` 测试仓库的测试覆盖率
- `yarn build` 编译当前组件库
我们建议运行 `yarn test` 或前文提及的变体以确保你的代码变更有没有影响原有功能,同时保证你写的每行代码都被正确的测试到,不管怎样这样都会提升组件库的整体质量。
如果你增加了一个新功能,请添加测试后再提交 pr,这样我们能确保以后你的代码不出问题。
### 一些约定
ProComponents 基于 antd 之上来开发,为了与 antd 的生态保持兼容性,我们要求覆盖 antd 的样式必须要使用 `.@{ant-prefix}` 变量来生成类名,在 js 中使用如下代码来配置实现。
```tsx | pure
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls('pro-${包名}');
```
const { readdirSync } = require('fs');
const { join } = require('path');
const pkgList = readdirSync(join(__dirname, './packages')).filter((pkg) => pkg.charAt(0) !== '.');
const moduleNameMapper = {};
pkgList.forEach((shortName) => {
const name = `@ant-design/pro-${shortName}`;
moduleNameMapper[name] = join(__dirname, `./packages/${shortName}/src`);
});
module.exports = {
collectCoverageFrom: [
'packages/**/src/**/*.{js}',
'!packages/**/src/demos/**',
],
moduleNameMapper,
testURL: 'http://localhost',
verbose: true,
snapshotSerializers: [require.resolve('enzyme-to-json/serializer')],
extraSetupFiles: ['./tests/setupTests.js'],
globals: {
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
},
};
\ No newline at end of file
{
"version": "independent",
"npmClient": "yarn",
"useWorkspaces": true,
"changelog": {
"repo": "test/winsdom-components",
"cacheDir": ".changelog"
},
"ignoreChanges": ["**/*.md", "**/*.test.js", "**/*.e2e.js", "**/fixtures/**", "**/test/**"]
}
\ No newline at end of file
{
"private": true,
"license": "MIT",
"workspaces": [
"packages/*"
],
"scripts": {
"bootstrap": "node ./scripts/bootstrap.js",
"build": "father-build && webpack",
"deploy": "npm run site && gh-pages -d ./dist",
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./packages && npm run lint:prettier",
"lint:prettier": "npm run prettier && git diff && prettier --version && prettier --check \"packages/**/**.{js,jsx,tsx,ts,less,md,json}\" --end-of-line auto",
"prettier": "prettier --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"",
"release": "node ./scripts/release.js",
"site": "dumi build",
"size": "npm run build && size-limit",
"start": "dumi dev",
"tsc:duplicate": "tsc -p ./tests/tsconfig.duplicate.json",
"sync:tnpm": "node -e 'require(\"./scripts/syncTNPM\")()'",
"test": "umi-test",
"test:coverage": "umi-test --coverage",
"test:update": "umi-test --updateSnapshot",
"update:deps": "yarn upgrade-interactive --latest"
},
"browserslist": [
"last 2 versions",
"Firefox ESR",
"> 1%",
"ie >= 11"
],
"devDependencies": {
"@ant-design/compatible": "^1.0.4",
"@ant-design/pro-skeleton": "^1.0.0-beta.2",
"@babel/core": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/preset-react": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
"@size-limit/preset-big-lib": "^4.5.5",
"@testing-library/react": "^10.0.2",
"@testing-library/react-hooks": "^3.2.1",
"@umijs/babel-preset-umi": "^3.0.14",
"@umijs/fabric": "^2.0.0",
"@umijs/plugin-analytics": "^0.2.2",
"@umijs/test": "^3.2.10",
"@umijs/test-utils": "^3.2.10",
"@umijs/utils": "^3.2.11",
"antd": "^4.7.0",
"babel-loader": "^8.1.0",
"babel-plugin-import": "^1.12.2",
"body-parser": "^1.18.2",
"chalk": "^4.1.0",
"cross-env": "^7.0.0",
"css-loader": "^3.4.2",
"dumi": "1.1.0-beta.24",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.4.3",
"eslint": "^7.2.0",
"father-build": "^1.18.1",
"gh-pages": "^3.1.0",
"glob": "^7.1.6",
"jest": "^26.2.2",
"jest-fetch-mock": "^3.0.3",
"jsdom": "^16.4.0",
"jsdom-global": "^3.0.2",
"lerna": "^3.20.2",
"lerna-changelog": "^1.0.1",
"less-loader": "^6.0.0",
"lint-staged": "^10.0.2",
"mini-css-extract-plugin": "^0.9.0",
"mockdate": "^3.0.2",
"moment": "^2.27.0",
"moment-timezone": "^0.5.31",
"np": "^6.1.0",
"npm-run-all": "^4.1.5",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"pify": "^5.0.0",
"prettier": "^2.1.2",
"pretty-quick": "^2.0.1",
"progress-bar-webpack-plugin": "^2.1.0",
"query-string": "^6.11.1",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-lazyload": "^3.0.0",
"react-markdown": "^4.3.0",
"react-test-renderer": "^16.9.0",
"size-limit": "^4.5.5",
"slash2": "^2.0.0",
"style-loader": "^1.1.3",
"stylelint": "^13.0.0",
"terser-webpack-plugin": "^3.0.2",
"typescript": "^3.9.7",
"umi": "^3.2.10",
"umi-plugin-githubpages": "^2.0.0",
"umi-request": "^1.3.5",
"umi-test": "^1.9.6",
"umi-types": "^0.5.11",
"webpack-bundle-analyzer": "^3.6.0",
"webpack-cli": "^3.3.12",
"write-pkg": "^4.0.0",
"xhr-mock": "^2.5.1",
"yorkie": "^2.0.0"
},
"gitHooks": {
"pre-commit": "pretty-quick --staged",
"commit-msg": "node scripts/verifyCommit.js"
},
"size-limit": [
{
"path": "packages/card/dist/**/*.js",
"limit": "100 s",
"webpack": false,
"running": false
}
]
}
# @ant-design/pro-card
> @ant-design/pro-card.
See our website [@ant-design/pro-card](https://umijs.org/plugins/card) for more information.
## Install
Using npm:
```bash
$ npm install --save @ant-design/pro-card
```
or using yarn:
```bash
$ yarn add @ant-design/pro-card
```
{
"name": "@ant-design/pro-card",
"version": "1.0.0-beta.1",
"description": "@ant-design/pro-card",
"module": "es/index.js",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"src",
"dist",
"es"
],
"repository": {
"type": "git",
"url": "https://github.com/ant-design/pro-components"
},
"browserslist": [
"last 2 versions",
"Firefox ESR",
"> 1%",
"ie >= 11"
],
"keywords": [
"antd",
"admin",
"ant-design",
"ant-design-pro"
],
"authors": [
"chencheng <sorrycc@gmail.com> (https://github.com/sorrycc)",
"chenshuai2144 <qixian.cs@outlook.com> (https://github.com/chenshuai2144)"
],
"license": "MIT",
"bugs": "http://github.com/umijs/plugins/issues",
"homepage": "https://github.com/ant-design/pro-components/tree/master/packages/card#readme",
"peerDependencies": {
"umi": "3.x"
},
"publishConfig": {
"access": "public"
}
}
---
title: ProCard - 标准卡片
nav:
title: 组件
path: /components
group:
path: /
---
# ProCard 标准卡片
页内容器卡片,提供标准卡片样式,卡片切分以及栅格布局能力。
## 何时使用
- 需要一个标准卡片容纳内容时。
- 需要多个卡片栅格,gutter 布局时。
- 需要进行卡片内切分布局时。
- 需要卡片可折叠时。
console.log("hello world");
\ No newline at end of file
{
"name": "@winsdom-components/pro-card",
"version": "1.0.0",
"description": "@winsdom-components/pro-card",
"keywords": [
"antd",
"admin",
"antd-design",
"winsdom-components"
],
"sideEffects": [
"*.less"
],
"homepage": "https://g.civnet.cn:8443/test/winsdom-components/tree/master/packages/card#readme",
"repository": {
"type": "git",
"url": "https://g.civnet.cn:8443/test/winsdom-components"
},
"license": "MIT",
"main": "lib/index.js",
"module": "es/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"es",
"dist"
],
"browserslist": [
"last 2 versions",
"Firefox ESR",
"> 1%",
"ie >= 11"
],
"dependencies": {
"@ant-design/icons": "^4.2.1",
"@ant-design/pro-utils": "1.0.3",
"classnames": "^2.2.6"
},
"peerDependencies": {
"antd": "4.x",
"react": "^16.x"
},
"publishConfig": {
"access": "public"
},
"authors": [
"dengxiaofeng"
]
}
\ No newline at end of file
procomponents.ant.design
\ No newline at end of file
const { existsSync, writeFileSync, readdirSync } = require('fs');
const { join } = require('path');
const { yParser } = require('@umijs/utils');
(async () => {
const args = yParser(process.argv);
const version = '1.0.0-beta.1';
const pkgs = readdirSync(join(__dirname, '../packages')).filter((pkg) => pkg.charAt(0) !== '.');
pkgs.forEach((shortName) => {
const name = `@winsdom-components/pro-${shortName}`;
const pkgJSONPath = join(__dirname, '..', 'packages', shortName, 'package.json');
const pkgJSONExists = existsSync(pkgJSONPath);
let json;
if (args.force || !pkgJSONExists) {
json = {
name,
version,
description: name,
module: 'es/index.js',
main: 'lib/index.js',
types: 'lib/index.d.ts',
files: ['lib', 'src', 'dist', 'es'],
repository: {
type: 'git',
url: 'https://g.civnet.cn:8443/test/winsdom-components',
},
browserslist: ['last 2 versions', 'Firefox ESR', '> 1%', 'ie >= 11'],
keywords: ['antd', 'admin', 'ant-design', 'ant-design-pro'],
authors: [
'dengxiaofeng',
],
license: 'MIT',
bugs: 'http://github.com/umijs/plugins/issues',
homepage: `https://g.civnet.cn:8443/test/winsdom-components/tree/master/packages/${shortName}#readme`,
peerDependencies: {
umi: '3.x',
},
publishConfig: {
access: 'public',
},
};
if (pkgJSONExists) {
const pkg = require(pkgJSONPath);
[
'dependencies',
'devDependencies',
'peerDependencies',
'bin',
'version',
'files',
'authors',
'types',
'sideEffects',
'main',
'module',
'description',
].forEach((key) => {
if (pkg[key]) json[key] = pkg[key];
});
}
writeFileSync(pkgJSONPath, `${JSON.stringify(json, null, 2)}\n`);
}
const readmePath = join(__dirname, '..', 'packages', shortName, 'README.md');
if (args.force || !existsSync(readmePath)) {
writeFileSync(
readmePath,
`# ${name}
> ${json.description}.
See our website [${name}](https://umijs.org/plugins/${shortName}) for more information.
## Install
Using npm:
\`\`\`bash
$ npm install --save ${name}
\`\`\`
or using yarn:
\`\`\`bash
$ yarn add ${name}
\`\`\`
`,
);
}
});
})();
\ No newline at end of file
const path = require('path');
const fs = require('fs');
const writePkg = require('write-pkg');
const cwd = process.cwd();
const ignoreDirPath = ['.DS_Store'];
const filePath = path.resolve(cwd, 'package.json');
const packagesDir = path.resolve(cwd, 'packages');
const json = JSON.parse(fs.readFileSync(filePath, 'utf8'));
delete json['size-limit'];
let componentsNames = fs.readdirSync(packagesDir);
componentsNames = componentsNames.filter((dir) => ignoreDirPath.indexOf(dir) === -1);
(async () => {
const sizeLimitConfig = [];
componentsNames.forEach((component) => {
sizeLimitConfig.push({
path: `packages/${component}/lib/**/*.js`,
limit: '2 s',
webpack: false,
running: false,
});
sizeLimitConfig.push({
path: `packages/${component}/es/**/*.js`,
limit: '2 s',
webpack: false,
running: false,
});
});
await writePkg(cwd, { ...json, 'size-limit': sizeLimitConfig });
})();
\ No newline at end of file
const { utils } = require('umi');
const { join } = require('path');
const exec = require('./utils/exec');
const getPackages = require('./utils/getPackages');
const isNextVersion = require('./utils/isNextVersion');
const { yParser, execa, chalk } = utils;
const cwd = process.cwd();
const args = yParser(process.argv);
const lernaCli = require.resolve('lerna/cli');
function printErrorAndExit(message) {
console.error(chalk.red(message));
process.exit(1);
}
function logStep(name) {
console.log(`${chalk.gray('>> Release:')} ${chalk.magenta.bold(name)}`);
}
function packageExists({ name, version }) {
const { stdout } = execa.sync('npm', ['info', `${name}@${version}`]);
return stdout.length > 0;
}
async function release() {
// Check git status
if (!args.skipGitStatusCheck) {
const gitStatus = execa.sync('git', ['status', '--porcelain']).stdout;
if (gitStatus.length) {
printErrorAndExit(`Your git status is not clean. Aborting.`);
}
} else {
logStep('git status check is skipped, since --skip-git-status-check is supplied');
}
// Check npm registry
logStep('check npm registry');
const userRegistry = execa.sync('npm', ['config', 'get', 'registry']).stdout;
if (userRegistry.includes('https://registry.yarnpkg.com/')) {
printErrorAndExit(`Release failed, please use ${chalk.blue('npm run release')}.`);
}
if (!userRegistry.includes('https://registry.npmjs.org/')) {
const registry = chalk.blue('https://registry.npmjs.org/');
printErrorAndExit(`Release failed, npm registry must be ${registry}.`);
}
let updated = null;
if (!args.publishOnly) {
// Get updated packages
logStep('check updated packages');
const updatedStdout = execa.sync(lernaCli, ['changed']).stdout;
updated = updatedStdout
.split('\n')
.map((pkg) => {
return pkg.split('/')[1];
})
.filter(Boolean);
if (!updated.length) {
printErrorAndExit('Release failed, no updated package is updated.');
}
// Clean
logStep('clean');
// Build
if (!args.skipBuild) {
logStep('build');
await exec('npm', ['run', 'build']);
} else {
logStep('build is skipped, since args.skipBuild is supplied');
}
// Bump version
// Commit
// Git Tag
// Push
logStep('bump version with lerna version');
const conventionalGraduate = args.conventionalGraduate
? ['--conventional-graduate'].concat(
Array.isArray(args.conventionalGraduate) ? args.conventionalGraduate.join(',') : [],
)
: [];
const conventionalPrerelease = args.conventionalPrerelease
? ['--conventional-prerelease'].concat(
Array.isArray(args.conventionalPrerelease) ? args.conventionalPrerelease.join(',') : [],
)
: [];
await exec(
lernaCli,
[
'version',
'--exact',
// '--no-commit-hooks',
// '--no-git-tag-version',
// '--no-push',
'--message',
'🎨 chore(release): Publish',
'--conventional-commits',
]
.concat(conventionalGraduate)
.concat(conventionalPrerelease),
);
}
// Publish
// Umi must be the latest.
const pkgs = args.publishOnly ? getPackages() : updated;
logStep(`publish packages: ${chalk.blue(pkgs.join(', '))}`);
pkgs.forEach((pkg, index) => {
const pkgPath = join(cwd, 'packages', pkg.replace('pro-', ''));
const { name, version } = require(join(pkgPath, 'package.json'));
const isNext = isNextVersion(version);
let isPackageExist = null;
if (args.publishOnly) {
isPackageExist = packageExists({ name, version });
if (isPackageExist) {
console.log(`package ${name}@${version} is already exists on npm, skip.`);
}
}
if (!args.publishOnly || !isPackageExist) {
console.log(
`[${index + 1}/${pkgs.length}] Publish package ${name} ${isNext ? 'with next tag' : ''}`,
);
const cliArgs = isNext ? ['publish', '--tag', 'next'] : ['publish'];
const { stdout } = execa.sync('npm', cliArgs, {
cwd: pkgPath,
});
console.log(stdout);
}
});
await exec('npm', ['run', 'prettier']);
logStep('done');
}
release().catch((err) => {
console.error(err);
process.exit(1);
});
\ No newline at end of file
const { execa } = require('@umijs/utils');
const { join } = require('path');
const getPackages = require('./utils/getPackages');
process.setMaxListeners(Infinity);
module.exports = (publishPkgList) => {
const pkgList = (publishPkgList || getPackages()).map((name) => {
return require(join(__dirname, '../packages', name, 'package.json')).name;
});
const commands = pkgList.map((pkg) => {
const subprocess = execa('tnpm', ['sync', pkg]);
subprocess.stdout.pipe(process.stdout);
return subprocess;
});
Promise.all(commands);
};
\ No newline at end of file
const { spawn } = require('child_process');
module.exports = function exec(command, args, opts) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, Object.assign({ stdio: 'inherit', env: process.env }, opts));
child.once('error', (err) => {
console.log(err);
reject(err);
});
child.once('close', (code) => {
if (code === 1) {
process.exit(1);
} else {
resolve();
}
});
});
};
\ No newline at end of file
const { readdirSync } = require('fs');
const { join } = require('path');
module.exports = function getPackages() {
return readdirSync(join(__dirname, '../../packages')).filter((pkg) => pkg.charAt(0) !== '.');
};
\ No newline at end of file
module.exports = function (version) {
return version.includes('-rc.') || version.includes('-beta.') || version.includes('-alpha.');
};
\ No newline at end of file
const { chalk } = require('@umijs/utils');
const msgPath = process.env.GIT_PARAMS;
const msg = require('fs').readFileSync(msgPath, 'utf-8').trim();
const commitRE = /^(((\ud83c[\udf00-\udfff])|(\ud83d[\udc00-\ude4f\ude80-\udeff])|[\u2600-\u2B55]) )?(revert: )?(feat|fix|docs|UI|refactor|⚡perf|workflow|build|CI|typos|chore|tests|types|wip|release|dep)(\(.+\))?: .{1,50}/;
if (!commitRE.test(msg)) {
console.log();
console.error(
` ${chalk.bgRed.white(' ERROR ')} ${chalk.red(
`invalid commit message format.`,
)}\n\n${chalk.red(
` Proper commit message format is required for automated changelog generation. Examples:\n\n`,
)}
${chalk.green(`💥 feat(compiler): add 'comments' option`)}\n
${chalk.green(`🐛 fix(compiler): fix some bug`)}\n
${chalk.green(`📝 docs(compiler): add some docs`)}\n
${chalk.green(`💄 UI(compiler): better styles`)}\n
${chalk.green(`🎨 chore(compiler): do something`)}\n
${chalk.red(`See .github/commit-convention.md for more details.\n`)}`,
);
process.exit(1);
}
\ No newline at end of file
export * from '../packages/card/src';
\ No newline at end of file
import { enableFetchMocks } from 'jest-fetch-mock';
import MockDate from 'mockdate';
import moment from 'moment-timezone';
import tableData from './table/mock.data.json';
/* eslint-disable global-require */
if (typeof window !== 'undefined') {
global.window.resizeTo = (width, height) => {
global.window.innerWidth = width || global.window.innerWidth;
global.window.innerHeight = height || global.window.innerHeight;
global.window.dispatchEvent(new Event('resize'));
};
global.window.scrollTo = () => {};
// ref: https://github.com/ant-design/ant-design/issues/18774
if (!window.matchMedia) {
Object.defineProperty(global.window, 'matchMedia', {
writable: true,
configurable: true,
value: jest.fn(() => ({
matches: false,
addListener: jest.fn(),
removeListener: jest.fn(),
})),
});
}
}
const Enzyme = require('enzyme');
Object.assign(Enzyme.ReactWrapper.prototype, {
findObserver() {
return this.find('ResizeObserver');
},
triggerResize() {
const ob = this.findObserver();
ob.instance().onResize([{ target: ob.getDOMNode() }]);
},
});
enableFetchMocks();
global.requestAnimationFrame =
global.requestAnimationFrame ||
function requestAnimationFrame(cb) {
return setTimeout(cb, 0);
};
global.cancelAnimationFrame =
global.cancelAnimationFrame ||
function cancelAnimationFrame() {
return null;
};
// browserMocks.js
const localStorageMock = (() => {
let store = {};
return {
getItem(key) {
return store[key] || null;
},
setItem(key, value) {
store[key] = value.toString();
},
clear() {
store = {};
},
};
})();
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
});
Object.defineProperty(window, 'cancelAnimationFrame', {
value: () => null,
});
moment.tz.setDefault('UTC');
// 2016-11-22 15:22:44
MockDate.set(1479799364000);
const mockFormatExpression = {
format: (value) => `¥ ${value.toString()}`,
};
Intl.NumberFormat = jest.fn().mockImplementation(() => mockFormatExpression);
Math.random = () => 0.8404419276253765;
fetch.mockResponse(async () => {
return { body: JSON.stringify(tableData) };
});
\ No newline at end of file
import { act } from 'react-dom/test-utils';
export const waitForComponentToPaint = async (wrapper, time = 10) => {
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, time));
wrapper.update();
});
};
export const waitTime = (time = 100) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
};
export const resizeWindow = (x, y) => {
window.innerWidth = x;
window.innerHeight = y;
window.dispatchEvent(new Event('resize'));
};
\ No newline at end of file
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const { readdirSync } = require('fs');
const tailPkgs = readdirSync(path.join(__dirname, 'packages')).filter(
(pkg) => pkg.charAt(0) !== '.'
);
const webPackConfigList = [];
tailPkgs.forEach((pkg) => {
const entry = {};
entry[`${pkg}`] = `./packages/${pkg}/src/index.js`;
entry[`${pkg}.min`] = `./packages/${pkg}/src/index.js`;
const config = {
entry,
output: {
filename: '[name].js',
library: `WinsDOM${pkg.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())}`,
libraryExport: 'default',
path: path.resolve(__dirname, 'packages', pkg, 'dist'),
globalObject: 'this'
},
mode: 'production',
resolve: {
extensions: ['.json', '.css', '.js', '.less'],
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: /\.min\.js$/,
}),
new OptimizeCSSAssetsPlugin({
include: /\.min\.js$/,
}),
],
},
module: {
rules: [
{
test: /\.(png|jpg|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
},
{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/typescript', '@babel/env', '@babel/react'],
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: true }],
'@babel/proposal-object-rest-spread',
],
},
},
},
{
test: /\.tsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/typescript',
[
'@babel/env',
{
loose: true,
modules: false,
},
],
'@babel/react',
],
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: true }],
'@babel/proposal-object-rest-spread',
],
},
},
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader', // creates style nodes from JS strings
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
],
},
{
test: /\.less$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) =>
`${path.relative(path.dirname(resourcePath), context)}/`,
},
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
},
],
},
externals: [
{
react: 'React',
'react-dom': 'ReactDOM',
antd: 'antd',
moment: 'moment',
},
],
plugins: [
new ProgressBarPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
]
};
webPackConfigList.push(config);
});
module.exports = webPackConfigList;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment