Skip to content

Commit

Permalink
feat(cli,tester,builder): support react/vue package
Browse files Browse the repository at this point in the history
  • Loading branch information
deot committed Sep 2, 2023
1 parent 2828c25 commit 5f9e6ef
Show file tree
Hide file tree
Showing 21 changed files with 857 additions and 33 deletions.
4 changes: 2 additions & 2 deletions packages/_/monorepo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"scripts": {
"cli": "../../../node_modules/.bin/tsx ../../cli/src/index.ts",
"dev": "npm run cli -- dev --dry-run",
"build": "npm run cli -- build",
"test": "npm run cli -- test",
"build": "npm run cli -- build --vue-package '@demo/helper-vue' --react-package '@demo/helper-react'",
"test": "npm run cli -- test --vue-package '@demo/helper-vue' --react-package '@demo/helper-react'",
"release": "npm run cli -- release",
"update": "npm run cli -- update"
},
Expand Down
8 changes: 8 additions & 0 deletions packages/_/monorepo/packages/react/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { App } from '../src/index';

describe('index.ts', () => {
it('any', () => {
expect(typeof App).toBe('function');
expect(App().children![0].children).toBe('Hello World');
});
});
15 changes: 15 additions & 0 deletions packages/_/monorepo/packages/react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "@demo/helper-react",
"version": "1.0.0",
"main": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"license": "MIT",
"publishConfig": {
"access": "public"
},
"dependencies": {
}
}
3 changes: 3 additions & 0 deletions packages/_/monorepo/packages/react/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default () => {
return <div>Hello World</div>;
};
3 changes: 3 additions & 0 deletions packages/_/monorepo/packages/react/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import App from './app';

export { App };
7 changes: 7 additions & 0 deletions packages/_/monorepo/packages/vue/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { App } from '../src/index';

describe('index.ts', () => {
it('any', () => {
expect(typeof App).toBe('object');
});
});
15 changes: 15 additions & 0 deletions packages/_/monorepo/packages/vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "@demo/helper-vue",
"version": "1.0.0",
"main": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"license": "MIT",
"publishConfig": {
"access": "public"
},
"dependencies": {
}
}
3 changes: 3 additions & 0 deletions packages/_/monorepo/packages/vue/src/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>Hello World!</div>
</template>
3 changes: 3 additions & 0 deletions packages/_/monorepo/packages/vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import App from './app.vue';

