mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-05-16 09:05:33 +08:00
feat(cli): 自动install组件包,支持pnpm,npm,yarn
This commit is contained in:
parent
2cde4bb5a0
commit
c19afda58c
@ -31,10 +31,16 @@ export interface EntryFile {
|
|||||||
componentFileAffix: string;
|
componentFileAffix: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NpmConfig {
|
||||||
|
registry?: string;
|
||||||
|
client?: 'npm' | 'yarn' | 'pnpm';
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserConfig {
|
export interface UserConfig {
|
||||||
source: string;
|
source: string;
|
||||||
temp: string;
|
temp: string;
|
||||||
packages: Record<string, any>;
|
packages: (string | Record<string, string>)[];
|
||||||
componentFileAffix: string;
|
componentFileAffix: string;
|
||||||
cleanTemp: boolean;
|
cleanTemp: boolean;
|
||||||
|
npmConfig?: NpmConfig;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ import { execSync } from 'child_process';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { exit } from 'process';
|
import { exit } from 'process';
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import * as recast from 'recast';
|
import * as recast from 'recast';
|
||||||
|
|
||||||
import type App from '../Core';
|
import type App from '../Core';
|
||||||
import { Entry, EntryType, PackageType } from '../types';
|
import { Entry, EntryType, NpmConfig, PackageType } from '../types';
|
||||||
|
|
||||||
interface TypeAssertion {
|
interface TypeAssertion {
|
||||||
type: string;
|
type: string;
|
||||||
@ -26,10 +27,16 @@ export const resolveAppPackages = (app: App) => {
|
|||||||
const valueMap: Record<string, string> = {};
|
const valueMap: Record<string, string> = {};
|
||||||
const pluginMap: Record<string, string> = {};
|
const pluginMap: Record<string, string> = {};
|
||||||
|
|
||||||
Object.entries(app.options.packages).forEach(([key, packagePath]) => {
|
const dependencies: Record<string, string> = {};
|
||||||
installPackage(packagePath, app.options.source);
|
|
||||||
|
|
||||||
const indexPath = require.resolve(packagePath);
|
const setPackages = (cwd: string, packagePath: string, key?: string) => {
|
||||||
|
const { name: moduleName } = splitNameVersion(packagePath);
|
||||||
|
|
||||||
|
if (!moduleName) throw Error('packages中包含非法配置');
|
||||||
|
|
||||||
|
const indexPath = execSync(`node -e "console.log(require.resolve('${moduleName}'))"`, { cwd })
|
||||||
|
.toString()
|
||||||
|
.replace('\n', '');
|
||||||
const indexCode = fs.readFileSync(indexPath, { encoding: 'utf-8', flag: 'r' });
|
const indexCode = fs.readFileSync(indexPath, { encoding: 'utf-8', flag: 'r' });
|
||||||
const ast = recast.parse(indexCode, { parser: require('recast/parsers/typescript') });
|
const ast = recast.parse(indexCode, { parser: require('recast/parsers/typescript') });
|
||||||
const result = typeAssertion({ ast, indexPath });
|
const result = typeAssertion({ ast, indexPath });
|
||||||
@ -41,12 +48,12 @@ export const resolveAppPackages = (app: App) => {
|
|||||||
if (entry.value) valueMap[key] = entry.value;
|
if (entry.value) valueMap[key] = entry.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (result.type === PackageType.COMPONENT) {
|
if (result.type === PackageType.COMPONENT && key) {
|
||||||
// 组件
|
// 组件
|
||||||
setItem(key, parseEntry({ ast, package: packagePath, indexPath }));
|
setItem(key, parseEntry({ ast, package: moduleName, indexPath }));
|
||||||
} else if (result.type === PackageType.PLUGIN) {
|
} else if (result.type === PackageType.PLUGIN && key) {
|
||||||
// 插件
|
// 插件
|
||||||
pluginMap[key] = packagePath;
|
pluginMap[key] = moduleName;
|
||||||
} else if (result.type === PackageType.COMPONENT_PACKAGE) {
|
} else if (result.type === PackageType.COMPONENT_PACKAGE) {
|
||||||
// 组件&插件包
|
// 组件&插件包
|
||||||
result.imports.forEach((i) => {
|
result.imports.forEach((i) => {
|
||||||
@ -66,6 +73,52 @@ export const resolveAppPackages = (app: App) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDependencies = (packagePath: string) => {
|
||||||
|
if (fs.existsSync(packagePath)) return;
|
||||||
|
const { name: moduleName, version } = splitNameVersion(packagePath);
|
||||||
|
if (!moduleName) return;
|
||||||
|
dependencies[moduleName] = version;
|
||||||
|
};
|
||||||
|
|
||||||
|
app.options.packages.forEach((item) => {
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
Object.entries(item).forEach(([, packagePath]) => {
|
||||||
|
getDependencies(packagePath);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getDependencies(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Object.keys(dependencies).length) {
|
||||||
|
const packageFile = path.join(app.options.source, 'package.json');
|
||||||
|
const packageBakFile = path.join(app.options.source, 'package.json.bak');
|
||||||
|
if (fs.existsSync(packageFile)) {
|
||||||
|
fs.copyFileSync(packageFile, packageBakFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
npmInstall(dependencies, app.options.source, app.options.npmConfig);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(packageBakFile)) {
|
||||||
|
fs.unlinkSync(packageFile);
|
||||||
|
fs.renameSync(packageBakFile, packageFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.options.packages.forEach((item) => {
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
Object.entries(item).forEach(([key, packagePath]) => {
|
||||||
|
setPackages(app.options.source, packagePath, key);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setPackages(app.options.source, item);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -77,16 +130,27 @@ export const resolveAppPackages = (app: App) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const installPackage = function (module: string, cwd: string) {
|
const npmInstall = function (dependencies: Record<string, string>, cwd: string, npmConfig: NpmConfig = {}) {
|
||||||
try {
|
const { client = 'npm', registry = 'https://registry.npmjs.org/' } = npmConfig;
|
||||||
// window下需要将路径中\转换成/
|
const install = {
|
||||||
execSync(`node -e "require.resolve('${module.replace(/\\/g, '/')}')"`, { stdio: 'ignore' });
|
npm: 'install',
|
||||||
} catch (e) {
|
yarn: 'add',
|
||||||
execSync(`npm install ${module}`, {
|
pnpm: 'add',
|
||||||
|
}[client];
|
||||||
|
|
||||||
|
const packages = Object.entries(dependencies)
|
||||||
|
.map(([name, version]) => `${name}@${version}`)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
const command = `${client} ${install} ${packages} --registry ${registry}`;
|
||||||
|
|
||||||
|
console.log(chalk.blue(cwd));
|
||||||
|
console.log(chalk.blue(command));
|
||||||
|
|
||||||
|
execSync(command, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
cwd,
|
cwd,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -362,3 +426,20 @@ const getASTTokenByTraverse = ({ ast, indexPath }: { ast: any; indexPath: string
|
|||||||
exportDefaultToken,
|
exportDefaultToken,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const splitNameVersion = function (str: string) {
|
||||||
|
if (typeof str !== 'string') {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const packStr = String.prototype.trim.call(str);
|
||||||
|
const ret = packStr.match(/((^|@).+)@(.+)/);
|
||||||
|
let name = packStr;
|
||||||
|
let version = 'latest';
|
||||||
|
if (ret && ret[3] !== '') {
|
||||||
|
({ 1: name, 3: version } = ret);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user