@aniyajs/rotor
Version:
基于webpack5开发的一款专注于打包、运行的工具
164 lines (139 loc) • 4.82 kB
JavaScript
;
// 确定当前构建环境
process.env.NODE_ENV = "production";
// 抛出所有未被捕获的错误
process.on("unhandledRejection", (error) => {
throw error;
});
const fs = require('fs-extra');
const path = require('path');
const { fork } = require('child_process');
const chalk = require('chalk');
const {
isFileExists,
getFilePathsInDirectory,
depthDependFilePaths,
funcOrStr,
} = require('../utils/common.js');
const { initRequireFileHandle, initTempHandle } = require('../utils/initialize.js');
const paths = require('../utils/paths.js');
const PluginGenerator = require("../utils/pluginGenerator");
// 匹配环境变量文件
const envFileReg = /^config\.[a-zA-Z0-9]+\.(ts|js)$/;
// 可忽略的依赖后缀
const dependentSuffixs = [".js", ".jsx", ".ts", ".tsx", ".json", ".less", ".scss", ".sass", ".css"];
// 匹配隐藏文件
const hiddenFileRule = /(^|[/\\])\../;
const pluginMainSuffixs = [".ts", ".js"];
// 获取config文件夹中文件
const envConfig = getFilePathsInDirectory(paths.appConfigPath, /^config\.[^.]+/);
// 检查所需文件是否存在 package.json、src/document.ejs
const fileExist = isFileExists([paths.appHtml, paths.appPackageJson], paths.appPath);
if (!fileExist) {
process.exit(1);
}
initRequireFileHandle()
.then(async (isInitRequire) => {
if (!isInitRequire) {
return new Error(null);
}
// 读取config文件深度依赖文件路径
// 过滤隐藏文件
const dependFiles = depthDependFilePaths(
[paths.appConfigJs, ...envConfig],
dependentSuffixs,
hiddenFileRule,
)
const configFiles = [paths.appConfigJs, ...dependFiles];
const memoConfig = require("../webpack/defaultConfig")(false);
// config/config.{js|ts} 文件初始不存在时
// paths.appTempMetaJs 文件写入 @aniyajs/rotor 默认配置
if (!fs.existsSync(paths.appConfigJs)) {
const strConfig = funcOrStr({
...memoConfig,
});
fs.writeJsonSync(
paths.appTempMetaJs,
{
paths: {},
lastConfig: strConfig,
},
{ spaces: 2 },
);
}
// 初始化mock、config配置缓存文件,并拿到config缓存文件的文件及config目录
const initSuccessPaths = await initTempHandle(
envFileReg,
configFiles,
false,
);
if (initSuccessPaths) {
const config = require(initSuccessPaths.appConfigTempIndexJs).default;
let pluginInfos = [];
if (config.aniyaPlugins && config.aniyaPlugins.length) {
const pluginPaths = config.aniyaPlugins.map(pluginRelativePath => path.join(
paths.appNodeModules,
pluginRelativePath,
));
// 检查插件文件是否存在
const pluginFileExist = isFileExists(pluginPaths);
if (pluginFileExist) {
config.aniyaPlugins.forEach((pluginRelativePath) => {
const pluginResolvePath = path.join(
paths.appNodeModules,
pluginRelativePath,
"lib",
);
const extension = pluginMainSuffixs.find((extension) =>
fs.existsSync(`${pluginResolvePath}${extension}`),
);
if (extension) {
const pluginGenertor = new PluginGenerator({
pluginIndex: `${pluginResolvePath}${extension}`,
memoConfig: config,
});
pluginGenertor.initialize();
// 使用局部变量避免污染全局 require
const esmRequire = require("esm")(module);
pluginGenertor.use(
esmRequire(`${pluginResolvePath}${extension}`).default,
);
pluginInfos.push(pluginGenertor.describeParams);
pluginGenertor.ending();
}
});
}
}
const strConfig = funcOrStr({
...memoConfig,
...config
});
fs.writeJsonSync(
paths.appTempMetaJs,
{
paths: initSuccessPaths,
lastConfig: strConfig,
},
{ spaces: 2 },
);
}
const buildProcess = fork(
path.resolve(__dirname, "../webpack/webpackBuild.js"),
{
cwd: process.cwd(),
stdio: "inherit",
},
);
// 监听子进程退出,正确传递退出码
buildProcess.on("exit", (code) => {
process.exit(code || 0);
});
buildProcess.on("error", (err) => {
console.log(chalk.red("Build process error:"), err.message || err);
process.exit(1);
});
})
.catch((error) => {
console.log(error);
process.exit(1);
});