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: support for command line #14

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion .fatherrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import { defineConfig } from 'father';

export default defineConfig({
plugins: ['@rc-component/father-plugin'],
});
esm: { ignores: ['src/cli/**'] }
});
55 changes: 53 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ npm install @ant-design/static-style-extract
## Usage

```tsx | pure
import extractStyle from `@ant-design/static-style-extract`;
import { extractStyle } from `@ant-design/static-style-extract`;

const cssText = extractStyle(); // :where(.css-bAMboOo).ant-btn ...

Expand All @@ -41,7 +41,7 @@ const cssText = extractStyle(); // :where(.css-bAMboOo).ant-btn ...
use with custom theme

```tsx | pure
import extractStyle from `@ant-design/static-style-extract`;
import { extractStyle } from `@ant-design/static-style-extract`;

const cssText = extractStyle(); // :where(.css-bAMboOo).ant-btn ...

Expand All @@ -52,6 +52,57 @@ const cssText = extractStyle((node) => (
));
```

use command line

```bash
npx @ant-design/static-style-extract@latest -i your-theme.tsx
```

<details>
<summary><code>your-theme.tsx</code> example</summary>

```tsx | pure
import * as React from 'react';
import { ConfigProvider } from 'antd';

const testGreenColor = '#008000';
const testRedColor = '#ff0000';

