mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
fix: 重新梳理构建流程
This commit is contained in:
parent
972518ff9c
commit
40d8332030
@ -1,9 +1,8 @@
|
||||
{
|
||||
"name": "@fesjs/build-vite",
|
||||
"version": "2.0.22",
|
||||
"version": "1.0.0",
|
||||
"description": "@fesjs/build-vite",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
|
3
packages/fes-build-vite/src/commands/build/index.js
Normal file
3
packages/fes-build-vite/src/commands/build/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default (api) => {
|
||||
console.log(api, 'TODO: 实现 vite build');
|
||||
};
|
@ -1,21 +1,28 @@
|
||||
import { createServer } from 'vite';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import SFCConfigBlockPlugin from './SFCConfigBlockPlugin';
|
||||
import SFCConfigBlockPlugin from '../SFCConfigBlockPlugin';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* 支持 https
|
||||
* 如何处理 html
|
||||
* dev 模式 port、https、css modules等能力和 webpack 对齐
|
||||
* proxy
|
||||
* createRouteMiddleware 能力
|
||||
* 确认 mock mountElementId 能用
|
||||
* 其他插件如何对内部配置进行修改
|
||||
*/
|
||||
|
||||
export default (api) => {
|
||||
const {
|
||||
paths,
|
||||
utils: { chalk },
|
||||
utils: { chalk, rimraf, getPort, changePort, getHostName },
|
||||
} = api;
|
||||
|
||||
const unwatchs = [];
|
||||
let server;
|
||||
|
||||
function destroy() {
|
||||
for (const unwatch of unwatchs) {
|
||||
unwatch();
|
||||
}
|
||||
server?.close();
|
||||
}
|
||||
|
||||
@ -32,7 +39,21 @@ export default (api) => {
|
||||
description: 'whether to turn on the https service',
|
||||
},
|
||||
],
|
||||
async fn() {
|
||||
async fn({ args = {} }) {
|
||||
rimraf.sync(paths.absTmpPath);
|
||||
|
||||
const port = await getPort(args.port || api.config.viteOption?.server?.port);
|
||||
changePort(port);
|
||||
|
||||
const hostname = getHostName(api.config.viteOption?.server?.host);
|
||||
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
|
||||
api.startWatch();
|
||||
|
||||
server = await createServer({
|
||||
mode: 'development',
|
||||
plugins: [vue(), SFCConfigBlockPlugin, vueJsx()],
|
||||
@ -45,7 +66,9 @@ export default (api) => {
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 8000,
|
||||
port,
|
||||
host: hostname,
|
||||
https: process.env.HTTPS || args.https,
|
||||
},
|
||||
});
|
||||
await server.listen();
|
3
packages/fes-build-vite/src/common/getConfig.js
Normal file
3
packages/fes-build-vite/src/common/getConfig.js
Normal file
@ -0,0 +1,3 @@
|
||||
export function getConfig() {
|
||||
return {};
|
||||
}
|
11
packages/fes-build-vite/src/index.js
Normal file
11
packages/fes-build-vite/src/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
export default function () {
|
||||
return {
|
||||
plugins: [
|
||||
// bundle configs
|
||||
|
||||
// commands
|
||||
require.resolve('./commands/build'),
|
||||
require.resolve('./commands/dev'),
|
||||
],
|
||||
};
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
export default function () {
|
||||
return {
|
||||
plugins: [
|
||||
// register methods
|
||||
require.resolve('./plugins/registerMethods'),
|
||||
|
||||
// bundle configs
|
||||
require.resolve('./plugins/features/alias'),
|
||||
require.resolve('./plugins/features/analyze'),
|
||||
|
@ -12,7 +12,7 @@ const logger = new Logger('fes:build-webpack');
|
||||
export default function (api) {
|
||||
const {
|
||||
paths,
|
||||
utils: { rimraf, generateFiles },
|
||||
utils: { rimraf },
|
||||
} = api;
|
||||
|
||||
api.registerCommand({
|
||||
@ -27,7 +27,10 @@ export default function (api) {
|
||||
});
|
||||
|
||||
// generate files
|
||||
await generateFiles({ api, watch: false });
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
|
||||
// build
|
||||
const { bundleConfig } = await getBundleAndConfigs({ api });
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { join, resolve } from 'path';
|
||||
import { existsSync, readdirSync, readFileSync } from 'fs';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { rimraf, chalk } from '@fesjs/utils';
|
||||
import zlib from 'zlib';
|
||||
import getConfig from './webpackConfig';
|
||||
@ -75,11 +75,7 @@ export async function getBundleAndConfigs({ api }) {
|
||||
}
|
||||
|
||||
export function cleanTmpPathExceptCache({ absTmpPath }) {
|
||||
if (!existsSync(absTmpPath)) return;
|
||||
readdirSync(absTmpPath).forEach((file) => {
|
||||
if (file === '.cache') return;
|
||||
rimraf.sync(join(absTmpPath, file));
|
||||
});
|
||||
rimraf.sync(absTmpPath);
|
||||
}
|
||||
|
||||
// These sizes are pretty large. We'll warn for bundles exceeding them.
|
||||
|
@ -6,7 +6,7 @@
|
||||
export default (api) => {
|
||||
const {
|
||||
paths,
|
||||
utils: { chalk, portfinder, generateFiles },
|
||||
utils: { chalk, getPort, getHostName, changePort },
|
||||
} = api;
|
||||
|
||||
const unwatchs = [];
|
||||
@ -37,18 +37,12 @@ export default (api) => {
|
||||
async fn({ args = {} }) {
|
||||
const { cleanTmpPathExceptCache, getBundleAndConfigs } = require('../buildDevUtils');
|
||||
const createRouteMiddleware = require('./createRouteMiddleware').default;
|
||||
const { watchPkg } = require('./watchPkg');
|
||||
|
||||
const defaultPort = process.env.PORT || args.port || api.config.devServer?.port;
|
||||
port = await portfinder.getPortPromise({
|
||||
port: defaultPort ? parseInt(String(defaultPort), 10) : 8000,
|
||||
});
|
||||
hostname = process.env.HOST || api.config.devServer?.host || 'localhost';
|
||||
console.log(args.port || api.config.devServer?.port);
|
||||
port = await getPort(args.port || api.config.devServer?.port);
|
||||
changePort(port);
|
||||
|
||||
process.send({
|
||||
type: 'UPDATE_PORT',
|
||||
port,
|
||||
});
|
||||
hostname = getHostName(api.config.devServer?.host);
|
||||
|
||||
// enable https
|
||||
const isHTTPS = process.env.HTTPS || args.https;
|
||||
@ -58,77 +52,13 @@ export default (api) => {
|
||||
cleanTmpPathExceptCache({
|
||||
absTmpPath: paths.absTmpPath,
|
||||
});
|
||||
const watch = process.env.WATCH !== 'none';
|
||||
|
||||
// generate files
|
||||
const unwatchGenerateFiles = await generateFiles({
|
||||
api,
|
||||
watch,
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
if (unwatchGenerateFiles) unwatchs.push(unwatchGenerateFiles);
|
||||
|
||||
if (watch) {
|
||||
// watch pkg changes
|
||||
const unwatchPkg = watchPkg({
|
||||
cwd: api.cwd,
|
||||
onChange() {
|
||||
console.log();
|
||||
api.logger.info('Plugins in package.json changed.');
|
||||
api.restartServer();
|
||||
},
|
||||
});
|
||||
unwatchs.push(unwatchPkg);
|
||||
|
||||
// watch config change
|
||||
const unwatchConfig = api.service.configInstance.watch({
|
||||
userConfig: api.service.userConfig,
|
||||
onChange: async ({ pluginChanged, valueChanged }) => {
|
||||
if (pluginChanged.length) {
|
||||
console.log();
|
||||
api.logger.info(`Plugins of ${pluginChanged.map((p) => p.key).join(', ')} changed.`);
|
||||
api.restartServer();
|
||||
}
|
||||
if (valueChanged.length) {
|
||||
let reload = false;
|
||||
let regenerateTmpFiles = false;
|
||||
const fns = [];
|
||||
const reloadConfigs = [];
|
||||
valueChanged.forEach(({ key, pluginId }) => {
|
||||
const { onChange } = api.service.plugins[pluginId].config || {};
|
||||
if (onChange === api.ConfigChangeType.regenerateTmpFiles) {
|
||||
regenerateTmpFiles = true;
|
||||
}
|
||||
if (!onChange || onChange === api.ConfigChangeType.reload) {
|
||||
reload = true;
|
||||
reloadConfigs.push(key);
|
||||
}
|
||||
if (typeof onChange === 'function') {
|
||||
fns.push(onChange);
|
||||
}
|
||||
});
|
||||
|
||||
if (reload) {
|
||||
console.log();
|
||||
api.logger.info(`Config ${reloadConfigs.join(', ')} changed.`);
|
||||
api.restartServer();
|
||||
} else {
|
||||
api.service.userConfig = api.service.configInstance.getUserConfig();
|
||||
|
||||
await api.setConfig();
|
||||
|
||||
if (regenerateTmpFiles) {
|
||||
await generateFiles({
|
||||
api,
|
||||
});
|
||||
} else {
|
||||
fns.forEach((fn) => fn());
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
unwatchs.push(unwatchConfig);
|
||||
}
|
||||
api.startWatch();
|
||||
|
||||
// dev
|
||||
const { bundleConfig } = await getBundleAndConfigs({ api });
|
||||
|
14
packages/fes-build-webpack/src/plugins/registerMethods.js
Normal file
14
packages/fes-build-webpack/src/plugins/registerMethods.js
Normal file
@ -0,0 +1,14 @@
|
||||
export default function (api) {
|
||||
[
|
||||
'addHTMLHeadScripts',
|
||||
'addMiddlewares',
|
||||
'modifyBundleConfigOpts',
|
||||
'modifyBundleConfig',
|
||||
'modifyBabelOpts',
|
||||
'modifyBabelPresetOpts',
|
||||
'chainWebpack',
|
||||
'modifyPublicPathStr',
|
||||
].forEach((name) => {
|
||||
api.registerMethod({ name });
|
||||
});
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { chokidar, lodash, winPath } from '@fesjs/utils';
|
||||
import { getAppPath } from './getAppEntryPath';
|
||||
|
||||
export default async ({ api, watch }) => {
|
||||
const { paths } = api;
|
||||
|
||||
async function generate() {
|
||||
api.logger.debug('generate files');
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
}
|
||||
|
||||
let watchers = [];
|
||||
|
||||
await generate();
|
||||
|
||||
function unwatch() {
|
||||
watchers.forEach((watcher) => {
|
||||
watcher.close();
|
||||
});
|
||||
watchers = [];
|
||||
}
|
||||
|
||||
function createWatcher(path) {
|
||||
const watcher = chokidar.watch(path, {
|
||||
// ignore .dotfiles and _mock.js
|
||||
ignored: /(^|[/\\])(_mock.js$|\..)/,
|
||||
ignoreInitial: true,
|
||||
});
|
||||
watcher.on(
|
||||
'all',
|
||||
lodash.throttle(async () => {
|
||||
await generate();
|
||||
}, 100),
|
||||
);
|
||||
watchers.push(watcher);
|
||||
}
|
||||
|
||||
if (watch) {
|
||||
const watcherPaths = await api.applyPlugins({
|
||||
key: 'addTmpGenerateWatcherPaths',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [paths.absPagesPath, getAppPath(paths.absSrcPath)],
|
||||
});
|
||||
lodash.uniq(watcherPaths.map((p) => winPath(p))).forEach((p) => {
|
||||
createWatcher(p);
|
||||
});
|
||||
}
|
||||
|
||||
return unwatch;
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
import { join } from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
import { winPath } from '@fesjs/utils';
|
||||
|
||||
export function getAppPath(absSrcPath) {
|
||||
for (const suffix of ['.js', '.ts', '.jsm', '.jsx', '.tsx']) {
|
||||
const p = winPath(join(absSrcPath, `app${suffix}`));
|
||||
if (existsSync(p)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
@ -6,7 +6,7 @@ import { runtimePath } from '../../../../utils/constants';
|
||||
export default function (api) {
|
||||
const {
|
||||
paths,
|
||||
utils: { Mustache, getAppEntryPath },
|
||||
utils: { Mustache, getAppPath },
|
||||
} = api;
|
||||
|
||||
const absoluteFilePath = 'core/plugin.js';
|
||||
@ -36,7 +36,7 @@ export default function (api) {
|
||||
const plugins = await api.applyPlugins({
|
||||
key: 'addRuntimePlugin',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [getAppEntryPath(paths.absSrcPath)].filter(Boolean),
|
||||
initialValue: [getAppPath(paths.absSrcPath)].filter(Boolean),
|
||||
});
|
||||
api.writeTmpFile({
|
||||
path: absoluteFilePath,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import assert from 'assert';
|
||||
import { dirname, join } from 'path';
|
||||
import { existsSync, statSync, readFileSync, writeFileSync, copyFileSync } from 'fs';
|
||||
import { startWatch } from './watch/watchMode';
|
||||
|
||||
export default function (api) {
|
||||
[
|
||||
@ -21,14 +22,6 @@ export default function (api) {
|
||||
'addTmpGenerateWatcherPaths',
|
||||
|
||||
'addBeforeMiddlewares',
|
||||
'addHTMLHeadScripts',
|
||||
'addMiddlewares',
|
||||
'modifyBundleConfigOpts',
|
||||
'modifyBundleConfig',
|
||||
'modifyBabelOpts',
|
||||
'modifyBabelPresetOpts',
|
||||
'chainWebpack',
|
||||
'modifyPublicPathStr',
|
||||
].forEach((name) => {
|
||||
api.registerMethod({ name });
|
||||
});
|
||||
@ -73,4 +66,11 @@ export default function (api) {
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
api.registerMethod({
|
||||
name: 'startWatch',
|
||||
fn() {
|
||||
startWatch(api);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
123
packages/fes-preset-built-in/src/plugins/watch/watchMode.js
Normal file
123
packages/fes-preset-built-in/src/plugins/watch/watchMode.js
Normal file
@ -0,0 +1,123 @@
|
||||
import { chokidar, winPath, lodash, getAppPath } from '@fesjs/utils';
|
||||
import { watchPkg } from './watchPkg';
|
||||
|
||||
async function generateWhenFilesChange({ api }) {
|
||||
const { paths } = api;
|
||||
|
||||
let watchers = [];
|
||||
|
||||
function unwatch() {
|
||||
watchers.forEach((watcher) => {
|
||||
watcher.close();
|
||||
});
|
||||
watchers = [];
|
||||
}
|
||||
|
||||
function createWatcher(path) {
|
||||
const watcher = chokidar.watch(path, {
|
||||
// ignore .dotfiles and _mock.js
|
||||
ignored: /(^|[/\\])(_mock.js$|\..)/,
|
||||
ignoreInitial: true,
|
||||
});
|
||||
watcher.on(
|
||||
'all',
|
||||
lodash.throttle(async () => {
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
}, 100),
|
||||
);
|
||||
watchers.push(watcher);
|
||||
}
|
||||
|
||||
const watcherPaths = await api.applyPlugins({
|
||||
key: 'addTmpGenerateWatcherPaths',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [paths.absPagesPath, getAppPath(paths.absSrcPath)],
|
||||
});
|
||||
lodash.uniq(watcherPaths.map((p) => winPath(p))).forEach((p) => {
|
||||
createWatcher(p);
|
||||
});
|
||||
|
||||
return unwatch;
|
||||
}
|
||||
|
||||
export async function startWatch(api) {
|
||||
if (process.env.WATCH === 'none') return;
|
||||
|
||||
let unwatchs = [];
|
||||
const destroy = () => {
|
||||
for (const unwatch of unwatchs) {
|
||||
unwatch();
|
||||
}
|
||||
unwatchs = [];
|
||||
api.restartServer();
|
||||
};
|
||||
|
||||
// generate files
|
||||
const unwatchGenerateFiles = await generateWhenFilesChange({ api });
|
||||
unwatchs.push(unwatchGenerateFiles);
|
||||
|
||||
// watch pkg changes
|
||||
const unwatchPkg = watchPkg({
|
||||
cwd: api.cwd,
|
||||
onChange() {
|
||||
console.log();
|
||||
api.logger.info('Plugins in package.json changed.');
|
||||
destroy();
|
||||
},
|
||||
});
|
||||
unwatchs.push(unwatchPkg);
|
||||
|
||||
// watch config change
|
||||
const unwatchConfig = api.service.configInstance.watch({
|
||||
userConfig: api.service.userConfig,
|
||||
onChange: async ({ pluginChanged, valueChanged }) => {
|
||||
if (pluginChanged.length) {
|
||||
console.log();
|
||||
api.logger.info(`Plugins of ${pluginChanged.map((p) => p.key).join(', ')} changed.`);
|
||||
destroy();
|
||||
}
|
||||
if (valueChanged.length) {
|
||||
let reload = false;
|
||||
let regenerateTmpFiles = false;
|
||||
const fns = [];
|
||||
const reloadConfigs = [];
|
||||
valueChanged.forEach(({ key, pluginId }) => {
|
||||
const { onChange } = api.service.plugins[pluginId].config || {};
|
||||
if (onChange === api.ConfigChangeType.regenerateTmpFiles) {
|
||||
regenerateTmpFiles = true;
|
||||
}
|
||||
if (!onChange || onChange === api.ConfigChangeType.reload) {
|
||||
reload = true;
|
||||
reloadConfigs.push(key);
|
||||
}
|
||||
if (typeof onChange === 'function') {
|
||||
fns.push(onChange);
|
||||
}
|
||||
});
|
||||
|
||||
if (reload) {
|
||||
console.log();
|
||||
api.logger.info(`Config ${reloadConfigs.join(', ')} changed.`);
|
||||
destroy();
|
||||
} else {
|
||||
api.service.userConfig = api.service.configInstance.getUserConfig();
|
||||
|
||||
await api.setConfig();
|
||||
|
||||
if (regenerateTmpFiles) {
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
} else {
|
||||
fns.forEach((fn) => fn());
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
unwatchs.push(unwatchConfig);
|
||||
}
|
6
packages/fes-utils/src/changePort.js
Normal file
6
packages/fes-utils/src/changePort.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default (port) => {
|
||||
process.send({
|
||||
type: 'UPDATE_PORT',
|
||||
port,
|
||||
});
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
import * as chokidar from 'chokidar';
|
||||
import lodash from 'lodash';
|
||||
import winPath from './winPath';
|
||||
import getAppPath from './getAppEntryPath';
|
||||
|
||||
export default async ({ api, watch }) => {
|
||||
const { paths } = api;
|
||||
|
||||
async function generate() {
|
||||
api.logger.debug('generate files');
|
||||
await api.applyPlugins({
|
||||
key: 'onGenerateFiles',
|
||||
type: api.ApplyPluginsType.event,
|
||||
});
|
||||
}
|
||||
|
||||
let watchers = [];
|
||||
|
||||
await generate();
|
||||
|
||||
function unwatch() {
|
||||
watchers.forEach((watcher) => {
|
||||
watcher.close();
|
||||
});
|
||||
watchers = [];
|
||||
}
|
||||
|
||||
function createWatcher(path) {
|
||||
const watcher = chokidar.watch(path, {
|
||||
// ignore .dotfiles and _mock.js
|
||||
ignored: /(^|[/\\])(_mock.js$|\..)/,
|
||||
ignoreInitial: true,
|
||||
});
|
||||
watcher.on(
|
||||
'all',
|
||||
lodash.throttle(async () => {
|
||||
await generate();
|
||||
}, 100),
|
||||
);
|
||||
watchers.push(watcher);
|
||||
}
|
||||
|
||||
if (watch) {
|
||||
const watcherPaths = await api.applyPlugins({
|
||||
key: 'addTmpGenerateWatcherPaths',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [paths.absPagesPath, getAppPath(paths.absSrcPath)],
|
||||
});
|
||||
lodash.uniq(watcherPaths.map((p) => winPath(p))).forEach((p) => {
|
||||
createWatcher(p);
|
||||
});
|
||||
}
|
||||
|
||||
return unwatch;
|
||||
};
|
1
packages/fes-utils/src/getHostName.js
Normal file
1
packages/fes-utils/src/getHostName.js
Normal file
@ -0,0 +1 @@
|
||||
export default (userHost) => process.env.HOST || userHost || 'localhost';
|
8
packages/fes-utils/src/getPort.js
Normal file
8
packages/fes-utils/src/getPort.js
Normal file
@ -0,0 +1,8 @@
|
||||
import portfinder from 'portfinder';
|
||||
|
||||
export default async function getPort(userPort) {
|
||||
const defaultPort = process.env.PORT || userPort;
|
||||
return portfinder.getPortPromise({
|
||||
port: defaultPort ? parseInt(String(defaultPort), 10) : 8000,
|
||||
});
|
||||
}
|
@ -25,8 +25,10 @@ import compatESModuleRequire from './compatESModuleRequire';
|
||||
import cleanRequireCache from './cleanRequireCache';
|
||||
import parseRequireDeps from './parseRequireDeps';
|
||||
import mergeConfig from './mergeConfig';
|
||||
import getAppEntryPath from './getAppEntryPath';
|
||||
import generateFiles from './generateFiles';
|
||||
import getAppPath from './getAppPath';
|
||||
import getPort from './getPort';
|
||||
import changePort from './changePort';
|
||||
import getHostName from './getHostName';
|
||||
|
||||
export {
|
||||
chalk,
|
||||
@ -58,6 +60,8 @@ export {
|
||||
mergeConfig,
|
||||
resolvePkg,
|
||||
resolveInnerDep,
|
||||
generateFiles,
|
||||
getAppEntryPath,
|
||||
getAppPath,
|
||||
getPort,
|
||||
changePort,
|
||||
getHostName,
|
||||
};
|
||||
|
1
packages/fes/types.d.ts
vendored
1
packages/fes/types.d.ts
vendored
@ -1,5 +1,6 @@
|
||||
import { Component, DefineComponent, App } from 'vue';
|
||||
import { RouteRecordRaw, Router } from 'vue-router';
|
||||
// @ts-ignore
|
||||
import { Plugin } from '@fesjs/runtime';
|
||||
// @ts-ignore
|
||||
import type { PluginRuntimeConfig, PluginBuildConfig } from '@@/configType';
|
||||
|
Loading…
x
Reference in New Issue
Block a user