Skip to content

Commit

Permalink
chore: update compile and dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Xu22Web committed Feb 12, 2023
1 parent 3e8b9a8 commit fb4dba2
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 137 deletions.
303 changes: 188 additions & 115 deletions bin/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import chalk from 'chalk';
import fs from 'fs';
import ora from 'ora';
import path from 'path';
import rollup from 'rollup';
import ts from 'typescript';
import ora from 'ora';
import chalk from 'chalk';
import SCRIPT_CONFIG from '../src/config/script';
import COMPILE_CONFIG from '../src/config/compile';
import SCRIPT_CONFIG from '../src/config/script';
// 根目录 文件名
const { rootDir, file, outDir } = COMPILE_CONFIG;
// 文件路径
const sourceFilePath = file;
const { input, output, rollupConfig, compress } = COMPILE_CONFIG;
// 输入文件路径
const inputFilePath = input.file;
// 输入目录名
const inputDirPath = path.dirname(input.file);
// 输出文件路径
const outputFilePath = output.file;
// 输出目录名
const outputDirPath = path.dirname(output.file);
// 导入路径
const importFilePaths: string[] = [];
// 缓存
const cache: {
[key: string]: { timeStamp: string; data: string; from: string; to: string };
} = JSON.parse(fs.readFileSync('cache.json', { encoding: 'utf-8' })) || {};

