mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
feat: 构建类型定义
This commit is contained in:
parent
a2425b7236
commit
64adb679c8
@ -5,23 +5,11 @@
|
||||
|
||||
import { existsSync } from 'fs';
|
||||
import { extname, join } from 'path';
|
||||
import {
|
||||
chalk,
|
||||
chokidar,
|
||||
compatESModuleRequire,
|
||||
deepmerge,
|
||||
cleanRequireCache,
|
||||
lodash,
|
||||
parseRequireDeps,
|
||||
winPath
|
||||
} from '@fesjs/utils';
|
||||
import { chalk, chokidar, compatESModuleRequire, deepmerge, cleanRequireCache, lodash, parseRequireDeps, winPath } from '@fesjs/utils';
|
||||
import assert from 'assert';
|
||||
import joi from 'joi';
|
||||
import { ServiceStage } from '../service/enums';
|
||||
import {
|
||||
getUserConfigWithKey,
|
||||
updateUserConfigWithKey
|
||||
} from './utils/configUtils';
|
||||
import { getUserConfigWithKey, updateUserConfigWithKey } from './utils/configUtils';
|
||||
import isEqual from './utils/isEqual';
|
||||
import mergeDefault from './utils/mergeDefault';
|
||||
|
||||
@ -60,17 +48,12 @@ export default class Config {
|
||||
}
|
||||
|
||||
getConfig({ defaultConfig }) {
|
||||
assert(
|
||||
this.service.stage >= ServiceStage.pluginReady,
|
||||
'Config.getConfig() failed, it should not be executed before plugin is ready.'
|
||||
);
|
||||
assert(this.service.stage >= ServiceStage.pluginReady, 'Config.getConfig() failed, it should not be executed before plugin is ready.');
|
||||
|
||||
const userConfig = this.getUserConfig();
|
||||
// 用于提示用户哪些 key 是未定义的
|
||||
// TODO: 考虑不排除 false 的 key
|
||||
const userConfigKeys = Object.keys(userConfig).filter(
|
||||
key => userConfig[key] !== false
|
||||
);
|
||||
const userConfigKeys = Object.keys(userConfig).filter((key) => userConfig[key] !== false);
|
||||
|
||||
// get config
|
||||
const pluginIds = Object.keys(this.service.plugins);
|
||||
@ -81,22 +64,17 @@ export default class Config {
|
||||
|
||||
const value = getUserConfigWithKey({
|
||||
key,
|
||||
userConfig
|
||||
userConfig,
|
||||
});
|
||||
// 不校验 false 的值,此时已禁用插件
|
||||
if (value === false) return;
|
||||
|
||||
// do validate
|
||||
const schema = config.schema(joi);
|
||||
assert(
|
||||
joi.isSchema(schema),
|
||||
`schema return from plugin ${pluginId} is not valid schema.`
|
||||
);
|
||||
assert(joi.isSchema(schema), `schema return from plugin ${pluginId} is not valid schema.`);
|
||||
const { error } = schema.validate(value);
|
||||
if (error) {
|
||||
const e = new Error(
|
||||
`Validate config "${key}" failed, ${error.message}`
|
||||
);
|
||||
const e = new Error(`Validate config "${key}" failed, ${error.message}`);
|
||||
e.stack = error.stack;
|
||||
throw e;
|
||||
}
|
||||
@ -111,21 +89,19 @@ export default class Config {
|
||||
if (key in defaultConfig) {
|
||||
const newValue = mergeDefault({
|
||||
defaultConfig: defaultConfig[key],
|
||||
config: value
|
||||
config: value,
|
||||
});
|
||||
updateUserConfigWithKey({
|
||||
key,
|
||||
value: newValue,
|
||||
userConfig
|
||||
userConfig,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (userConfigKeys.length) {
|
||||
const keys = userConfigKeys.length > 1 ? 'keys' : 'key';
|
||||
throw new Error(
|
||||
`Invalid config ${keys}: ${userConfigKeys.join(', ')}`
|
||||
);
|
||||
throw new Error(`Invalid config ${keys}: ${userConfigKeys.join(', ')}`);
|
||||
}
|
||||
|
||||
return userConfig;
|
||||
@ -143,7 +119,7 @@ export default class Config {
|
||||
requireDeps.forEach(cleanRequireCache);
|
||||
this.service.babelRegister.setOnlyMap({
|
||||
key: 'config',
|
||||
value: requireDeps
|
||||
value: requireDeps,
|
||||
});
|
||||
|
||||
// require config and merge
|
||||
@ -173,31 +149,22 @@ export default class Config {
|
||||
|
||||
getConfigFile() {
|
||||
// TODO: support custom config file
|
||||
let configFile = CONFIG_FILES.find(f => existsSync(join(this.cwd, f)));
|
||||
let configFile = CONFIG_FILES.find((f) => existsSync(join(this.cwd, f)));
|
||||
if (!configFile) return [];
|
||||
configFile = winPath(configFile);
|
||||
let envConfigFile;
|
||||
// 潜在问题:
|
||||
// .local 和 .env 的配置必须有 configFile 才有效
|
||||
if (process.env.FES_ENV) {
|
||||
envConfigFile = this.addAffix(
|
||||
configFile,
|
||||
process.env.FES_ENV
|
||||
);
|
||||
envConfigFile = this.addAffix(configFile, process.env.FES_ENV);
|
||||
if (!existsSync(join(this.cwd, envConfigFile))) {
|
||||
throw new Error(
|
||||
`get user config failed, ${envConfigFile} does not exist, but process.env.FES_ENV is set to ${process.env.FES_ENV}.`
|
||||
);
|
||||
throw new Error(`get user config failed, ${envConfigFile} does not exist, but process.env.FES_ENV is set to ${process.env.FES_ENV}.`);
|
||||
}
|
||||
}
|
||||
const files = [
|
||||
configFile,
|
||||
envConfigFile,
|
||||
this.localConfig && this.addAffix(configFile, 'local')
|
||||
]
|
||||
.filter(f => !!f)
|
||||
.map(f => join(this.cwd, f))
|
||||
.filter(f => existsSync(f));
|
||||
const files = [configFile, envConfigFile, this.localConfig && this.addAffix(configFile, 'local')]
|
||||
.filter((f) => !!f)
|
||||
.map((f) => join(this.cwd, f))
|
||||
.filter((f) => existsSync(f));
|
||||
return files;
|
||||
}
|
||||
|
||||
@ -221,7 +188,7 @@ export default class Config {
|
||||
}
|
||||
return memo;
|
||||
}, [])
|
||||
.filter(f => !f.startsWith(configDir));
|
||||
.filter((f) => !f.startsWith(configDir));
|
||||
|
||||
return [configDir].concat(files);
|
||||
}
|
||||
@ -231,7 +198,7 @@ export default class Config {
|
||||
let userConfig = opts.userConfig;
|
||||
const watcher = chokidar.watch(paths, {
|
||||
ignoreInitial: true,
|
||||
cwd: this.cwd
|
||||
cwd: this.cwd,
|
||||
});
|
||||
watcher.on('all', (event, path) => {
|
||||
console.log(chalk.green(`[${event}] ${path}`));
|
||||
@ -252,12 +219,9 @@ export default class Config {
|
||||
if (!isEqual(newUserConfig[key], userConfig[key])) {
|
||||
const changed = {
|
||||
key,
|
||||
pluginId
|
||||
pluginId,
|
||||
};
|
||||
if (
|
||||
newUserConfig[key] === false
|
||||
|| userConfig[key] === false
|
||||
) {
|
||||
if (newUserConfig[key] === false || userConfig[key] === false) {
|
||||
pluginChanged.push(changed);
|
||||
} else {
|
||||
valueChanged.push(changed);
|
||||
@ -269,7 +233,7 @@ export default class Config {
|
||||
opts.onChange({
|
||||
userConfig: newUserConfig,
|
||||
pluginChanged,
|
||||
valueChanged
|
||||
valueChanged,
|
||||
});
|
||||
}
|
||||
userConfig = newUserConfig;
|
||||
|
@ -1,16 +1,9 @@
|
||||
import {
|
||||
lodash,
|
||||
winPath
|
||||
} from '@fesjs/utils';
|
||||
|
||||
import { lodash, winPath } from '@fesjs/utils';
|
||||
|
||||
export default class BabelRegister {
|
||||
only = {};
|
||||
|
||||
setOnlyMap({
|
||||
key,
|
||||
value
|
||||
}) {
|
||||
setOnlyMap({ key, value }) {
|
||||
this.only[key] = value;
|
||||
this.register();
|
||||
}
|
||||
@ -19,7 +12,7 @@ export default class BabelRegister {
|
||||
const only = lodash.uniq(
|
||||
Object.keys(this.only)
|
||||
.reduce((memo, key) => memo.concat(this.only[key]), [])
|
||||
.map(winPath)
|
||||
.map(winPath),
|
||||
);
|
||||
require('@babel/register')({
|
||||
presets: [
|
||||
@ -27,17 +20,17 @@ export default class BabelRegister {
|
||||
require.resolve('@babel/preset-env'),
|
||||
{
|
||||
targets: {
|
||||
node: 'current'
|
||||
node: 'current',
|
||||
},
|
||||
modules: 'commonjs'
|
||||
}
|
||||
]
|
||||
modules: 'commonjs',
|
||||
},
|
||||
],
|
||||
],
|
||||
ignore: [/node_modules/],
|
||||
only,
|
||||
extensions: ['.jsx', '.js', '.ts', '.tsx'],
|
||||
babelrc: false,
|
||||
cache: false
|
||||
cache: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -32,5 +32,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"windicss-webpack-plugin": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import WindiCSSWebpackPlugin from 'windicss-webpack-plugin';
|
||||
import { name } from '../package.json';
|
||||
|
||||
export default (api) => {
|
||||
api.describe({
|
||||
@ -47,4 +48,9 @@ export default (api) => {
|
||||
|
||||
return memo;
|
||||
});
|
||||
|
||||
api.addBuildType(() => ({
|
||||
source: name,
|
||||
specifier: ['WindicssBuildConfig'],
|
||||
}));
|
||||
};
|
||||
|
7
packages/fes-plugin-windicss/types.d.ts
vendored
Normal file
7
packages/fes-plugin-windicss/types.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import type { Config } from 'windicss/types/interfaces';
|
||||
|
||||
export interface WindicssBuildConfig {
|
||||
windicss: {
|
||||
config: Config
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
// fes.config.js 只负责管理 cli 相关的配置
|
||||
import pxtoviewport from '@ttou/postcss-px-to-viewport';
|
||||
import { defineBuildConfig } from '@fesjs/fes';
|
||||
|
||||
|
||||
export default {
|
||||
export default defineBuildConfig({
|
||||
define: {
|
||||
// __VUE_OPTIONS_API__: true,
|
||||
// __VUE_PROD_DEVTOOLS__: false
|
||||
@ -45,4 +45,5 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
"@fesjs/preset-built-in": "^2.0.22",
|
||||
"@fesjs/runtime": "^2.0.2",
|
||||
"@fesjs/utils": "^2.0.4",
|
||||
"pirates": "^4.0.5",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"vue-router": "^4.0.1"
|
||||
},
|
||||
@ -49,4 +50,4 @@
|
||||
"node": "^10.12.0 || ^12.0.0 || >= 14.0.0"
|
||||
},
|
||||
"types": "types.d.ts"
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,13 @@ import fork from './utils/fork';
|
||||
import getCwd from './utils/getCwd';
|
||||
import getPkg from './utils/getPkg';
|
||||
import fesPkg from '../package.json';
|
||||
import { hackFesInBuild } from './hackFesInBuild';
|
||||
|
||||
const requiredVersion = fesPkg.engines.node;
|
||||
|
||||
function checkNodeVersion(wanted, id) {
|
||||
if (
|
||||
!semver.satisfies(process.version, wanted, { includePrerelease: true })
|
||||
) {
|
||||
console.log(
|
||||
chalk.red(
|
||||
`You are using Node ${process.version}, but this version of ${id} requires Node ${wanted}.\nPlease upgrade your Node version.`
|
||||
)
|
||||
);
|
||||
if (!semver.satisfies(process.version, wanted, { includePrerelease: true })) {
|
||||
console.log(chalk.red(`You are using Node ${process.version}, but this version of ${id} requires Node ${wanted}.\nPlease upgrade your Node version.`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@ -31,7 +26,7 @@ const args = yParser(rawArgv);
|
||||
const command = args._[0];
|
||||
if (command === 'dev') {
|
||||
const child = fork({
|
||||
scriptPath: require.resolve('./forkedDev')
|
||||
scriptPath: require.resolve('./forkedDev'),
|
||||
});
|
||||
// ref:
|
||||
// http://nodejs.cn/api/process/signal_events.html
|
||||
@ -44,16 +39,17 @@ const args = yParser(rawArgv);
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
hackFesInBuild();
|
||||
if (command === 'build') {
|
||||
process.env.NODE_ENV = 'production';
|
||||
}
|
||||
await new Service({
|
||||
cwd: getCwd(),
|
||||
pkg: getPkg(process.cwd()),
|
||||
fesPkg
|
||||
fesPkg,
|
||||
}).run({
|
||||
args,
|
||||
rawArgv
|
||||
rawArgv,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -8,6 +8,7 @@ import { Service } from './serviceWithBuiltIn';
|
||||
import getCwd from './utils/getCwd';
|
||||
import getPkg from './utils/getPkg';
|
||||
import fesPkg from '../package.json';
|
||||
import { hackFesInBuild } from './hackFesInBuild';
|
||||
|
||||
const args = yParser(process.argv.slice(2));
|
||||
|
||||
@ -21,8 +22,8 @@ function onSignal(signal, service) {
|
||||
key: 'onExit',
|
||||
type: service.ApplyPluginsType.event,
|
||||
args: {
|
||||
signal
|
||||
}
|
||||
signal,
|
||||
},
|
||||
});
|
||||
process.exit(0);
|
||||
}
|
||||
@ -30,17 +31,17 @@ function onSignal(signal, service) {
|
||||
(async () => {
|
||||
try {
|
||||
process.env.NODE_ENV = 'development';
|
||||
hackFesInBuild();
|
||||
const service = new Service({
|
||||
cwd: getCwd(),
|
||||
pkg: getPkg(process.cwd()),
|
||||
fesPkg
|
||||
fesPkg,
|
||||
});
|
||||
await service.run({
|
||||
name: 'dev',
|
||||
args
|
||||
args,
|
||||
});
|
||||
|
||||
|
||||
// kill(2) Ctrl-C
|
||||
process.once('SIGINT', () => onSignal('SIGINT', service));
|
||||
// kill(3) Ctrl-\
|
||||
|
20
packages/fes/src/hackFesInBuild.js
Normal file
20
packages/fes/src/hackFesInBuild.js
Normal file
@ -0,0 +1,20 @@
|
||||
// my-module/register.js
|
||||
import { addHook } from 'pirates';
|
||||
|
||||
function matcher(filename) {
|
||||
if (filename.endsWith('/fes/lib/index.js')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function hackFesInBuild() {
|
||||
addHook(
|
||||
() => `
|
||||
module.exports = {
|
||||
defineBuildConfig(params) {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ exts: ['.js'], ignoreNodeModules: false, matcher },
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user