// Not a React component (Pure function)
export default (node) => (
<>
<ConfigProvider
theme={{
token: {
colorBgBase: testGreenColor,
},
}}
>
{node}
</ConfigProvider>
<ConfigProvider
theme={{
token: {
colorPrimary: testGreenColor,
},
}}
>
<ConfigProvider
theme={{
token: {
colorBgBase: testRedColor,
},
}}
>
{node}
</ConfigProvider>
</ConfigProvider>
</>
)
```

</details>

## Example

http://localhost:8000
Expand Down
3 changes: 3 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../lib/cli/index.js');
41 changes: 41 additions & 0 deletions docs/examples/_example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* coped from https://ant.design/docs/react/server-side-rendering-cn
* > npx @ant-design/static-style-extract@latest -i ./docs/examples/_example.tsx
*/
import * as React from 'react';
import { ConfigProvider } from 'antd';

const testGreenColor = '#008000';
const testRedColor = '#ff0000';

// Not a React component (Pure function)
export default (node) => (
<>
<ConfigProvider
theme={{
token: {
colorBgBase: testGreenColor,
},
}}
>
{node}
</ConfigProvider>
<ConfigProvider
theme={{
token: {
colorPrimary: testGreenColor,
},
}}
>
<ConfigProvider
theme={{
token: {
colorBgBase: testRedColor,
},
}}
>
{node}
</ConfigProvider>
</ConfigProvider>
</>
)
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@
"url": "https://github.com/ant-design/static-style-extract/issues"
},
"files": [
"bin",
"es",
"lib"
],
"license": "MIT",
"main": "./lib/index",
"module": "./es/index",
"bin": "./bin/index.js",
"scripts": {
"start": "dumi dev",
"build": "dumi build",
"dev": "father dev",
"compile": "father build",
"prepublishOnly": "npm run compile && np --yolo --no-publish",
"lint": "eslint src/ docs/examples/ --ext .tsx,.ts,.jsx,.js",
Expand All @@ -46,14 +49,19 @@
"cross-env": "^7.0.1",
"dumi": "^2.1.0",
"eslint": "^7.0.0",
"execa": "5",
"father": "^4.0.0",
"less": "^3.10.3",
"nanoid": "3",
"np": "^6.2.0",
"picocolors": "^1.0.0",
"rc-test": "^7.0.13",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"regenerator-runtime": "^0.13.7",
"typescript": "^4.0.0"
"tsx": "^4.6.2",
"typescript": "^4.0.0",
"yargs": "^17.7.2"
},
"dependencies": {
"@ant-design/cssinjs": "^1.8.1",
Expand Down
18 changes: 18 additions & 0 deletions src/cli/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import c from 'picocolors'
import pkg from '../../package.json'

export const ARROW = c.cyan('→')
export const CHECK = c.green('✔')
export const CROSS = c.red('✘')
export const WARN = c.yellow('ℹ')
export const PREFIX = 'antd'

export const cssinjsVersion = pkg.dependencies['@ant-design/cssinjs'];
export const version = pkg.version;
export const name = pkg.name;

export const example = `
import * as React from 'react';
import { ConfigProvider } from 'antd';
export default (node) => React.createElement(ConfigProvider, null, node);
`.trim();
55 changes: 55 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import process from 'process'
import c from 'picocolors'
import { hideBin } from 'yargs/helpers'
import yargs from 'yargs'
import { CROSS, version, name } from './constants'
import { run } from './run'

function header() {
console.log(`\n${c.green(`${name} `)}${c.dim(`v${version}`)}`)
}

const instance = yargs(hideBin(process.argv))
.scriptName(name)
.usage('')
.command(
'*',
'Generate static css',
args => args
.option('output', {
alias: 'o',
description: 'Output file path',
type: 'string',
default: 'antd.min.css'
})
.option('input', {
alias: 'i',
description: 'Input file path',
type: 'string'
})
.option('overwrite', {
alias: 'w',
description: 'Overwrite existing files',
type: 'boolean'
})
.help(),
async (args) => {
header()
console.log()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个空的 log 拿来干嘛的?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link

@yoyo837 yoyo837 Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

空行.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接在打印的地方加 \n 不就行了么

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

条条大路通北京。😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉没必要单独写一个空 log ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

哈哈哈 细枝末节

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整体看起来没啥大问题,可以测一下平台兼容性,至少 mac 和 windows 得支持

try {
await run(args)
}
catch (error) {
console.error(c.inverse(c.red(' Failed to generate ')))
console.error(c.red(`${CROSS} ${String(error)}`))
process.exit(1)
}
},
)
.showHelpOnFail(false)
.alias('h', 'help')
.version('version', version)
.alias('v', 'version')

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
instance.help().argv
76 changes: 76 additions & 0 deletions src/cli/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import c from 'picocolors'
import { CHECK, WARN, PREFIX } from './constants'
import { nanoid } from 'nanoid'
import execa from 'execa';

export interface CliOptions {
/**
* @default `antd.min.css`
*/
output?: string;
input?: string;
overwrite?: boolean;
}

const tsxPath = require.resolve('tsx/cli');
const coreFilePath = path.join(__dirname, '..');

export async function run(options: CliOptions = {}) {
const { output = "antd.min.css", input = '', overwrite } = options;
const OVERWRITE = !!process.env.ALLAY_OVERWRITE /** Can be used for CI */ || overwrite;

const cwd = process.cwd()

const outputFilePath = path.join(cwd, output);
const inputFilePath = path.join(cwd, input);

const userInputFileExits = input.length > 0 && fs.existsSync(inputFilePath)

if (input.length > 0 && !userInputFileExits) {
console.log(c.yellow(`${WARN} ${input.length ? c.bold(input) : 'input'} is not exists.`));
}

if (fs.existsSync(outputFilePath) && !OVERWRITE) {
throw new Error(`${output} is already exists.`);
}

const outputDir = path.dirname(outputFilePath);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}

// ====== Generate temp file ======
const id = nanoid().replaceAll('-', '_');
const fileExt = userInputFileExits ? path.extname(inputFilePath) : '.js';
const internalFileName = `.temp_${PREFIX}_${id}${fileExt}`,
internalVariable = `${PREFIX}_${id}`;
let internalFileContent = '';

if (userInputFileExits) {
internalFileContent += `import ${internalVariable} from ${JSON.stringify(inputFilePath)};\n`
} else {
internalFileContent += `const ${internalVariable} = void 0;\n`
}

internalFileContent += `
import { extractStyle } from ${JSON.stringify(coreFilePath)};
import fs from 'fs';
fs.writeFileSync(${JSON.stringify(outputFilePath)}, extractStyle(${internalVariable}));
`.trim();

const tmpFilePath = path.join(os.tmpdir(), internalFileName);
const symlinkPath = path.join(path.dirname(inputFilePath), internalFileName);
fs.writeFileSync(tmpFilePath, internalFileContent, { encoding: 'utf-8', mode: 0o777 });
fs.symlinkSync(tmpFilePath, symlinkPath, 'file');

execa.node(tsxPath, [symlinkPath])
.then(() => {
console.log(c.green(`${CHECK} ${c.bold(output)} is generated.`));
})
.finally(() => {
fs.unlinkSync(symlinkPath);
})
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"paths": {
"@/*": ["src/*"],
"@@/*": [".dumi/tmp/*"],
Expand Down