export { App };
2 changes: 2 additions & 0 deletions packages/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
}
},
"dependencies": {
"@deot/dev-react": "*",
"@deot/dev-shared": "^2.4.0",
"@deot/dev-vue": "*",
"@microsoft/api-extractor": "^7.36.4",
"autoprefixer": "^10.4.15",
"chalk": "^5.3.0",
Expand Down
13 changes: 13 additions & 0 deletions packages/builder/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ export class Build {
dts: boolean;
scriptFormats: string;
nodePackage: string;
vuePackage: string;
reactPackage: string;
};

isVuePackage: boolean;

isReactPackage: boolean;

isNodePackage: boolean;

constructor(packageFolderName: string, commandOptions: Build['commandOptions']) {
const { workspace, packageDir, packageName, packageFolderName: packageFolderName$, subpackagesMap } = Locals.impl();
const subpackages = subpackagesMap[packageFolderName] || [];
Expand All @@ -43,6 +51,11 @@ export class Build {
: `${packageName}-${packageFolderName}`;
this.packageOptions = require$(`${this.packageDir}/package.json`); // eslint-disable-line
this.commandOptions = commandOptions;

const { reactPackage, vuePackage, nodePackage } = commandOptions;
this.isVuePackage = typeof vuePackage === 'string' && (vuePackage === '*' || (vuePackage.split(',')).includes(this.packageName));
this.isReactPackage = typeof vuePackage === 'string' && (vuePackage === '*' || (reactPackage.split(',')).includes(this.packageName));
this.isNodePackage = typeof nodePackage === 'string' && (nodePackage === '*' || (nodePackage.split(',')).includes(this.packageName));
}

async process() {
Expand Down
27 changes: 22 additions & 5 deletions packages/builder/src/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from 'fs-extra';
import { Locals } from '@deot/dev-shared';
import { build as createViteBuild } from 'vite';
import { build as createViteBuild, mergeConfig } from 'vite';
import type { InlineConfig } from 'vite';
import sharedVueConfig from '@deot/dev-vue';
import sharedReactConfig from '@deot/dev-react';
import type { Build } from './build';

const dirname = path.dirname(fileURLToPath(import.meta.url));
Expand All @@ -12,8 +14,18 @@ export const run = async (options: Build) => {
const locals = Locals.impl();
const { cwd, workspace } = locals;

const { packageSourceDir: srcDir, packageOutDir: outDir, packageName, packageDir, packageOptions, commandOptions } = options || {};
const { scriptFormats, nodePackage } = commandOptions;
const {
packageSourceDir: srcDir,
packageOutDir: outDir,
packageName,
packageDir,
packageOptions,
commandOptions,
isNodePackage,
isVuePackage,
isReactPackage
} = options || {};
const { scriptFormats } = commandOptions;

const stats: Array<{ format?: string; size: number; file: string }> = [];
let files = fs.existsSync(srcDir)
Expand Down Expand Up @@ -47,18 +59,23 @@ export const run = async (options: Build) => {
options$.configFile = path.relative(cwd, path.resolve(cwd, './build.config.ts'));
} else {
options$.configFile = path.relative(cwd, path.resolve(dirname, '../shared.config.ts'));
// 只有使用默认配置时才有效,否则就自行配置(这样可以配置单独Plugin的参数)
options$ = isVuePackage
? mergeConfig(sharedVueConfig, options$)
: isReactPackage
? mergeConfig(sharedReactConfig, options$)
: options$;
}

let viteBuild = await createViteBuild(options$);

return viteBuild;
};

const needFilter = typeof nodePackage === 'string' && (nodePackage === '*' || (nodePackage.split(',')).includes(packageName));
const formats = scriptFormats
.split(',')
.filter((i: string) => {
return !needFilter || ['es', 'cjs'].includes(i);
return !isNodePackage || ['es', 'cjs'].includes(i);
});
await formats
.reduce(
Expand Down
2 changes: 1 addition & 1 deletion packages/builder/src/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import autoprefixer from "autoprefixer";
import type { Build } from './build';

export const run = async (options: Build) => {
const { packageSourceDir: srcDir, packageOutDir: outDir, packageDir } = options || {};
const { packageSourceDir: srcDir, packageOutDir: outDir } = options || {};
const styles = fs.existsSync(srcDir)
? fs
.readdirSync(srcDir)
Expand Down
6 changes: 3 additions & 3 deletions packages/builder/src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const dirname = path.dirname(fileURLToPath(import.meta.url));

export const run = async (options: Build) => {
const { workspace, packageDir: packageRootDir } = Locals.impl();
const { packageDir, packageOutDir, packageSourceDir, packageOptions, commandOptions } = options;
const { isVuePackage, packageDir, packageOutDir, packageSourceDir, packageOptions, commandOptions } = options;

const done = () => {
const stats: Array<{ size: number; file: string }> = [];
Expand Down Expand Up @@ -46,6 +46,7 @@ export const run = async (options: Build) => {
compilerOptions: {
declaration: true,
emitDeclarationOnly: true,
allowJs: true,
rootDir,
outDir: '.'
},
Expand All @@ -54,8 +55,7 @@ export const run = async (options: Build) => {
]
}, null, '\t'));

// TODO: tsc是个变量,如vue-tsc就可以编译vue相关
await Shell.spawn('tsc', ['-p', `${tempDir}/tsconfig.json`]);
await Shell.spawn(isVuePackage ? 'vue-tsc' : 'tsc', ['-p', `${tempDir}/tsconfig.json`]);

const configPath = `${tempDir}/api-extractor.json`;
// 生成api-extractor用于合并dts
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ addOptions(
.option('--package-name <string>', 'Select packageName')
.option('--script-formats <string>', 'Script Formats(Output)', 'es,cjs')
.option('--node-package <string>')
.option('--vue-package <string>')
.option('--react-package <string>')
.option('--no-dts [boolean]', 'No Export Types'),
Builder.run
);
Expand Down Expand Up @@ -117,6 +119,8 @@ addOptions(
.option('--no-coverage [boolean]', 'Coverage Analyze')
.option('--package-name <string>', 'Select PackageName')
.option('--subpackage <string>', 'Select SubpackageName')
.option('--vue-package <string>')
.option('--react-package <string>')
.option('--watch [boolean]', 'Watch Test')
.option('--environment <string>', 'Environment', 'jsdom'),
Tester.run
Expand Down
3 changes: 2 additions & 1 deletion packages/index/tsconfig.shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"esModuleInterop": true,
"noImplicitAny": false,
"removeComments": true,
"allowSyntheticDefaultImports": true
"allowSyntheticDefaultImports": true,
"allowImportingTsExtensions": true
}
}
2 changes: 1 addition & 1 deletion packages/tester/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('index', () => {
});

// console.log(stdout);
expect(stdout).toMatch('4 passed');
expect(stdout).toMatch('6 passed');

// coverage
expect(stdout).toMatch(' index/src |');
Expand Down
2 changes: 2 additions & 0 deletions packages/tester/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"access": "public"
},
"dependencies": {
"@deot/dev-react": "*",
"@deot/dev-shared": "^2.4.0",
"@deot/dev-vue": "*",
"@vitest/coverage-istanbul": "^0.34.2",
"cross-env": "^7.0.3",
"inquirer": "^9.2.10",
Expand Down
30 changes: 25 additions & 5 deletions packages/tester/shared.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
import * as path from 'node:path';
import { createRequire } from "node:module";
import { defineConfig, configDefaults } from 'vitest/config';
import { defineConfig, configDefaults, mergeConfig } from 'vitest/config';
import type { UserConfig } from 'vite';

import vue from '@vitejs/plugin-vue';
import vueJSX from '@vitejs/plugin-vue-jsx';
import react from '@vitejs/plugin-react-swc';

/**
* https://github.com/vuejs/core/issues/8303
* to fix error: ReferenceError: __name is not defined
*/
let __defProp = Object.defineProperty;
let __name = (target: any, value: any) => __defProp(target, 'name', { value, configurable: true });
globalThis.__name = globalThis.__name || __name;

const getViteConfig = (options: any) => {
return options.useVue
? defineConfig({ plugins: [vue(), vueJSX()] })
: options.useReact
? defineConfig({ plugins: [react()] })
: {};
};
const cwd = process.cwd();

// options
Expand All @@ -12,8 +31,8 @@ const { workspace, packageFolderName, subpackageFolderName, subpackagesMap } = o
let tests: string[] = [];
let collects: string[] = [];

const TEST_PATTEN = `**.(spec|test).[jt]s?(x)`;
const COLLECT_PATTEN = `**/*.ts`;
const TEST_PATTEN = `**/*.{test,spec}.[jt]s?(x)`;
const COLLECT_PATTEN = `**/*.[jt]s?(x)`;

if (workspace) {
let prefixDir = `${workspace}/${packageFolderName || '*'}`;
Expand Down Expand Up @@ -55,7 +74,7 @@ if (workspace) {
const replacement = (name: string) => path.resolve(cwd, `./packages/${name}/src`);
const { name } = createRequire(cwd)(path.resolve(cwd, workspace ? `${workspace}/index` : '', 'package.json'));

export default defineConfig({
export default mergeConfig(getViteConfig(options), defineConfig({
resolve: workspace
? {
alias: [
Expand Down Expand Up @@ -89,4 +108,5 @@ export default defineConfig({
]
}
}
}) as UserConfig;
}) as UserConfig);

33 changes: 28 additions & 5 deletions packages/tester/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,16 @@ export const run = (options: Options) => Utils.autoCatch(async () => {

const isDev = process.env.NODE_ENV === 'development';
const NODE_ENV = process.env.NODE_ENV || 'TEST';
const TEST_OPTIONS = encodeURIComponent(JSON.stringify(options));

if (dryRun) {
const command = `cross-env NODE_ENV=${NODE_ENV} TEST_OPTIONS=${TEST_OPTIONS} vitest `
const command = `cross-env NODE_ENV=${NODE_ENV} TEST_OPTIONS=${encodeURIComponent(JSON.stringify(options))} vitest `
+ ([
'--passWithNoTests',
`${!(watch || isDev) ? '--watch=false' : ''}`
].join(' '));
Shell.spawn(`echo ${command}`);
return;
}

process.env.NODE_ENV = process.env.NODE_ENV || 'TEST';
process.env.TEST_OPTIONS = TEST_OPTIONS;

let options$: UserConfig = {
environment,
Expand All @@ -80,9 +76,36 @@ export const run = (options: Options) => Utils.autoCatch(async () => {
} else if (fs.existsSync(`${cwd}/test.config.ts`)) {
options$.config = path.relative(cwd, path.resolve(cwd, './test.config.ts'));
} else {
/**
* 和build保持一致, 仅当默认时,才启用vue
* startVitest第四个参数设置plugins的话;
* .vue就无法搜集覆盖率了, 这里需要在shared.config.ts直接配置
* 引入只是为了去除tsx执行的hack
*/
const { vuePackage } = options;
const packageName = Locals.getPackageName(options.packageFolderName);
const isVuePackage = typeof vuePackage === 'string' && (
packageName === locals.packageName
|| packageName === `${locals.packageName}-*`
|| vuePackage === '*'
|| (vuePackage.split(',')).includes(packageName)
);

const isReactPackage = typeof vuePackage === 'string' && (
packageName === locals.packageName
|| packageName === `${locals.packageName}-*`
|| vuePackage === '*'
|| (vuePackage.split(',')).includes(packageName)
);

options.useVue = !!isVuePackage;
options.useReact = !!isReactPackage;
options$.config = path.relative(cwd, path.resolve(dirname, '../shared.config.ts'));
}

process.env.NODE_ENV = NODE_ENV;
process.env.TEST_OPTIONS = encodeURIComponent(JSON.stringify(options));

await startVitest('test', [], options$);
}, {
onError: (e: any) => {
Expand Down
Loading

0 comments on commit 5f9e6ef

Please sign in to comment.