@wgoo/cli
Version:
Wgoo Cli 是一个 React 组件库构建工具,通过 Wgoo Cli 可以快速搭建一套功能完备的 React 组件库。
216 lines (183 loc) • 5.03 kB
JavaScript
const execa = require('execa');
const chokidar = require('chokidar');
const { join, relative } = require('path');
const { remove, copy, readdirSync, existsSync } = require('fs-extra');
const { clean } = require('./clean');
const { CSS_LANG } = require('../common/css');
const { ora, consola, slimPath } = require('../common/logger');
const { installDependencies } = require('../common/manager');
const { compileJs } = require('../compiler/compile-js');
const { compileStyle } = require('../compiler/compile-style');
const { compilePackage } = require('../compiler/compile-package');
const { genPackageEntry } = require('../compiler/gen-package-entry');
const { genStyleDepsMap } = require('../compiler/gen-style-deps-map');
const { genComponentStyle } = require('../compiler/gen-component-style');
const { SRC_DIR, LIB_DIR, ES_DIR } = require('../common/constant');
const { genPackageStyle } = require('../compiler/gen-package-style');
const {
isDir,
isStyle,
isScript,
isDemoDir,
isTestDir,
setNodeEnv,
setModuleEnv,
setBuildTarget,
} = require('../common');
async function compileFile(filePath) {
if (isScript(filePath)) {
return compileJs(filePath);
}
if (isStyle(filePath)) {
return compileStyle(filePath);
}
return remove(filePath);
}
async function compileDir(dir) {
const files = readdirSync(dir);
await Promise.all(
files.map((filename) => {
const filePath = join(dir, filename);
if (isDemoDir(filePath) || isTestDir(filePath)) {
return remove(filePath);
}
if (isDir(filePath)) {
return compileDir(filePath);
}
return compileFile(filePath);
})
);
}
async function copySourceCode() {
await copy(SRC_DIR, ES_DIR);
await copy(SRC_DIR, LIB_DIR);
}
async function buildESMOutputs() {
setModuleEnv('esmodule');
setBuildTarget('package');
await compileDir(ES_DIR);
}
async function buildCJSOutputs() {
setModuleEnv('commonjs');
setBuildTarget('package');
await compileDir(LIB_DIR);
}
async function buildTypeDeclarations() {
const tsConfig = join(process.cwd(), 'tsconfig.declaration.json');
if (existsSync(tsConfig)) {
await execa('tsc', ['-p', tsConfig]);
}
}
async function buildStyleEntry() {
await genStyleDepsMap();
genComponentStyle();
}
async function buildPackageScriptEntry() {
const esEntryFile = join(ES_DIR, 'index.js');
const libEntryFile = join(LIB_DIR, 'index.js');
genPackageEntry({
outputPath: esEntryFile,
pathResolver: (path) => `./${relative(SRC_DIR, path)}`,
});
await copy(esEntryFile, libEntryFile);
}
async function buildPackageStyleEntry() {
const styleEntryFile = join(LIB_DIR, `index.${CSS_LANG}`);
genPackageStyle({
outputPath: styleEntryFile,
pathResolver: (path) => path.replace(SRC_DIR, '.'),
});
}
async function buildBundledOutputs() {
setModuleEnv('esmodule');
await compilePackage(false);
await compilePackage(true);
}
const tasks = [
{
text: 'Copy Source Code',
task: copySourceCode,
},
{
text: 'Build Package Script Entry',
task: buildPackageScriptEntry,
},
{
text: 'Build Component Style Entry',
task: buildStyleEntry,
},
{
text: 'Build Package Style Entry',
task: buildPackageStyleEntry,
},
{
text: 'Build Type Declarations',
task: buildTypeDeclarations,
},
{
text: 'Build ESModule Outputs',
task: buildESMOutputs,
},
{
text: 'Build CommonJS Outputs',
task: buildCJSOutputs,
},
{
text: 'Build Bundled Outputs',
task: buildBundledOutputs,
},
];
async function runBuildTasks() {
for (let i = 0; i < tasks.length; i++) {
const { task, text } = tasks[i];
const spinner = ora(text).start();
try {
/* eslint-disable no-await-in-loop */
await task();
spinner.succeed(text);
} catch (err) {
spinner.fail(text);
console.log(err);
throw err;
}
}
consola.success('Compile successfully');
}
function watchFileChange() {
consola.info('Watching file changes...');
chokidar.watch(SRC_DIR).on('change', async (path) => {
if (isDemoDir(path) || isTestDir(path)) {
return;
}
const spinner = ora('File changed, start compilation...').start();
const esPath = path.replace(SRC_DIR, ES_DIR);
const libPath = path.replace(SRC_DIR, LIB_DIR);
try {
await copy(path, esPath);
await copy(path, libPath);
await compileFile(esPath);
await compileFile(libPath);
await genStyleDepsMap();
genComponentStyle({ cache: false });
spinner.succeed('Compiled: ' + slimPath(path));
} catch (err) {
spinner.fail('Compile failed: ' + path);
console.log(err);
}
});
}
async function build(cmd) {
setNodeEnv('production');
try {
await clean();
await installDependencies();
await runBuildTasks();
if (cmd.watch) {
watchFileChange();
}
} catch (err) {
consola.error('Build failed');
process.exit(1);
}
}
module.exports = { build };