This commit is contained in:
harrywan 2024-12-10 10:44:15 +08:00
commit 88c88d9116
27 changed files with 2095 additions and 393 deletions

View File

@ -1,3 +1,64 @@
## [3.4.7](https://github.com/WeBankFinTech/fes.js/compare/v3.4.5...v3.4.7) (2024-12-01)
### Bug Fixes
* 代理插件兼容 array 写法 ([#260](https://github.com/WeBankFinTech/fes.js/issues/260)) ([7c01ee9](https://github.com/WeBankFinTech/fes.js/commit/7c01ee979e0776101c0f00bebca8a283d48cef6e))
* 受控模式优化 ([#262](https://github.com/WeBankFinTech/fes.js/issues/262)) ([4d28a09](https://github.com/WeBankFinTech/fes.js/commit/4d28a09c85ff1d140ffbc086b7ca6f24e02c6a4f))
* 修复pc模版无法启动问题 ([#261](https://github.com/WeBankFinTech/fes.js/issues/261)) ([b1ea675](https://github.com/WeBankFinTech/fes.js/commit/b1ea675f40b158266c28bcc7fedfd3eabba9f38c))
### Features
* 添加 console 配置,支持输出 version ([#263](https://github.com/WeBankFinTech/fes.js/issues/263)) ([c7ad0cd](https://github.com/WeBankFinTech/fes.js/commit/c7ad0cd8062d50519e3aea7ca957320967d41d41))
* webpack-dev 升级到5.x,提升 dev 性能,优化日志输出 ([#259](https://github.com/WeBankFinTech/fes.js/issues/259)) ([efd8708](https://github.com/WeBankFinTech/fes.js/commit/efd87087522cd2dce6b5dc89fbe93ef46efd08bf))
## [3.4.6](https://github.com/WeBankFinTech/fes.js/compare/v3.4.5...v3.4.6) (2024-11-28)
### Bug Fixes
* 代理插件兼容 array 写法 ([#260](https://github.com/WeBankFinTech/fes.js/issues/260)) ([7c01ee9](https://github.com/WeBankFinTech/fes.js/commit/7c01ee979e0776101c0f00bebca8a283d48cef6e))
* 受控模式优化 ([#262](https://github.com/WeBankFinTech/fes.js/issues/262)) ([4d28a09](https://github.com/WeBankFinTech/fes.js/commit/4d28a09c85ff1d140ffbc086b7ca6f24e02c6a4f))
* 修复pc模版无法启动问题 ([#261](https://github.com/WeBankFinTech/fes.js/issues/261)) ([b1ea675](https://github.com/WeBankFinTech/fes.js/commit/b1ea675f40b158266c28bcc7fedfd3eabba9f38c))
### Features
* webpack-dev 升级到5.x,提升 dev 性能,优化日志输出 ([#259](https://github.com/WeBankFinTech/fes.js/issues/259)) ([efd8708](https://github.com/WeBankFinTech/fes.js/commit/efd87087522cd2dce6b5dc89fbe93ef46efd08bf))
## [3.4.5](https://github.com/WeBankFinTech/fes.js/compare/v3.4.3...v3.4.5) (2024-11-19)
### Bug Fixes
* 控制 tab 是否可以刷新 ([#257](https://github.com/WeBankFinTech/fes.js/issues/257)) ([4b3fb7b](https://github.com/WeBankFinTech/fes.js/commit/4b3fb7b3d120a36eb894b47a7c08267888b53c15))
### Features
* menu 支持配置 _blank 在新页面打开 ([#258](https://github.com/WeBankFinTech/fes.js/issues/258)) ([eb6ed75](https://github.com/WeBankFinTech/fes.js/commit/eb6ed75dd45bea746b2dac339f2c2aae5b361b66))
## [3.4.4](https://github.com/WeBankFinTech/fes.js/compare/v3.4.3...v3.4.4) (2024-11-19)
### Bug Fixes
* 控制 tab 是否可以刷新 ([#257](https://github.com/WeBankFinTech/fes.js/issues/257)) ([4b3fb7b](https://github.com/WeBankFinTech/fes.js/commit/4b3fb7b3d120a36eb894b47a7c08267888b53c15))
### Features
* menu 支持配置 _blank 在新页面打开 ([#258](https://github.com/WeBankFinTech/fes.js/issues/258)) ([eb6ed75](https://github.com/WeBankFinTech/fes.js/commit/eb6ed75dd45bea746b2dac339f2c2aae5b361b66))
## [3.4.3](https://github.com/WeBankFinTech/fes.js/compare/v3.4.2...v3.4.3) (2024-11-12) ## [3.4.3](https://github.com/WeBankFinTech/fes.js/compare/v3.4.2...v3.4.3) (2024-11-12)

View File

@ -1,4 +1,3 @@
export const zh = { export const zh = {
'/guide/': [ '/guide/': [
{ {
@ -6,12 +5,12 @@ export const zh = {
items: [ items: [
{ {
text: '介绍', text: '介绍',
link: '/guide/index.md' link: '/guide/index.md',
}, },
{ {
text: '快速上手', text: '快速上手',
link: '/guide/getting-started.md' link: '/guide/getting-started.md',
} },
], ],
}, },
{ {
@ -19,35 +18,44 @@ export const zh = {
items: [ items: [
{ {
text: '目录结构', text: '目录结构',
link: '/guide/directory-structure.md' link: '/guide/directory-structure.md',
},{ },
{
text: 'Vite 和 Webpack 双构建', text: 'Vite 和 Webpack 双构建',
link: '/guide/builder.md' link: '/guide/builder.md',
},{ },
{
text: '编译时配置', text: '编译时配置',
link: '/guide/config.md' link: '/guide/config.md',
},{ },
{
text: '运行时配置', text: '运行时配置',
link: '/guide/runtime-config.md' link: '/guide/runtime-config.md',
},{ },
{
text: '环境变量', text: '环境变量',
link: '/guide/env.md' link: '/guide/env.md',
},{ },
{
text: '路由', text: '路由',
link: '/guide/route.md' link: '/guide/route.md',
},{ },
{
text: '插件', text: '插件',
link: '/guide/plugin.md' link: '/guide/plugin.md',
},{ },
{
text: 'HTML 模板', text: 'HTML 模板',
link: '/guide/template.md' link: '/guide/template.md',
},{ },
{
text: 'Mock 数据', text: 'Mock 数据',
link: '/guide/mock.md' link: '/guide/mock.md',
},{ },
text: '从 2.0.x 迁移到 3.0.x', {
link: '/guide/upgrade3.md' text: '从 2.x 迁移到 3.x',
} link: '/guide/upgrade3.md',
},
], ],
}, },
{ {
@ -55,102 +63,102 @@ export const zh = {
items: [ items: [
{ {
text: '使用图片', text: '使用图片',
link: '/guide/image.md' link: '/guide/image.md',
}, },
{ {
text: '使用 css', text: '使用 css',
link: '/guide/css.md' link: '/guide/css.md',
}, },
{ {
text: '静态资源', text: '静态资源',
link: '/guide/public.md' link: '/guide/public.md',
} },
], ],
}, },
{ {
text: '贡献指南', text: '贡献指南',
link: '/guide/contributing.md' link: '/guide/contributing.md',
}, },
{ {
text: '常见问题', text: '常见问题',
link: '/guide/faq.md' link: '/guide/faq.md',
}, },
], ],
'/reference/plugin/': [ '/reference/plugin/': [
{ {
text: '介绍', text: '介绍',
link: '/reference/plugin/index.md' link: '/reference/plugin/index.md',
}, },
{ {
text: 'Plugins', text: 'Plugins',
items: [ items: [
{ {
text: '@fesjs/plugin-access', text: '@fesjs/plugin-access',
link: '/reference/plugin/plugins/access.md' link: '/reference/plugin/plugins/access.md',
}, },
{ {
text: '@fesjs/plugin-enums', text: '@fesjs/plugin-enums',
link: '/reference/plugin/plugins/enums.md' link: '/reference/plugin/plugins/enums.md',
}, },
{ {
text: '@fesjs/plugin-icon', text: '@fesjs/plugin-icon',
link: '/reference/plugin/plugins/icon.md' link: '/reference/plugin/plugins/icon.md',
}, },
{ {
text: '@fesjs/plugin-jest', text: '@fesjs/plugin-jest',
link: '/reference/plugin/plugins/jest.md' link: '/reference/plugin/plugins/jest.md',
}, },
{ {
text: '@fesjs/plugin-layout', text: '@fesjs/plugin-layout',
link: '/reference/plugin/plugins/layout.md' link: '/reference/plugin/plugins/layout.md',
}, },
{ {
text: '@fesjs/plugin-locale', text: '@fesjs/plugin-locale',
link: '/reference/plugin/plugins/locale.md' link: '/reference/plugin/plugins/locale.md',
}, },
{ {
text: '@fesjs/plugin-model', text: '@fesjs/plugin-model',
link: '/reference/plugin/plugins/model.md' link: '/reference/plugin/plugins/model.md',
}, },
{ {
text: '@fesjs/plugin-request', text: '@fesjs/plugin-request',
link: '/reference/plugin/plugins/request.md' link: '/reference/plugin/plugins/request.md',
}, },
{ {
text: '@fesjs/plugin-vuex', text: '@fesjs/plugin-vuex',
link: '/reference/plugin/plugins/vuex.md' link: '/reference/plugin/plugins/vuex.md',
}, },
{ {
text: '@fesjs/plugin-qiankun', text: '@fesjs/plugin-qiankun',
link: '/reference/plugin/plugins/qiankun.md' link: '/reference/plugin/plugins/qiankun.md',
}, },
{ {
text: '@fesjs/plugin-windicss', text: '@fesjs/plugin-windicss',
link: '/reference/plugin/plugins/windicss.md' link: '/reference/plugin/plugins/windicss.md',
}, },
{ {
text: '@fesjs/plugin-sass', text: '@fesjs/plugin-sass',
link: '/reference/plugin/plugins/sass.md' link: '/reference/plugin/plugins/sass.md',
}, },
{ {
text: '@fesjs/plugin-editor', text: '@fesjs/plugin-editor',
link: '/reference/plugin/plugins/editor.md' link: '/reference/plugin/plugins/editor.md',
}, },
{ {
text: '@fesjs/plugin-pinia', text: '@fesjs/plugin-pinia',
link: '/reference/plugin/plugins/pinia.md' link: '/reference/plugin/plugins/pinia.md',
}, },
{ {
text: '@fesjs/plugin-watermark', text: '@fesjs/plugin-watermark',
link: '/reference/plugin/plugins/watermark.md' link: '/reference/plugin/plugins/watermark.md',
}, },
{ {
text: '@fesjs/plugin-login', text: '@fesjs/plugin-login',
link: '/reference/plugin/plugins/login.md' link: '/reference/plugin/plugins/login.md',
}, },
{ {
text: '@fesjs/plugin-swc', text: '@fesjs/plugin-swc',
link: '/reference/plugin/plugins/swc.md' link: '/reference/plugin/plugins/swc.md',
}, },
], ],
}, },
@ -158,10 +166,10 @@ export const zh = {
text: '插件开发', text: '插件开发',
items: [{ items: [{
text: '插件介绍', text: '插件介绍',
link: '/reference/plugin/dev/index.md' link: '/reference/plugin/dev/index.md',
}, { }, {
text: '插件API', text: '插件API',
link: '/reference/plugin/dev/api.md' link: '/reference/plugin/dev/api.md',
}], }],
}, },
], ],

View File

@ -6,12 +6,12 @@ import { withBase } from 'vitepress'
## 依赖环境 ## 依赖环境
首先得有 [Node.js](https://nodejs.org/),并确保 node 版本是 12.13 或以上。 首先得有 [Node.js](https://nodejs.org/),并确保 node 版本是 `v18.12.0` 或以上。
```bash ```bash
# 打印 node 版本 # 打印 node 版本
node -v node -v
v12.13.0 v18.12.0
``` ```
推荐使用 [pnpm](https://pnpm.io/installation) 管理 npm 依赖 推荐使用 [pnpm](https://pnpm.io/installation) 管理 npm 依赖

View File

@ -1,28 +1,29 @@
# 从 2.0.x 迁移到 3.0.x # 从 2.x 迁移到 3.x
## 版本 3.0.x 的 break ## 版本 3.x 的 break
1. 编译时的 [base](../reference/config/index.md/#base) 配置,移到了 [router.base](../reference/config/index.md/#router) 下。 1. 环境要求 `node >= v18.12.0`
2. [webpack-dev-server](https://github.com/webpack/webpack-dev-server) 从 `v3.x` 升级到了 `v4.x`,如果遇到配置不兼容,可以查看[webpack-dev-server 3.x 升级 4.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md)。 2. 编译时的 [base](../reference/config/index.md/#base) 配置,移到了 [router.base](../reference/config/index.md/#router) 下
3. [layout 插件](../reference/plugin/plugins/layout.md#_4-x-升级到-5-x) 有一些属性变更 3. [webpack-dev-server](https://github.com/webpack/webpack-dev-server) 从 `v3.x` 升级到了 `v5.x`,如果遇到配置不兼容,可以查看[webpack-dev-server 3.x 升级 4.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md)、[webpack-dev-server 4.x 升级 5.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md)
3. [request 插件](../reference/plugin/plugins/request.md#_2-x-升级到-3-x) 有一些参数变更 4. [layout 插件](../reference/plugin/plugins/layout.md#_4-x-升级到-5-x) 有一些属性变更
5. [request 插件](../reference/plugin/plugins/request.md#_2-x-升级到-3-x) 有一些参数变更,升级请使用最新版本
## 继续使用 Webpack ## 继续使用 Webpack
1. 添加 Webpack 构建依赖包: `npm i @fesjs/builder-webpack -D` 1. 添加 Webpack 构建依赖包: `npm i @fesjs/builder-webpack -D`
2. 如果设置了 `publicPath: './'`,请更改为 `publicPath: ''` 2. `dev``publicPath` 配置不能为 `./`,请更改为 `auto`
3. 将 html 模版文件从 `public/index.html` 文件挪到项目根目录,移除 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 相关配置,具体模版变量使用请查看[HTML 模版](../guide/template.html) 3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,移除 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 相关配置,具体模版变量使用请查看[HTML 模版](../guide/template.html)
## 换成 Vite ## 换成 Vite
1. 安装依赖包 `npm i @fesjs/builder-vite` 1. 安装依赖包 `npm i @fesjs/builder-vite`
2. 将 Webpack 相关的配置换成 Vite具体可查看[配置](../reference/config/index.md) 2. 将 Webpack 相关的配置换成 Vite具体可查看[配置](../reference/config/index.md)
3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,如果有相应的 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 配置,需要改成 [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html) 的写法 3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,如果有相应的 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 配置,需要改成 [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html) 的写法
4. 将 `require` 等 Vite 不支持的代码,改写成 Vite 支持的方式 4. 将 `require` 等 Vite 不支持的代码,改写成 Vite 支持的方式
## 插件 ## 插件
插件都需要升级到 `3.0.x` 版本,新版添加了兼容`builder`的逻辑,但是提供的接口和配置没有变化,只需要升级版本即可使用。 插件都需要升级到 `3.x` 版本,新版添加了兼容`builder`的逻辑,但是提供的接口和配置没有变化,只需要升级版本即可使用。
- [@fesjs/plugin-layout](../reference/plugin/plugins/layout.md) 需要升级到`5.0.x`版本。 - [@fesjs/plugin-layout](../reference/plugin/plugins/layout.md) 需要升级到`5.0.x`版本。
- [@fesjs/plugin-locale](../reference/plugin/plugins/locale.md) 需要升级到`4.0.x`版本。 - [@fesjs/plugin-locale](../reference/plugin/plugins/locale.md) 需要升级到`4.0.x`版本。

View File

@ -93,6 +93,22 @@ export default {
}; };
``` ```
### console
- 类型: `object`
- 默认值:`{}`
- 详情:
用于控制应用启动的时候在 console 中打印的信息,目前仅支持 version
- 示例:
```js
export default {
console: {
version: true
}
};
```
### define ### define
- 类型: `object` - 类型: `object`

View File

@ -1,7 +1,7 @@
{ {
"name": "fes.js", "name": "fes.js",
"type": "module", "type": "module",
"version": "3.4.3", "version": "3.4.7",
"private": true, "private": true,
"packageManager": "pnpm@8.6.6", "packageManager": "pnpm@8.6.6",
"description": "一个好用的前端管理台快速开发框架", "description": "一个好用的前端管理台快速开发框架",

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/create-fes-app", "name": "@fesjs/create-fes-app",
"version": "3.0.4", "version": "3.0.6",
"description": "create a app base on fes.js", "description": "create a app base on fes.js",
"main": "lib/index.js", "main": "lib/index.js",
"files": [ "files": [

View File

@ -17,8 +17,8 @@
}, },
"dependencies": { "dependencies": {
"@fesjs/fes": "^3.0.0", "@fesjs/fes": "^3.0.0",
"@fesjs/plugin-access": "^3.0.0", "@fesjs/plugin-access": "^3.1.9",
"@fesjs/plugin-layout": "^5.0.0", "@fesjs/plugin-layout": "^5.4.3",
"@fesjs/plugin-model": "^3.0.0", "@fesjs/plugin-model": "^3.0.0",
"@fesjs/plugin-enums": "^3.0.0", "@fesjs/plugin-enums": "^3.0.0",
"@fesjs/fes-design": "^0.8.0", "@fesjs/fes-design": "^0.8.0",
@ -27,4 +27,4 @@
"core-js": "^3.29.1" "core-js": "^3.29.1"
}, },
"private": true "private": true
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/builder-webpack", "name": "@fesjs/builder-webpack",
"version": "3.0.14", "version": "3.1.0",
"description": "@fesjs/builder-webpack", "description": "@fesjs/builder-webpack",
"author": "qlin", "author": "qlin",
"license": "MIT", "license": "MIT",
@ -26,7 +26,7 @@
"access": "public" "access": "public"
}, },
"peerDependencies": { "peerDependencies": {
"@fesjs/fes": "^3.1.12", "@fesjs/fes": "^3.1.17",
"core-js": "^3.29.1" "core-js": "^3.29.1"
}, },
"dependencies": { "dependencies": {
@ -66,7 +66,7 @@
"webpack": "^5.90.3", "webpack": "^5.90.3",
"webpack-5-chain": "^8.0.1", "webpack-5-chain": "^8.0.1",
"webpack-bundle-analyzer": "^4.4.0", "webpack-bundle-analyzer": "^4.4.0",
"webpack-dev-server": "^4.15.1", "webpack-dev-server": "^5.1.0",
"webpackbar": "^5.0.2" "webpackbar": "^7.0.0"
} }
} }

View File

@ -1,19 +1,28 @@
import { extname } from 'path'; import { extname } from 'node:path';
import historyFallback from 'connect-history-api-fallback'; import historyFallback from 'connect-history-api-fallback';
const ASSET_EXT_NAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg']; const ASSET_EXT_NAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg'];
const proxyMiddleware = (api) => (req, res, next) => { function proxyMiddleware(api) {
const proxyConfig = api.config.proxy; return (req, res, next) => {
if (proxyConfig && Object.keys(proxyConfig).some((path) => req.url.startsWith(path))) { const proxyConfig = api.config.proxy;
return next(); if (proxyConfig) {
} if (Array.isArray(proxyConfig)) {
if (ASSET_EXT_NAMES.includes(extname(req.url))) { if (proxyConfig.some(item => item.context.some(path => path && req.url.startsWith(path)))) {
return next(); return next();
} }
}
else if (Object.keys(proxyConfig).some(path => req.url.startsWith(path))) {
return next();
}
}
if (ASSET_EXT_NAMES.includes(extname(req.url))) {
return next();
}
const history = historyFallback(); const history = historyFallback();
history(req, res, next); history(req, res, next);
}; };
}
export default proxyMiddleware; export default proxyMiddleware;

View File

@ -1,6 +1,23 @@
import WebpackDevServer from 'webpack-dev-server';
import webpack from 'webpack';
import { chalk } from '@fesjs/utils'; import { chalk } from '@fesjs/utils';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
function formatProxy(proxy) {
if (!proxy) {
return [];
}
if (Array.isArray(proxy)) {
return proxy;
}
return Object.keys(proxy).map((apiPath) => {
return {
context: [apiPath],
...proxy[apiPath],
};
});
}
export function startDevServer({ webpackConfig, host, port, proxy, https, beforeMiddlewares, afterMiddlewares, customerDevServerConfig }) { export function startDevServer({ webpackConfig, host, port, proxy, https, beforeMiddlewares, afterMiddlewares, customerDevServerConfig }) {
const options = { const options = {
@ -10,6 +27,7 @@ export function startDevServer({ webpackConfig, host, port, proxy, https, before
client: { client: {
logging: 'error', logging: 'error',
overlay: false, overlay: false,
progress: true,
webSocketURL: { webSocketURL: {
hostname: host, hostname: host,
port, port,
@ -27,12 +45,20 @@ export function startDevServer({ webpackConfig, host, port, proxy, https, before
...(customerDevServerConfig || {}), ...(customerDevServerConfig || {}),
port, port,
host, host,
proxy, proxy: formatProxy(proxy),
}; };
const compiler = webpack(webpackConfig); const compiler = webpack(webpackConfig);
const server = new WebpackDevServer(options, compiler); const server = new WebpackDevServer(options, compiler);
if (options.host === '0.0.0.0') {
console.log(chalk.green('Server: '), chalk.blue(`${options.server}://${options.host}:${options.port}`)); // eslint-disable-next-line no-console
console.log(chalk.green(' ➜ Local: '), chalk.cyan(`${options.server}://127.0.0.1:${options.port}`));
// eslint-disable-next-line no-console
console.log(chalk.gray(' ➜ Network: '), chalk.gray(`${options.server}://${options.host}:${options.port}`));
}
else {
// eslint-disable-next-line no-console
console.log(chalk.green(' ➜ :Local: '), chalk.cyan(`${options.server}://${options.host}:${options.port}`));
}
server.startCallback((err) => { server.startCallback((err) => {
if (err) { if (err) {
console.error(err); console.error(err);

View File

@ -1,5 +1,6 @@
import path from 'path'; import fs from 'node:fs';
import fs from 'fs'; import path from 'node:path';
import process from 'node:process';
import { cleanTmpPathExceptCache, getBundleAndConfigs } from '../../common/buildDevUtils'; import { cleanTmpPathExceptCache, getBundleAndConfigs } from '../../common/buildDevUtils';
import connectHistoryMiddleware from './connectHistoryMiddleware'; import connectHistoryMiddleware from './connectHistoryMiddleware';

View File

@ -1,13 +1,13 @@
import { join } from 'node:path';
import { existsSync } from 'node:fs'; import { existsSync } from 'node:fs';
import Config from 'webpack-5-chain'; import { join } from 'node:path';
import webpack from 'webpack'; import webpack from 'webpack';
import Config from 'webpack-5-chain';
import createCssWebpackConfig from './css'; import createCssWebpackConfig from './css';
import getBabelOpts from './getBabelOpts';
import createVueWebpackConfig from './vue';
import createDefineWebpackConfig from './define'; import createDefineWebpackConfig from './define';
import createMinimizerWebpackConfig from './minimizer'; import getBabelOpts from './getBabelOpts';
import createHtmlWebpackConfig from './html'; import createHtmlWebpackConfig from './html';
import createMinimizerWebpackConfig from './minimizer';
import createVueWebpackConfig from './vue';
const DEFAULT_EXCLUDE_NODE_MODULES = [ const DEFAULT_EXCLUDE_NODE_MODULES = [
'vue', 'vue',
@ -124,12 +124,14 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
webpackConfig.module webpackConfig.module
.rule('esm') .rule('esm')
.test(/\.m?jsx?$/) .test(/\.m?jsx?$/)
.resolve.set('fullySpecified', false); .resolve
.set('fullySpecified', false);
webpackConfig.module webpackConfig.module
.rule('js') .rule('js')
.test(/\.(js|mjs|jsx|ts|tsx)$/) .test(/\.(js|mjs|jsx|ts|tsx)$/)
.exclude.add((filepath) => { .exclude
.add((filepath) => {
// always transpile js in vue files // always transpile js in vue files
if (/(\.vue|\.jsx)$/.test(filepath)) { return false; } if (/(\.vue|\.jsx)$/.test(filepath)) { return false; }
@ -147,9 +149,11 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
webpackConfig.module webpackConfig.module
.rule('js-in-node_modules') .rule('js-in-node_modules')
.test(/\.(js|mjs)$/) .test(/\.(js|mjs)$/)
.include.add(/node_modules/) .include
.add(/node_modules/)
.end() .end()
.exclude.add((filepath) => { .exclude
.add((filepath) => {
if (transpileDepRegex && transpileDepRegex.test(filepath)) { return true; } if (transpileDepRegex && transpileDepRegex.test(filepath)) { return true; }
return false; return false;

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/compiler", "name": "@fesjs/compiler",
"version": "3.0.4", "version": "3.0.6",
"description": "@fesjs/compiler", "description": "@fesjs/compiler",
"author": "qlin", "author": "qlin",
"license": "MIT", "license": "MIT",

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/plugin-layout", "name": "@fesjs/plugin-layout",
"version": "5.4.1", "version": "5.4.5",
"description": "@fesjs/plugin-layout", "description": "@fesjs/plugin-layout",
"author": "harrywan", "author": "harrywan",
"license": "MIT", "license": "MIT",
@ -28,7 +28,7 @@
"access": "public" "access": "public"
}, },
"peerDependencies": { "peerDependencies": {
"@fesjs/fes": "^3.1.13", "@fesjs/fes": "^3.1.17",
"@fesjs/fes-design": ">=0.7.0", "@fesjs/fes-design": ">=0.7.0",
"vue": "^3.2.47", "vue": "^3.2.47",
"vue-router": "^4.0.1" "vue-router": "^4.0.1"

View File

@ -1,7 +1,7 @@
<template> <template>
<FMenu <FMenu
v-model:expandedKeys="expandedKeysRef" v-model:expanded-keys="expandedKeysRef"
:model-value="activePath" v-model="activeMenu"
:inverted="inverted" :inverted="inverted"
:mode="mode" :mode="mode"
:options="transformedMenus" :options="transformedMenus"
@ -12,9 +12,9 @@
</template> </template>
<script> <script>
import { computed, h, ref, watch } from 'vue';
import { FMenu } from '@fesjs/fes-design';
import { useRoute, useRouter } from '@@/core/coreExports'; import { useRoute, useRouter } from '@@/core/coreExports';
import { FMenu } from '@fesjs/fes-design';
import { computed, h, nextTick, ref, watch } from 'vue';
import { transform as transformByAccess } from '../helpers/pluginAccess'; import { transform as transformByAccess } from '../helpers/pluginAccess';
import { transform as transformByLocale } from '../helpers/pluginLocale'; import { transform as transformByLocale } from '../helpers/pluginLocale';
import { flatNodes } from '../helpers/utils'; import { flatNodes } from '../helpers/utils';
@ -79,6 +79,7 @@ export default {
const router = useRouter(); const router = useRouter();
const transformedMenus = computed(() => transformByLocale(transformByAccess(transform(props.menus)))); const transformedMenus = computed(() => transformByLocale(transformByAccess(transform(props.menus))));
const menuArray = computed(() => flatNodes(transformedMenus.value)); const menuArray = computed(() => flatNodes(transformedMenus.value));
const activePath = computed(() => { const activePath = computed(() => {
const matchMenus = menuArray.value.filter((menu) => { const matchMenus = menuArray.value.filter((menu) => {
const match = menu.match; const match = menu.match;
@ -96,6 +97,12 @@ export default {
return matchMenus[0].path; return matchMenus[0].path;
}); });
const activeMenu = ref(activePath.value);
watch(activePath, () => {
activeMenu.value = activePath.value;
});
const expandedKeysRef = ref(props.expandedKeys); const expandedKeysRef = ref(props.expandedKeys);
watch( watch(
@ -132,9 +139,17 @@ export default {
query: currentMenu?.query || {}, query: currentMenu?.query || {},
params: currentMenu?.params || {}, params: currentMenu?.params || {},
}); });
// TODO
nextTick(() => {
activeMenu.value = activePath.value;
});
window.open(resolved.href, '_blank'); window.open(resolved.href, '_blank');
} }
else if (/^https?:\/\//.test(path)) { else if (/^https?:\/\//.test(path)) {
// TODO
nextTick(() => {
activeMenu.value = activePath.value;
});
window.open(path, '_blank'); window.open(path, '_blank');
} }
else if (/^\//.test(path)) { else if (/^\//.test(path)) {
@ -150,6 +165,7 @@ export default {
}; };
return { return {
activeMenu,
activePath, activePath,
expandedKeysRef, expandedKeysRef,
transformedMenus, transformedMenus,

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/preset-built-in", "name": "@fesjs/preset-built-in",
"version": "3.1.11", "version": "3.1.14",
"description": "@fesjs/preset-built-in", "description": "@fesjs/preset-built-in",
"author": "qlin", "author": "qlin",
"license": "MIT", "license": "MIT",
@ -29,7 +29,7 @@
"vue": "^3.2.47" "vue": "^3.2.47"
}, },
"dependencies": { "dependencies": {
"@fesjs/compiler": "^3.0.4", "@fesjs/compiler": "^3.0.6",
"@fesjs/runtime": "^3.0.1", "@fesjs/runtime": "^3.0.1",
"@fesjs/utils": "^3.0.3", "@fesjs/utils": "^3.0.3",
"@vue/compiler-sfc": "^3.3.4", "@vue/compiler-sfc": "^3.3.4",

View File

@ -16,6 +16,7 @@ export default function () {
require.resolve('./plugins/features/alias'), require.resolve('./plugins/features/alias'),
require.resolve('./plugins/features/autoprefixer'), require.resolve('./plugins/features/autoprefixer'),
require.resolve('./plugins/features/define'), require.resolve('./plugins/features/define'),
require.resolve('./plugins/features/console'),
require.resolve('./plugins/features/dynamicImport'), require.resolve('./plugins/features/dynamicImport'),
require.resolve('./plugins/features/globalCSS'), require.resolve('./plugins/features/globalCSS'),
require.resolve('./plugins/features/inlineLimit'), require.resolve('./plugins/features/inlineLimit'),

View File

@ -12,6 +12,8 @@ import DefaultContainer from './defaultContainer.vue';
{{{ entryCodeAhead }}} {{{ entryCodeAhead }}}
{{{ CONSOLE }}}
const renderClient = (opts = {}) => { const renderClient = (opts = {}) => {
const { plugin, routes, rootElement } = opts; const { plugin, routes, rootElement } = opts;
const rootContainer = plugin.applyPlugins({ const rootContainer = plugin.applyPlugins({

View File

@ -13,6 +13,15 @@ export function importsToStr(imports) {
}); });
} }
function getConsoleInfo(config, pkg) {
if (config.console?.version) {
return `
console.log('%c[${pkg.name}]%c${pkg.version}', 'background-color: #1677ff; border-top-left-radius: 6px; border-bottom-left-radius: 6px; color: white; padding: 4px', 'background-color: #42b983; border-top-right-radius: 6px; border-bottom-right-radius: 6px; color: white; padding: 4px');
`;
}
return '';
}
export default function (api) { export default function (api) {
const { const {
utils: { Mustache }, utils: { Mustache },
@ -24,6 +33,7 @@ export default function (api) {
path: 'fes.js', path: 'fes.js',
content: Mustache.render(fesTpl, { content: Mustache.render(fesTpl, {
enableTitle: api.config.title !== false, enableTitle: api.config.title !== false,
CONSOLE: getConsoleInfo(api.config, api.pkg),
defaultTitle: api.config.title || 'fes.js', defaultTitle: api.config.title || 'fes.js',
runtimePath, runtimePath,
rootElement: `#${api.config.mountElementId || 'app'}`, rootElement: `#${api.config.mountElementId || 'app'}`,

View File

@ -0,0 +1,13 @@
export default (api) => {
api.describe({
key: 'console',
config: {
default: {
version: false,
},
schema(joi) {
return joi.object().description('output info in console, default version');
},
},
});
};

View File

@ -1,8 +1,8 @@
import { Component, DefineComponent, Component, App } from 'vue'; import type { App, Component, DefineComponent } from 'vue';
import { RouteRecordRaw, Router, RouterHistory, createMemoryHistory, createWebHashHistory, createWebHistory } from 'vue-router'; import type { createMemoryHistory, createWebHashHistory, createWebHistory, Router, RouteRecordRaw, RouterHistory } from 'vue-router';
// @ts-ignore // @ts-ignore
import { Plugin } from '@fesjs/runtime'; import type { Plugin } from '@fesjs/runtime';
interface BeforeRenderConfig { interface BeforeRenderConfig {
loading: Component; loading: Component;
@ -44,6 +44,9 @@ declare module '@fesjs/fes' {
interface PluginBuildConfig { interface PluginBuildConfig {
globalCSS?: 'beforeImports' | 'afterImports'; globalCSS?: 'beforeImports' | 'afterImports';
alias?: Record<string, string>; alias?: Record<string, string>;
console?: {
version?: boolean;
};
autoprefixer?: { autoprefixer?: {
/** environment for `Browserslist` */ /** environment for `Browserslist` */
env?: string; env?: string;
@ -86,10 +89,10 @@ declare module '@fesjs/fes' {
dynamicImport?: boolean; dynamicImport?: boolean;
inlineLimit?: number; inlineLimit?: number;
mock?: mock?:
| boolean | boolean
| { | {
prefix?: string; prefix?: string;
}; };
mountElementId?: string; mountElementId?: string;
plugins?: string[]; plugins?: string[];
presets?: string[]; presets?: string[];

View File

@ -8,6 +8,9 @@ export default defineBuildConfig({
define: { define: {
__DEV__: false, __DEV__: false,
}, },
console: {
version: true,
},
html: { html: {
title: '海贼王', title: '海贼王',
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@fesjs/fes", "name": "@fesjs/fes",
"version": "3.1.13", "version": "3.1.17",
"description": "一个好用的前端管理台快速开发框架", "description": "一个好用的前端管理台快速开发框架",
"preferGlobal": true, "preferGlobal": true,
"scripts": { "scripts": {
@ -38,8 +38,8 @@
"strong" "strong"
], ],
"dependencies": { "dependencies": {
"@fesjs/compiler": "^3.0.4", "@fesjs/compiler": "^3.0.6",
"@fesjs/preset-built-in": "^3.1.11", "@fesjs/preset-built-in": "^3.1.14",
"@fesjs/runtime": "^3.0.1", "@fesjs/runtime": "^3.0.1",
"@fesjs/utils": "^3.0.3", "@fesjs/utils": "^3.0.3",
"pirates": "^4.0.5", "pirates": "^4.0.5",

View File

@ -1,17 +1,16 @@
import process from 'node:process'; import process from 'node:process';
import { chalk, semver, yParser } from '@fesjs/utils'; import { chalk, semver, yParser } from '@fesjs/utils';
import fesPkg from '../package.json'; import fesPkg from '../package.json';
import { hackFesInBuild } from './hackFesInBuild';
import { Service } from './serviceWithBuiltIn'; import { Service } from './serviceWithBuiltIn';
import fork from './utils/fork'; import fork from './utils/fork';
import getCwd from './utils/getCwd'; import getCwd from './utils/getCwd';
import getPkg from './utils/getPkg'; import getPkg from './utils/getPkg';
import { hackFesInBuild } from './hackFesInBuild';
const requiredVersion = fesPkg.engines.node; const requiredVersion = fesPkg.engines.node;
function checkNodeVersion(wanted, id) { function checkNodeVersion(wanted, id) {
if (!semver.satisfies(process.version, wanted, { includePrerelease: true })) { if (!semver.satisfies(process.version, wanted, { includePrerelease: true })) {
// eslint-disable-next-line no-console
console.log(chalk.red(`You are using Node ${process.version}, but this version of ${id} requires Node ${wanted}.\nPlease upgrade your Node version.`)); 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); process.exit(1);
} }
@ -29,21 +28,21 @@ const args = yParser(rawArgv);
const child = fork({ const child = fork({
scriptPath: require.resolve('./forkedDev'), scriptPath: require.resolve('./forkedDev'),
}); });
// ref:
// http://nodejs.cn/api/process/signal_events.html // http://nodejs.cn/api/process/signal_events.html
process.on('SIGINT', () => { process.on('SIGINT', () => {
child.kill('SIGINT'); child.kill('SIGINT');
process.exit(1); process.exit();
}); });
process.on('SIGTERM', () => { process.on('SIGTERM', () => {
child.kill('SIGTERM'); child.kill('SIGTERM');
process.exit(1); process.exit();
}); });
} }
else { else {
hackFesInBuild(); hackFesInBuild();
if (command === 'build') if (command === 'build') {
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
}
await new Service({ await new Service({
cwd: getCwd(), cwd: getCwd(),

View File

@ -21,8 +21,9 @@ export default function start({ scriptPath }) {
catch (e) { catch (e) {
port = 9230; // node default inspect port plus 1. port = 9230; // node default inspect port plus 1.
} }
if (usedPorts.includes(port)) if (usedPorts.includes(port)) {
port += 1; port += 1;
}
usedPorts.push(port); usedPorts.push(port);
return `--inspect-brk=${port}`; return `--inspect-brk=${port}`;
@ -31,8 +32,9 @@ export default function start({ scriptPath }) {
} }
// set port to env when current port has value // set port to env when current port has value
if (CURRENT_PORT) if (CURRENT_PORT) {
process.env.PORT = CURRENT_PORT; process.env.PORT = CURRENT_PORT;
}
const child = fork(scriptPath, process.argv.slice(2), { const child = fork(scriptPath, process.argv.slice(2), {
execArgv, execArgv,

2051
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff