Skip to content

Commit

Permalink
feat(publish): 优化publish,从方法参数取值,而不是node命令行参数
Browse files Browse the repository at this point in the history
  • Loading branch information
novlan1 committed Aug 15, 2023
1 parent 93185fe commit cf5538d
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 125 deletions.
2 changes: 1 addition & 1 deletion src/env-variable/env-variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function getEnvVariableMap(filepath: string) {
* @param {string} filepath 保存环境变量的文件路径
* @returns {string} 环境变量的值
*/
export function readEnvVariable(key: string, filepath: string) {
export function readEnvVariable(key: string, filepath: string): string {
if (!fs.lstatSync(filepath)) {
console.log('[readEnvVariable] 文件不存在:', filepath, ',请先创建文件');
process.exit(1);
Expand Down
20 changes: 20 additions & 0 deletions src/publish/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const ENV_MAP = {
DEV_HOST_NAME: 'DEV_HOST_NAME',
DEV_HOST_PWD: 'DEV_HOST_PWD',

VUE_APP_DIR: 'VUE_APP_DIR',
VUE_APP_AUTHOR: 'VUE_APP_AUTHOR',
VUE_APP_PATH_PROD: 'VUE_APP_PATH_PROD',
VUE_APP_PATH_TEST: 'VUE_APP_PATH_TEST',
} as const;

export const PUBLISH_ENV_MAP = {
PROD: 'prod',
TEST: 'test',
DEV_CLOUD: 'devcloud',
} as const;

export const PUBLISH_HOST_ENV = {
PROD: 'web-static',
TEST: 'web-test',
} as const;
111 changes: 12 additions & 99 deletions src/publish/helper.ts
Original file line number Diff line number Diff line change
@@ -1,109 +1,22 @@
import * as http from 'http';
import * as path from 'path';
import * as fs from 'fs';
import type { IPublishOptions } from './types';
import { readEnvVariable } from '../env-variable/env-variable';


export function postFile(fileDataInfo, fileKeyValue, options?: IPublishOptions) {
return new Promise(((resolve, reject) => {
if (!options) {
console.log('[publish] failed. 需要 options');
return;
}

const req = http.request(options, (res) => {
// res.setEncoding("utf8");
res.on('data', (chunk) => {
const result = JSON.parse(chunk);
console.log('[postFile] result: ', result);
resolve(result);
});
});

req.on('error', (e) => {
console.log(`[postFile] problem with request: ${e.message}`);
reject(e);
});

const boundaryKey = Math.random().toString(16);
const endData = `\r\n----${boundaryKey}--`;

let dataLength = 0;
const dataArr: Array<Record<string, any>> = [];
for (const item of fileDataInfo) {
const dataInfo = `\r\n----${boundaryKey}\r\n` + `Content-Disposition: form-data; name="${item.urlKey}"\r\n\r\n${item.urlValue}`;
const dataBinary = Buffer.from(dataInfo, 'utf-8');
dataLength += dataBinary.length;
dataArr.push({
dataInfo,
});
}

const files: Array<Record<string, any>> = [];
for (const item of fileKeyValue) {
const content = `\r\n----${boundaryKey}\r\n` + 'Content-Type: application/octet-stream\r\n' + `Content-Disposition: form-data; name="${item.urlKey}"; filename="${path.basename(item.urlValue)}"\r\n` + 'Content-Transfer-Encoding: binary\r\n\r\n';
// 当编码为ascii时,中文会乱码。
const contentBinary = Buffer.from(content, 'utf-8');
files.push({
contentBinary,
filePath: item.urlValue,
});
}

let contentLength = 0;
for (const item of files) {
const { filePath } = item;
if (fs.existsSync(filePath)) {
const stat = fs.statSync(filePath);
contentLength += stat.size;
} else {
contentLength += Buffer.from('\r\n', 'utf-8').length;
}
contentLength += item.contentBinary.length;
}
export function getRootDir() {
const rootDir = process.cwd();
return rootDir;
}

req.setHeader('Content-Type', `multipart/form-data; boundary=--${boundaryKey}`);
req.setHeader('Content-Length', dataLength + contentLength + Buffer.byteLength(endData));

// 将参数发出
for (const item of dataArr) {
req.write(item.dataInfo);
}
export function getEnvValue(key: string) {
const rootDir = getRootDir();
const localEnvPath = path.join(rootDir, '.env.local');
const envPath = path.join(rootDir, '.env');

let fileIndex = 0;
const doOneFile = function () {
req.write(files[fileIndex].contentBinary);
const currentFilePath = files[fileIndex].filePath;
if (fs.existsSync(currentFilePath)) {
// @ts-ignore
const fileStream = fs.createReadStream(currentFilePath, { bufferSize: 4 * 1024 });
fileStream.pipe(req, { end: false });

fileStream.on('end', () => {
fileIndex += 1;
if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
});
} else {
req.write('\r\n');
fileIndex += 1;
const envValue = readEnvVariable(key, envPath);
const localEnvValue = readEnvVariable(key, localEnvPath);

if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
}
};

if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
}));
return localEnvValue || envValue || '';
}

109 changes: 109 additions & 0 deletions src/publish/post-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as http from 'http';
import * as path from 'path';
import * as fs from 'fs';
import type { IPublishOptions } from './types';


export function postFile(fileDataInfo, fileKeyValue, options?: IPublishOptions) {
return new Promise(((resolve, reject) => {
if (!options) {
console.log('[publish] failed. 需要 options');
return;
}

const req = http.request(options, (res) => {
// res.setEncoding("utf8");
res.on('data', (chunk) => {
const result = JSON.parse(chunk);
console.log('[postFile] result: ', result);
resolve(result);
});
});

req.on('error', (e) => {
console.log(`[postFile] problem with request: ${e.message}`);
reject(e);
});

const boundaryKey = Math.random().toString(16);
const endData = `\r\n----${boundaryKey}--`;

let dataLength = 0;
const dataArr: Array<Record<string, any>> = [];
for (const item of fileDataInfo) {
const dataInfo = `\r\n----${boundaryKey}\r\n` + `Content-Disposition: form-data; name="${item.urlKey}"\r\n\r\n${item.urlValue}`;
const dataBinary = Buffer.from(dataInfo, 'utf-8');
dataLength += dataBinary.length;
dataArr.push({
dataInfo,
});
}

const files: Array<Record<string, any>> = [];
for (const item of fileKeyValue) {
const content = `\r\n----${boundaryKey}\r\n` + 'Content-Type: application/octet-stream\r\n' + `Content-Disposition: form-data; name="${item.urlKey}"; filename="${path.basename(item.urlValue)}"\r\n` + 'Content-Transfer-Encoding: binary\r\n\r\n';
// 当编码为ascii时,中文会乱码。
const contentBinary = Buffer.from(content, 'utf-8');
files.push({
contentBinary,
filePath: item.urlValue,
});
}

let contentLength = 0;
for (const item of files) {
const { filePath } = item;
if (fs.existsSync(filePath)) {
const stat = fs.statSync(filePath);
contentLength += stat.size;
} else {
contentLength += Buffer.from('\r\n', 'utf-8').length;
}
contentLength += item.contentBinary.length;
}

req.setHeader('Content-Type', `multipart/form-data; boundary=--${boundaryKey}`);
req.setHeader('Content-Length', dataLength + contentLength + Buffer.byteLength(endData));

// 将参数发出
for (const item of dataArr) {
req.write(item.dataInfo);
}

let fileIndex = 0;
const doOneFile = function () {
req.write(files[fileIndex].contentBinary);
const currentFilePath = files[fileIndex].filePath;
if (fs.existsSync(currentFilePath)) {
// @ts-ignore
const fileStream = fs.createReadStream(currentFilePath, { bufferSize: 4 * 1024 });
fileStream.pipe(req, { end: false });

fileStream.on('end', () => {
fileIndex += 1;
if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
});
} else {
req.write('\r\n');
fileIndex += 1;

if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
}
};

if (fileIndex === files.length) {
req.end(endData);
} else {
doOneFile();
}
}));
}

44 changes: 19 additions & 25 deletions src/publish/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@ import * as path from 'path';
import { spawnSync } from 'child_process';

import { getIPAddress, getIPAddressStr } from '../ip/ip';
import { readEnvVariable } from '../env-variable/env-variable';

import { postFile } from './helper';
import { getRootDir, getEnvValue } from './helper';
import { postFile } from './post-file';
import { ENV_MAP, PUBLISH_ENV_MAP, PUBLISH_HOST_ENV } from './config';
import type { IPublishOptions } from './types';

const rootDir = process.cwd();

const localEnvPath = path.join(rootDir, '.env.local');
const envPath = path.join(rootDir, '.env');


const rootDir = getRootDir();
const PUBLISH_BASH_FILE = path.resolve(__dirname, '../script/publish.sh');
const ENV_DEV_HOST_NAME = 'DEV_HOST_NAME';
const ENV_DEV_HOST_PWD = 'DEV_HOST_PWD';


function getDevPwd() {
const devHostName = readEnvVariable(ENV_DEV_HOST_NAME, localEnvPath);
const devHostPwd = readEnvVariable(ENV_DEV_HOST_PWD, localEnvPath);
const devHostName = getEnvValue(ENV_MAP.DEV_HOST_NAME);
const devHostPwd = getEnvValue(ENV_MAP.DEV_HOST_PWD);

return {
devHostName,
devHostPwd,
Expand Down Expand Up @@ -53,20 +48,19 @@ function validate({
return 0;
}
// 禁止本机发布
if ((getIPAddress().indexOf('10.45') === 0 || getIPAddress().indexOf('10.20') === 0) && publishEnv === 'prod') {
if ((getIPAddress().indexOf('10.45') === 0 || getIPAddress().indexOf('10.20') === 0) && publishEnv === PUBLISH_ENV_MAP.PROD) {
console.log('[publish] 禁止在本机发布!');
return;
}
return;
}

export async function localPublish(options: IPublishOptions) {
const dir = readEnvVariable('VUE_APP_DIR', localEnvPath);
const author = readEnvVariable('VUE_APP_AUTHOR', localEnvPath);
const publishPathProd = readEnvVariable('VUE_APP_PATH_PROD', envPath);
const publishPathTest = readEnvVariable('VUE_APP_PATH_TEST', envPath);
const args = process.argv.slice(2);
const publishEnv = args[0];
const dir = getEnvValue(ENV_MAP.VUE_APP_DIR);
const author = getEnvValue(ENV_MAP.VUE_APP_AUTHOR);
const publishPathProd = getEnvValue(ENV_MAP.VUE_APP_PATH_PROD);
const publishPathTest = getEnvValue(ENV_MAP.VUE_APP_PATH_TEST);
const { publishEnv = PUBLISH_ENV_MAP.TEST } = options;

if (!validate({
dir,
Expand Down Expand Up @@ -127,7 +121,7 @@ async function realPublish({
options: IPublishOptions;
}) {
let desc = '';
let env = 'web-test';
let env: string = PUBLISH_HOST_ENV.TEST;

const shell: Record<string, any> = {};
shell.runSync = function (cmd, args, options) {
Expand All @@ -139,17 +133,17 @@ async function realPublish({
};


if (publishEnv === 'prod') {
if (publishEnv === PUBLISH_ENV_MAP.PROD) {
desc = `${publishPathProd}/${moduleName}`;
env = 'web-static';
} else if (publishEnv === 'devcloud') {
env = PUBLISH_HOST_ENV.PROD;
} else if (publishEnv === PUBLISH_ENV_MAP.DEV_CLOUD) {
const {
devHostName,
devHostPwd,
} = getDevPwd();

if (!devHostName || !devHostPwd) {
console.log('[publish] failed: ', `没有找到有效的 ${ENV_DEV_HOST_NAME}${ENV_DEV_HOST_PWD}`);
console.log('[publish] failed: ', `没有找到有效的 ${ENV_MAP.DEV_HOST_NAME}${ENV_MAP.DEV_HOST_PWD}`);
return;
}

Expand All @@ -163,7 +157,7 @@ async function realPublish({
return;
} else {
desc = `${publishPathTest}/${moduleName}`;
env = 'web-test';
env = PUBLISH_HOST_ENV.TEST;
}

const fileDataInfo = [
Expand Down
1 change: 1 addition & 0 deletions src/publish/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export type IPublishOptions = {
port: string;
path: string;
method?: string;
publishEnv?: string;
};

0 comments on commit cf5538d

Please sign in to comment.