powerful-cli
Version:
封装了webpack功能的命令行接口, 提供serve、build、lib等命令, 支持vue3、js、ts等...
388 lines (381 loc) • 12 kB
TypeScript
import type {Configuration as WebpackConfiguration} from 'webpack';
import type {Configuration as DevConfiguration} from 'webpack-dev-server';
import type FileManagerPlugin from 'filemanager-webpack-plugin';
import type {Options} from 'eslint-webpack-plugin';
import type HtmlWebpackPlugin from 'html-webpack-plugin';
//region 基础类型
type Awaitable<T>=T|Promise<T>;
type Multiable<T>=T|Array<T>;
interface DateLocale{
weeks?:[string,string,string,string,string,string,string];
weeksShort?:[string,string,string,string,string,string,string];
months?:[string,string,string,string,string,string,string,string,string,string,string,string];
monthsShort?:[string,string,string,string,string,string,string,string,string,string,string,string];
quarters?:[string,string,string,string];
am?:string;
pm?:string;
}
interface DateFormatOption{
dateLocale?:DateLocale;
timezoneOffset?:number;
}
//endregion
interface ConfigFnParam<R>{
returnCheck:(r:R) => R;
baseDir:string;
packageJson:Record<string,any>;
args:Record<string,string|number|boolean|undefined>&{_:Array<string>};
command:'build'|'lib'|'serve';
utils:{
extend:(...args:Array<any>) => any;
copyReplace:<T>(v:Array<T>) => Array<T>;
copyCover:<T>(v:T) => T;
copyCustom:<T>(v:(dest:any) => T) => T;
dateFormat:(date:Date,format:string,option?:DateFormatOption) => string;
};
}
type BaseConfig<E>={
//继承的配置文件
extendConfigs:Array<string|FinalConfigFn<any>>;
//读取环境变量的位置, 可以从多个位置读取(叠加)
envPath:Multiable<string>;
//额外的环境变量, 可以覆盖环境文件里的变量
extraEnv:Record<string,string|number|boolean>;
}&E;
interface InjectConfig{
//唯一键, 默认为 package.json 的name字段
unique?:string;
//调试模式
debug:boolean;
//额外的环境变量, 可以覆盖环境文件里的变量
extraEnv:Record<string,string|number|boolean>;
//开发服务器, 参考webpack的配置
devServer:DevConfiguration;
/*
入口js注入封装
[key]:'inject.js' 相当于
{
filename:'inject.js',
preLoad:[],
debug:false,
}
*/
emitEntryInjectJs:Record<string,string|{
//输出js文件名
filename:string;
//预加载js, css
preLoad?:string[];
//是否输出调试信息, 默认为 false
debug?:boolean;
}>;
/*
入口页面
[key]:'src/main.js' 相当于
{
entry:'src/main.js',
template:`template/${key}.html`,
filename:`${key}.html`,
}
*/
pages:Record<string,string|{
//入口文件
entry:string;
//html模板, 文件不存在, 默认为 template/index.html
template?:string;
//当为 false 表示使用 template 选项
templateContent?:HtmlWebpackPlugin.Options['templateContent'];
//html输出文件名, 默认为 index.html
filename?:string;
//html标题, 默认为 package.json 的name字段
title?:string;
//标题图标, 默认为 htmlTemplate.favicon
favicon?:string;
//html是否压缩或压缩选项, 参考 html-minifier-terser, 默认为 htmlTemplate.minify, 或 根据环境判断
minify?:boolean|Record<string,any>|undefined;
//注入到html的变量, 在 htmlTemplate.templateParameters的基础上增加/覆盖
templateParameters?:HtmlWebpackPlugin.Options['templateParameters']|undefined;
//资源注入控制, false需要手动注入, 默认为 htmlTemplate.inject
inject?:boolean|'head'|'body'|undefined;
//资源的公共路径
publicPath?:string;
//对应html的<base>节点
base?:string|Record<string,string>;
//对应html的<meta>节点
meta?:Record<string,string>;
//是否生成html, 默认为 true
html?:boolean;
}>;
//html模板
htmlTemplate:{
//标题图标
favicon:string;
//html是否压缩或压缩选项, 参考 html-minifier-terser
minify?:boolean|Record<string,any>|undefined;
//注入到html的变量(全局注入)
templateParameters:HtmlWebpackPlugin.Options['templateParameters'];
//资源注入控制, false需要手动注入
inject:boolean|'head'|'body';
};
//outputDir所代表的: 绝对路径(包括URL), 相对路径, '//域名'(用于保持协议相同), 'auto'
publicPath:string;
//输出地址
outputDir:string;
//资源地址
assetsDir:string;
//别名
alias:Record<string,string | false>;
//打包信息文件
buildFile:{
//是否生成信息文件
emit:boolean;
//文件名
name:string;
//文件内容, 数组被换行拼接
content:Multiable<string>;
};
//生成文件, 键是文件名, 值是文件内容(null和undefined表示不生成)
emitFiles:Record<string,null|undefined|Multiable<string>>;
//替换标记
definePlugin:Record<string,string>;
//开发者调试面板
vConsole:{
//是否启用
active:boolean;
//是否启用vue插件
vue:boolean;
},
//build命令下的配置
buildConfig:{
//信息输出格式
buildConsole:'normal'|'raw';
//代码压缩
minimize:boolean|'swc';
/*
源图
eval-source-map
eval-nosources-source-map
source-map
nosources-source-map
inline-source-map
inline-nosources-source-map
hidden-source-map
hidden-nosources-source-map
*/
sourceMap:boolean|string;
//生成css源图
cssSourceMap:boolean;
//保留源码中的console语句
sourceLog:boolean;
};
//lib命令下的配置
libConfig:{
html:{
//html模板, 文件不存在, 默认为 template/index.html
template?:string;
//当为 false 表示使用 template 选项
templateContent?:HtmlWebpackPlugin.Options['templateContent'];
//html输出文件名, 默认为 index.html
filename?:string;
//html标题, 默认为 config.libConfig.name + '库'
title?:string;
//标题图标, 默认为 htmlTemplate.favicon
favicon?:string;
//html是否压缩或压缩选项, 参考 html-minifier-terser, 默认为 htmlTemplate.minify, 或 true
minify?:boolean|Record<string,any>|undefined;
//注入到html的变量, 在 htmlTemplate.templateParameters的基础上增加/覆盖
templateParameters?:HtmlWebpackPlugin.Options['templateParameters']|undefined;
//资源注入控制, false需要手动注入, 默认为 htmlTemplate.inject
inject?:boolean|'head'|'body'|undefined;
//资源的公共路径
publicPath?:string;
//对应html的<base>节点
base?:string|Record<string,string>;
//对应html的<meta>节点
meta?:Record<string,string>;
//script标签加载模式
scriptLoading:'blocking'|'defer'|'module';
};
//信息输出格式
buildConsole:'normal'|'raw';
//库名称, 默认为 package.json 的name字段
name:string;
//入口文件
entry:string;
//代码压缩
minimize:boolean|'swc';
/*
源图
eval-source-map
eval-nosources-source-map
source-map
nosources-source-map
inline-source-map
inline-nosources-source-map
hidden-source-map
hidden-nosources-source-map
*/
sourceMap:boolean|string;
//生成css源图
cssSourceMap:boolean;
//保留源码中的console语句
sourceLog:boolean;
//外部依赖
externals:WebpackConfiguration['externals'];
//暴露的导出
export:Multiable<string>|undefined;
//添加所有需要的依赖
polyfillAll?:boolean;
//是否启用异步 chunk, 默认为 false
asyncChunks?:boolean;
};
terserOptions:{
default?:Record<string,any>;
swc?:Record<string,any>;
};
//静态资源拷贝
copy:{
//拷贝路径
dir:string|Record<string,{
//不存在, 默认为全局 to
to?:string
|(
(
pathData:{context:string;absoluteFilename?:string},
globalTo?:(pathData:{context:string;absoluteFilename?:string}) => Awaitable<string>,
) => Awaitable<string>
)
|undefined;
//不存在, 默认为全局 toType
toType?:'dir'|'file'|'template'|undefined;
//值越小越先执行, 默认 0
priority?:number;
//不存在, 默认为全局 minimize
minimize?:boolean;
//不存在, 默认为全局 filter
filter?:Multiable<
(
(
absolutePath:string,
relativePath:string,
globalFilter?:(absolutePath:string,relativePath:string) => Awaitable<boolean>,
) => Awaitable<boolean>
)
|RegExp
>|undefined;
//不存在, 默认为全局 transformer
transformer?:Multiable<
(
(
content:Buffer,
absolutePath:string,
relativePath:string,
globalTransformer?:(content:Buffer,absolutePath:string,relativePath:string) => Awaitable<string|Buffer>
) => Awaitable<string|Buffer>
)
>|undefined;
}>;
//目标路径
to?:string|((pathData:{context:string;absoluteFilename?:string}) => Awaitable<string>)|undefined;
//目标路径类型
toType?:'dir'|'file'|'template'|undefined;
//是否压缩
minimize:boolean;
//只拷贝返回true的资源
filter?:Multiable<((absolutePath:string,relativePath:string) => Awaitable<boolean>)|RegExp>|undefined;
//内容转换器
transformer?:Multiable<((content:Buffer,absolutePath:string,relativePath:string) => Awaitable<string|Buffer>)>|undefined;
};
//js转义配置
babel:{
//@babel/preset-env的选项
presetOption:{
[k:string]:any;
//使用的browserslist环境
browserslistEnv?:string|undefined;
//打印启用的 polyfills 和 transform plugins
debug:boolean;
/*
如何处理 polyfill
usage 自动导入用到的 polyfill
entry 自己在入口处导入 polyfill, 程序根据目标环境剔除不必要的
false 不做处理(完全自己导入)
*/
useBuiltIns:'usage'|'entry'|false;
};
//插件
plugins:Array<any>;
//必要依赖
polyfills:Array<string>|true;
//其他依赖(不会加 core-js/ 前缀)
extraPolyfills?:Array<string>;
//需要转义的依赖
transpileDependencies:Array<string|RegExp>;
//额外的入口(需要注入polyfills的地方)
extraEntry:Array<string|RegExp>;
}
//typescript相关配置
typescript:{
//是否启用类型检查
active:boolean;
//tsconfig.json 路径, 默认为项目根目录下的 tsconfig.json
configFile?:string;
};
//代码格式校验
eslint:Options&{
//是否启用
active:boolean;
};
//markdown转vue配置
markdown:{
//注入的组件, 键是组件名, 值是路径
components?:Record<string, string>;
//不同元素的class名, 键是元素名, 值是class名
elementClassName?:Record<string, string>;
//引入的css
cssModules?:string[];
};
css:{
//css预处理
preprocessor?:(content:string) => Awaitable<string>;
};
//分包配置
cacheGroups:Exclude<
Exclude<
WebpackConfiguration['optimization'],
undefined
>['splitChunks'],
false|undefined
>['cacheGroups'];
splitChunks:Exclude<
WebpackConfiguration['optimization'],
undefined
>['splitChunks'];
//包分析报告配置
report:{
//是否生成报告文件
emit:boolean;
//分析文件类型
type:'html'|'json';
//文件名
filename:string;
//webpack的Stats配置
statsOptions:WebpackConfiguration['stats']|null;
},
//参考 filemanager-webpack-plugin
fileManager?:ConstructorParameters<typeof FileManagerPlugin>[number]|undefined;
//webpack的配置
webpackConfig:WebpackConfiguration;
}
//此方法中注入了环境变量以及合并后配置,返回的值被用于再次合并配置
type InjectFn<E>=(param:BaseConfig<E>&ConfigFnParam<Partial<InjectConfig>>) => Awaitable<Partial<InjectConfig>>;
type FinalConfig<E>=BaseConfig<E>&{
injectFns:Array<InjectFn<E>>;
}
type BaseConfigFn<E>=(param:ConfigFnParam<Partial<BaseConfig<E>>>) => Awaitable<Partial<BaseConfig<E>>>;
type FinalConfigFn<E>=(param:ConfigFnParam<any>) => Promise<FinalConfig<E>>;
declare function defineConfig<E = unknown>(configFn:BaseConfigFn<E>,...injectFns:Array<InjectFn<E>>):FinalConfigFn<E>;
export {
defineConfig,
BaseConfig,
InjectConfig,
};