@luban-cli/cli-plugin-service
Version:
A development runtime environment dependency
215 lines • 9.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Service = void 0;
const Config = require("webpack-chain");
const webpack_merge_1 = __importDefault(require("webpack-merge"));
const cli_shared_utils_1 = require("@luban-cli/cli-shared-utils");
const globby_1 = __importDefault(require("globby"));
const loadAndSetEnv_1 = require("../utils/loadAndSetEnv");
const loadProjectConfig_1 = require("../utils/loadProjectConfig");
const loadMockConfig_1 = require("../utils/loadMockConfig");
const pkg_1 = require("../utils/pkg");
const defaultInstance_1 = require("../utils/defaultInstance");
const PluginAPI_1 = require("./PluginAPI");
const options_1 = require("./options");
const constant_1 = require("./constant");
const produce_1 = require("./produce");
class Service {
constructor(context) {
this._context = context;
this._commands = {};
this.pkg = pkg_1.resolvePkg(this.context);
this.rootOptions = pkg_1.resolveLubanConfig(this.pkg);
this.PROJECT_CONFIG_FILE_NAME = "luban.config.ts";
this.PROJECT_MOCK_CONFIG_FILE_NAME = "mock/index.js";
this.webpackConfigQueue = new Map();
this.webpackConfigQueue.set("public", {
id: "public",
config: new Config(),
chainCallback: [],
rawCallback: [],
});
this.mockConfig = undefined;
}
init(mode, commandName, args, rawArgv) {
return __awaiter(this, void 0, void 0, function* () {
this.mode = mode;
loadAndSetEnv_1.loadAndSetEnv(this.mode, this.context, commandName);
this.commandPlugins = yield this.resolveCommandPlugins();
this.configPlugins = yield this.resolveConfigPlugins();
const loadedProjectConfig = loadProjectConfig_1.loadProjectOptions(this.context, this.PROJECT_CONFIG_FILE_NAME);
this.projectConfig = options_1.mergeProjectOptions(loadedProjectConfig, this.rootOptions);
this.commandPlugins.forEach(({ id, instance }) => {
if (typeof instance.addWebpackConfig === "function") {
const _api = new PluginAPI_1.CommandPluginAPI(id, this);
instance.addWebpackConfig({ api: _api, projectConfig: this.projectConfig });
}
});
if (typeof this.projectConfig.configureWebpack === "function") {
this.webpackConfigQueue.forEach((q) => {
if (q.id !== "public") {
q.rawCallback.push(this.projectConfig.configureWebpack);
}
});
}
this.mockConfig = loadMockConfig_1.loadMockConfig(this.context, this.PROJECT_MOCK_CONFIG_FILE_NAME, this.projectConfig.mock);
const commonParams = {
projectConfig: this.projectConfig,
options: this.rootOptions,
mode: this.mode,
commandName,
args,
rawArgv,
};
this.configPlugins.forEach(({ id, instance }) => {
const api = new PluginAPI_1.ConfigPluginAPI(id, this);
instance.apply(Object.assign({ api }, commonParams));
});
this.commandPlugins.forEach(({ id, instance }) => {
const _api = new PluginAPI_1.CommandPluginAPI(id, this);
instance.apply(Object.assign({ api: _api }, commonParams));
});
if (typeof this.projectConfig.chainWebpack === "function") {
this.webpackConfigQueue.forEach((q) => {
if (q.id !== "public") {
q.chainCallback.push(this.projectConfig.chainWebpack);
}
});
}
});
}
run(name, args = { _: [] }, rawArgv = []) {
return __awaiter(this, void 0, void 0, function* () {
if (!name) {
cli_shared_utils_1.error(`please specify command name`);
process.exit(1);
}
const mode = args.mode || (name === "build" ? "production" : "development");
if (name === "serve" || name === "build") {
yield produce_1.produce();
}
yield this.init(mode, name, args, rawArgv);
// after init, all command registered
args._ = args._ || [];
let command = this._commands[name];
if (!constant_1.builtinServiceCommandNameList.has(name) || args.help) {
command = this._commands.help;
}
else {
args._.shift();
rawArgv.shift();
}
const { commandCallback } = command;
return Promise.resolve(commandCallback());
});
}
resolveCommandPlugins() {
return __awaiter(this, void 0, void 0, function* () {
const builtInCommandPluginsPath = yield globby_1.default("../commands/*.js", {
cwd: __dirname,
});
const idToPlugin = (id) => {
const Instance = require(id).default;
return {
id: id.replace(/^.\//, "built-in:"),
instance: new Instance(),
};
};
return builtInCommandPluginsPath.map(idToPlugin);
});
}
resolveConfigPlugins() {
return __awaiter(this, void 0, void 0, function* () {
const loadPluginServiceWithWarn = (id) => {
let serviceApply = undefined;
try {
serviceApply = cli_shared_utils_1.loadFile(`${id}/dist/index.js`);
}
catch (e) {
// `service of plugin [${id}] not found while resolving plugin, use default service function instead`,
}
return serviceApply || defaultInstance_1.DefaultInstance;
};
const prefixRE = /^-cli\/cli-plugin-/;
const idToPlugin = (id) => {
const Instance = prefixRE.test(id)
? loadPluginServiceWithWarn(id)
: require(id).default || defaultInstance_1.DefaultInstance;
return {
id: id.replace(/^.\//, "built-in:"),
instance: new Instance(),
};
};
const builtInConfigPluginsPath = yield globby_1.default("../config/*.js", {
cwd: __dirname,
});
const builtInConfigPlugins = builtInConfigPluginsPath.map(idToPlugin);
const pluginList = this.pkg.__luban_config__ ? this.pkg.__luban_config__.plugins : {};
const projectPlugins = Object.keys(pluginList)
.filter((p) => prefixRE.test(p))
.map(idToPlugin);
return builtInConfigPlugins.concat(projectPlugins);
});
}
resolveChainableWebpackConfig(name) {
const configQueue = this.webpackConfigQueue.get(name);
configQueue === null || configQueue === void 0 ? void 0 : configQueue.chainCallback.forEach((fn) => {
if ((configQueue === null || configQueue === void 0 ? void 0 : configQueue.id) === "public") {
return;
}
fn(configQueue.config, configQueue.id);
});
return configQueue === null || configQueue === void 0 ? void 0 : configQueue.config;
}
resolveWebpackConfig(name) {
const chainableConfig = this.resolveChainableWebpackConfig(name);
if (chainableConfig) {
let config = chainableConfig.toConfig();
const configQueue = this.webpackConfigQueue.get(name);
configQueue === null || configQueue === void 0 ? void 0 : configQueue.rawCallback.forEach((fn) => {
if ((configQueue === null || configQueue === void 0 ? void 0 : configQueue.id) === "public") {
return;
}
if (typeof fn === "function") {
// we pass whole config object, so user can modify parsed webpack config
// but in 'luban.config.ts' just allow modify ‘module’ 'plugins' 'externals', because we have type check
const result = fn(config, configQueue.id);
if (result) {
config = webpack_merge_1.default(config, result);
}
}
});
return config;
}
}
addWebpackConfigQueueItem(name) {
const config = new Config();
config.name(name);
this.webpackConfigQueue.set(name, {
id: name,
config,
chainCallback: [],
rawCallback: [],
});
}
get context() {
return this._context;
}
get commands() {
return this._commands;
}
}
exports.Service = Service;
//# sourceMappingURL=Service.js.map