/**
* @description 编译
* @param filePath
Expand All @@ -22,81 +34,89 @@ const handleCompile = async (
| {
data: string;
compileName: string;
compiltPath: string;
compiltelativePath: string;
originName: string;
originPath: string;
originRelativePath: string;
}
| undefined
> => {
// 后缀
const ext = path.extname(filePath);
// 完整路径
const fullFilePath = path.resolve(rootDir, filePath);
// 全路径
const fullFilePath = path.resolve(filePath);
// 文件名
const fileName = getFileName(filePath);
// 创建配置
const options = createOptions(fullFilePath);
// 创建项目
const program = ts.createIncrementalProgram(options);
// 根据项目配置获取源文件
const sourceFile = program.getSourceFile(fullFilePath);
// 自定义处理流程
const customTransformers: ts.CustomTransformers = {
before: [transformerFactory],
};
return new Promise((resolve) => {
// 编译生成
program.emit(
sourceFile,
(name, text) => {
// 编译后的文件数据
const data = text.replace(/export (\{.*\}|default .*);/g, '');
// 编译后的文件名
const compileName = getFileName(name);

resolve({
data,
compileName,
originName: fileName,
originPath: fullFilePath,
originRelativePath: filePath,
});
},
undefined,
false,
customTransformers
);
});
};
/**
* @description 解析模块
* @param filePath
* @returns
*/
const resoveModule = async (
rawModulePath: string
): Promise<{
modulePath: string;
time: string | undefined;
stats: boolean;
}> => {
// 文件路径
const modulePath = path.join(rawModulePath);
// 后缀
const ext = path.extname(modulePath);
// 文件名
const fileName = getFileName(modulePath);
// 路径存在状态
const exists = handleFileStatus(fullFilePath);
// 不存在 检查index.ts
if (!exists) {
if (!ext.length) {
// 加后缀
const res = await handleCompile(`${filePath}.ts`);
if (res) {
const { stats, time } = handleFileStatus(modulePath);
// 文件存在
if (stats) {
return { modulePath, time, stats };
}
// 存在扩展
if (!ext.length) {
// 加后缀
const res = await resoveModule(`${modulePath}.ts`);
if (res.stats) {
return res;
}
if (fileName !== 'index.ts') {
const res = await resoveModule(`${modulePath}/index.ts`);
if (res.stats) {
return res;
}
if (fileName !== 'index.ts') {
const res = await handleCompile(`${filePath}/index.ts`);
if (res) {
return res;
}
}
}
return;
}
// 是文件
if (exists) {
// 创建配置
const options = createOptions(fullFilePath);
// 创建项目
const program = ts.createIncrementalProgram(options);
// 根据项目配置获取源文件
const sourceFile = program.getSourceFile(fullFilePath);
// 自定义处理流程
const customTransformers: ts.CustomTransformers = {
before: [transformerFactory],
};
return new Promise((resolve) => {
// 编译生成
program.emit(
sourceFile,
(name, text) => {
// 编译后的文件数据
const data = text.replace(/export (\{.*\}|default .*);/g, '');
// 编译后的文件名
const compileName = getFileName(name);
// 编译路径
const compiltPath = path.resolve(rootDir, outDir, compileName);
// 相对
const compiltelativePath = path.join(rootDir, outDir, compileName);
resolve({
data,
compileName,
compiltPath,
compiltelativePath,
originName: fileName,
originPath: fullFilePath,
originRelativePath: filePath,
});
},
undefined,
false,
customTransformers
);
});
}
return;
return { modulePath, time, stats };
};
/**
* @description 获取文件名
Expand All @@ -120,25 +140,26 @@ const handleFileStatus = (filePath: string) => {
const fileInfo = fs.statSync(filePath);
// 是文件
if (fileInfo.isFile()) {
return true;
const { mtime } = fileInfo;
return { stats: true, time: mtime.toJSON() };
}
}
return false;
return { stats: false };
};
/**
* @description 生成配置
* @param filePath
* @returns
*/
const createOptions = (filePath: string): ts.CreateProgramOptions => {
const { target, module, outDir } = COMPILE_CONFIG;
const { target, module } = COMPILE_CONFIG;
// 项目配置
const programOptions = {
rootNames: [filePath],
options: {
target,
module,
outDir,
outputDirPath,
},
};
return programOptions;
Expand All @@ -147,7 +168,7 @@ const createOptions = (filePath: string): ts.CreateProgramOptions => {
* @description 创建用户脚本注释配置
* @returns
*/
const createCommentConfig = () => {
const createConfigComment = () => {
// 脚本数据
const data: string[] = [];
data.push('// ==UserScript==');
Expand All @@ -162,7 +183,7 @@ const createCommentConfig = () => {
}
}
data.push('// ==/UserScript==');
return data.join('\n');
return data.join('\r\n');
};
// 处理流程工厂
const transformerFactory: ts.TransformerFactory<ts.SourceFile> = (context) => {
Expand All @@ -185,7 +206,7 @@ const transformerFactory: ts.TransformerFactory<ts.SourceFile> = (context) => {
// 提取模块相对路径
const [relativefilePath] = rawSpecificPath;
// 获取实际路径
const filePath = path.resolve(rootDir, relativefilePath);
const filePath = path.resolve(inputDirPath, relativefilePath);
// 获取文本信息
const content = fs
.readFileSync(filePath, {
Expand Down Expand Up @@ -238,59 +259,111 @@ const transformerFactory: ts.TransformerFactory<ts.SourceFile> = (context) => {
// 主函数
const main = async () => {
// 开始编译
const progress = ora('准备编译生成脚本文件!');
progress.start(`正在编译... ${chalk.blueBright(file)}`);
// 编译
const res = await handleCompile(sourceFilePath);
const progress = ora('准备编译生成脚本文件...');
// 数据
const fullData: string[] = [];

// 注释
progress.start(`正在生成 ${chalk.blueBright('用户脚本配置')} 注释...`);
// 用户脚本注释配置
const config = createConfigComment();
fullData.push(config);
// 注释
progress.succeed(`已生成 ${chalk.blueBright('用户脚本配置')} 注释!`);

// 解析模块
const { modulePath } = await resoveModule(inputFilePath);
progress.start(`正在编译... ${chalk.blueBright(modulePath)}`);
// 编译
const res = await handleCompile(modulePath);
if (res) {
// 编译信息
const {
originRelativePath,
compileName,
compiltPath,
compiltelativePath,
data,
} = res;
const { compileName, data } = res;
// 脚本内容
const content: string[] = [];
content.push(data);
progress.succeed(
`完成编译: ${chalk.blueBright(originRelativePath)} -> ${chalk.blueBright(
`完成编译: ${chalk.blueBright(modulePath)} -> ${chalk.blueBright(
compileName
)}`
);
// 数据
const fullData: string[] = [];
// 注释
progress.start(`正在生成${chalk.blueBright('用户脚本配置')}注释...`);
// 用户脚本注释配置
const config = createCommentConfig();
// 注释
progress.start(`已生成${chalk.blueBright('用户脚本配置')}注释!`);
fullData.push(config);
// 编译相对路径
const compileRelativePath = path.join(inputDirPath, compileName);

// 源文件名 编译文件名 数据
for (const i in importFilePaths) {
const filePath = importFilePaths[i];
progress.start(`正在编译... ${chalk.blueBright(filePath)}`);
// 编译
const res = await handleCompile(filePath);
if (res) {
// 编译信息
const { originRelativePath, data: importData } = res;
progress.succeed(
`完成编译: ${chalk.blueBright(
originRelativePath
)} -> ${chalk.blueBright(compileName)}`
);
fullData.push(importData);
continue;
// 相对路径
const relativefilePath = importFilePaths[i];
// 文件路径
const filePath = path.join(inputDirPath, relativefilePath);
// 解析模块
const { time, modulePath, stats } = await resoveModule(filePath);

progress.start(`正在编译... ${chalk.blueBright(modulePath)}`);
// 存在模块
if (stats) {
// 缓存
if (cache[modulePath]) {
const { timeStamp, from, to } = cache[modulePath];
if (time === timeStamp) {
// 缓存取数据
content.push(cache[modulePath].data);
progress.succeed(
`缓存编译: ${chalk.blueBright(from)} -> ${chalk.blueBright(to)}`
);
continue;
}
}

// 编译
const res = await handleCompile(modulePath);
if (res) {
// 编译信息
const { originRelativePath, compileName, data } = res;
content.push(data);
// 缓存
cache[modulePath] = {
timeStamp: <string>time,
data,
from: originRelativePath,
to: compileName,
};
progress.succeed(
`直接编译: ${chalk.blueBright(
originRelativePath
)} -> ${chalk.blueBright(compileName)}`
);
continue;
}
}
progress.fail(`编译失败,请检查导入文件路径!`);
progress.fail(`编译失败: ${chalk.red(filePath)}, 请检查导入文件路径!`);
break;
}
fullData.push(data);

progress.start(`正在导出文件... ${chalk.blueBright(compiltPath)}`);
fs.writeFileSync(compiltPath, fullData.join('\n').replace(/\n{2,}/, '\n'));
progress.succeed(`导出文件: ${chalk.blueBright(compiltelativePath)}`);
progress.start(`正在生成js文件...`);
// 生成js文件
fs.writeFileSync(compileRelativePath, content.join('\r\n'));
progress.succeed(`生成js文件成功!`);

if (compress) {
progress.start(`正在压缩js文件...`);
// rollup 压缩
const bundle = await rollup.rollup(rollupConfig.inputOptions);
const { output } = await bundle.write(rollupConfig.outputOptions);
fullData.push(output[0].code);
progress.succeed(`压缩js文件成功!`);
} else {
fullData.push(content.join('\r\n').replace(/(\r\n){2,}/g, '\r\n'));
}

progress.start(
`正在导出整合的脚本文件... ${chalk.blueBright(outputFilePath)}`
);
// 导出文件
fs.writeFileSync('cache.json', JSON.stringify(cache));
// 导出文件
fs.writeFileSync(outputFilePath, fullData.join('\r\n'));
progress.succeed(`导出整合的脚本文件: ${chalk.blueBright(outputFilePath)}`);
return;
}
progress.fail(`编译失败,请检查文件路径!`);
Expand Down
1 change: 1 addition & 0 deletions cache.json

Large diffs are not rendered by default.

Loading

0 comments on commit fb4dba2

Please sign in to comment.