diff --git a/docs/.vuepress/configs/sidebar/en.ts b/docs/.vuepress/configs/sidebar/en.ts index 510be41f..cbd8c194 100644 --- a/docs/.vuepress/configs/sidebar/en.ts +++ b/docs/.vuepress/configs/sidebar/en.ts @@ -15,6 +15,7 @@ export const en: SidebarConfig = { text: '基础', children: [ '/guide/directory-structure.md', + '/guide/builder.md', '/guide/config.md', '/guide/runtime-config.md', '/guide/env.md', diff --git a/docs/.vuepress/configs/sidebar/zh.ts b/docs/.vuepress/configs/sidebar/zh.ts index dd87e85f..e46b036d 100644 --- a/docs/.vuepress/configs/sidebar/zh.ts +++ b/docs/.vuepress/configs/sidebar/zh.ts @@ -15,6 +15,7 @@ export const zh: SidebarConfig = { text: '基础', children: [ '/zh/guide/directory-structure.md', + '/zh/guide/builder.md', '/zh/guide/config.md', '/zh/guide/runtime-config.md', '/zh/guide/env.md', diff --git a/docs/zh/guide/builder.md b/docs/zh/guide/builder.md new file mode 100644 index 00000000..d76e64df --- /dev/null +++ b/docs/zh/guide/builder.md @@ -0,0 +1,22 @@ +# 支持 Vite 和 Webpack 双构建 + +`Fes.js@2.1.x` 版本支持 Vite 和 Webpack 两种构建方式,不再内置构建方式,需要开发者自行选择: + +- 选用 Vite 构建,安装 `npm i @fesjs/build-vite` 依赖即可。 +- 选用 Webpack 构建,安装 `npm i @fesjs/build-webpack` 依赖即可。 + +## 使用差异 + +由于 Fes.js 在 Vite 和 Webpack 上做了一层封装,开发者关心的构建配置不会太多。从使用上来说,主要存在以下几个差异点: + +### 配置 + +Webpack 和 Vite 构建在配置方面有一些差异,具体可以查阅[配置](../reference/config)。 + +### 静态文件处理 + +由于 Vite 的限制,不支持 `require` 语法,具体 Vite 的用法可以查看[官网](https://cn.vitejs.dev/guide/assets.html) + +### html 模版 + +Webpack 对于 html 模版是没有什么限制的,而 Vite 推荐模版文件就放在项目根目录下。Webpack 有个非常强大的 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin),Fes.js 引入了[vite-plugin-html](https://github.com/vbenjs/vite-plugin-html) 进行能力的对齐,如果开发者想要个性化定制模版,那么在配置上还是存在差异的。 diff --git a/docs/zh/guide/config.md b/docs/zh/guide/config.md index b8bbf5bb..d201c129 100644 --- a/docs/zh/guide/config.md +++ b/docs/zh/guide/config.md @@ -1,87 +1,104 @@ -# 配置 +# 编译时配置 -Fes.js 约定 `.fes.js` 文件为项目编译需要配置文件,可以引入 node 端依赖项,不要引入浏览器端依赖项。 +Fes.js 约定 `.fes.js` 文件为项目编译需要编译时配置文件,可以引入 node 端依赖项,不要引入浏览器端依赖项。 - -一份常见的配置示例如下: +一份常见的配置示例如下(更多配置项请查阅[配置](../reference/config)): ```js -export default { +import { defineBuildConfig } from '@fesjs/fes'; + +export default defineBuildConfig({ base: '/foo/', publicPath: '/', devServer: { - port: 8080 + port: 8080, }, mock: { - prefix: '/v2' + prefix: '/v2', }, proxy: { '/v2': { - 'target': 'https://api.douban.com/', - 'changeOrigin': true, + target: 'https://api.douban.com/', + changeOrigin: true, }, }, layout: { - title: "Fes.js", + title: 'Fes.js', footer: 'Created by MumbelFe', multiTabs: false, - menus: [{ - name: 'index' - }, { - name: 'onepiece' - }, { - name: 'store' - }, { - name: 'simpleList' - }] - } -} + menus: [ + { + name: 'index', + }, + { + name: 'onepiece', + }, + { + name: 'store', + }, + { + name: 'simpleList', + }, + ], + }, +}); ``` ## 本地临时配置文件 + 可以新建 `.fes.local.js` 作为本地临时配置文件。这份配置会和 `.fes.js` 做 `deep merge` 后形成最终配置。 + ```js // .fes.js export default { mock: false }; // .fes.local.js -export default { +export default { mock: true, devServer: { port: 8080 } }; ``` + 最终的配置是: + ```js -{ +{ mock: true, devServer: { port: 8080 } }; ``` + ::: warning -`.fes.local.js` 是本地验证使用的临时配置,仅在 `fes dev` 时有效,请将其添加到 `.gitignore`,务必不要提交到 `git` 仓库中。 +`.fes.local.js` 是本地验证使用的临时配置,仅在 `fes dev` 时有效,请将其添加到 `.gitignore`,不要提交到 `git` 仓库中。 ::: ## 多环境多份配置 + 可以通过环境变量 `FES_ENV` 区分不同环境,来指定当前环境的配置文件,这份配置会和 `.fes.js` 做 `deep merge` 后形成最终配。 比如配置如下: + ```js // .fes.js export default { mock: false }; // .fes.uat.js -export default { +export default { mock: true, devServer: { port: 8080 } }; ``` + 当我们运行: + ```bash FES_ENV=uat fes dev ``` + 这时候会命中 `.fes.uat.js` 这份环境配置,最终配置是: + ```js -{ +{ mock: true, devServer: { port: 8080 } }; @@ -89,8 +106,8 @@ FES_ENV=uat fes dev ## 优先级 -本地临时配置 > 环境配置 > 基础配置 +本地临时配置 > 环境配置 > 基础配置 ::: tip 如果多份配置中存在相同的配置项,**则优先级高的会覆盖优先级低的**。 -::: +::: diff --git a/docs/zh/guide/runtime-config.md b/docs/zh/guide/runtime-config.md index 11e24a73..1fa76eab 100644 --- a/docs/zh/guide/runtime-config.md +++ b/docs/zh/guide/runtime-config.md @@ -8,20 +8,75 @@ Fes.js 框架跟传统开发模式不一样。传统开发模式中用户编写 例如: -plugin-acess插件定义运行时配置项: +plugin-acess 插件定义运行时配置项: + ```js api.addRuntimePluginKey(() => 'access'); ``` -plugin-acess插件读取配置项: + +plugin-acess 插件读取配置项: + ```js const runtimeConfig = plugin.applyPlugins({ key: 'access', type: ApplyPluginsType.modify, - initialValue: {} + initialValue: {}, }); ``` 而用户则只需要配置: + +```js +// app.js +import { defineBuildConfig } from '@fesjs/fes'; + +export default defineRuntimeConfig({ + access: memo => ({ + ...memo + unAccessHandler({ + router, to, from, next + }) { + // 处理逻辑 + }, + noFoundHandler({ + router, to, from, next + }) { + // 处理逻辑 + }, + }), +}); +``` + +## 配置智能提示 + +配置可以单独导出,也可以通过 `defineRuntimeConfig` 工具函数获取类型提示。 + +方式一(推荐,有类型提示): + +```js +// app.js +import { defineBuildConfig } from '@fesjs/fes'; + +export default defineRuntimeConfig({ + access: memo => ({ + ...memo + unAccessHandler({ + router, to, from, next + }) { + // 处理逻辑 + }, + noFoundHandler({ + router, to, from, next + }) { + // 处理逻辑 + }, + }), + // ...其他配置项 +}); +``` + +方式二: + ```js // app.js export const access = memo => ({ @@ -37,7 +92,6 @@ export const access = memo => ({ // 处理逻辑 }, }); - ``` ## 配置项 @@ -49,6 +103,7 @@ beforeRender(lastOpts) 在渲染之前执行,执行`action`过程中显示 `loading` 配置的组件,执行结果作为参数 `initialState` 传给 `modifyClientRenderOpts`。 示例: + ```js // app.js import { access } from '@fesjs/fes'; @@ -65,31 +120,32 @@ export function beforeRender(lastOpts) { setTimeout(() => { setRole('admin'); resolve({ - userName: 'harrywan' + userName: 'harrywan', }); }, 1000); }); - } - } -}; + }, + }; +} ``` ### patchRoutes patchRoutes({routes }) - 修改路由。 比如在最前面添加一个 /foo 路由: -``` + +```js export function patchRoutes({ routes }) { - routes.unshift({ - path: '/foo', - component: require('@/extraRoutes/foo').default, - }); + routes.unshift({ + path: '/foo', + component: require('@/extraRoutes/foo').default, + }); } ``` + :::tip 直接修改 `routes`, 不需要返回 ::: @@ -99,18 +155,20 @@ export function patchRoutes({ routes }) { modifyClientRenderOpts(lastOpts) 修改 `clientRender` 参数。参数是一个对象: -- routes,路由配置信息 -- rootElement, 渲染的根节点,默认是 `#app`,可通过配置 `mountElementId` 修改。 -- initialState, 初始化数据,`beforeRender` 运行得到的数据。 + +- routes,路由配置信息 +- rootElement, 渲染的根节点,默认是 `#app`,可通过配置 `mountElementId` 修改。 +- initialState, 初始化数据,`beforeRender` 运行得到的数据。 比如在微前端里动态修改渲染根节点: + ```js let isSubApp = false; export function modifyClientRenderOpts(lastOpts) { - return { - ...lastOpts, - rootElement: isSubApp ? 'sub-root' : lastOpts.rootElement, - }; + return { + ...lastOpts, + rootElement: isSubApp ? 'sub-root' : lastOpts.rootElement, + }; } ``` @@ -120,12 +178,13 @@ rootContainer(LastRootContainer, args) 修改交给 Vue 渲染时的根组件,默认是 ``。 -- LastRootContainer,上一个插件修改后的结果。 -- args,包含: - - routes,全量路由配置 - - plugin,运行时插件机制 +- LastRootContainer,上一个插件修改后的结果。 +- args,包含: + - routes,全量路由配置 + - plugin,运行时插件机制 + +比如在可以包一层 DIV: -比如在可以包一层DIV: ```js export function rootContainer(container) { return () => { @@ -133,8 +192,8 @@ export function rootContainer(container) {
- ) - } + ); + }; } ``` @@ -145,14 +204,14 @@ onAppCreated({app}) 创建 app 实例后触发。 比如用于安装 Vue 插件: + ```js -import { createRouter } from "vue-router"; +import { createRouter } from 'vue-router'; export function onAppCreated({ app }) { const router = createRouter(); app.use(router); } - ``` ### render @@ -163,22 +222,22 @@ render(oldRender: Function) 比如用于渲染之前做权限校验。 - - ### onRouterCreated onRouterCreated({router}) -生成router时触发。 +生成 router 时触发。 比如用于收集切换路由的记录: + ```js export function onRouterCreated({ router }) { router.afterEach((to, from) => { - console.log(to) + console.log(to); }); } ``` ## 更多配置项 -Fes.js 允许插件注册运行时配置,如果你使用插件,肯定会在插件里找到更多运行时的配置项。 \ No newline at end of file + +Fes.js 允许插件注册运行时配置,如果你使用插件,肯定会在插件里找到更多运行时的配置项。 diff --git a/docs/zh/reference/config/README.md b/docs/zh/reference/config/README.md index dd4c1225..7fed58e7 100644 --- a/docs/zh/reference/config/README.md +++ b/docs/zh/reference/config/README.md @@ -208,7 +208,7 @@ export default { - 默认值: `/` - 详情: - 配置 webpack 的 publicPath。当打包的时候,webpack 会在静态文件路径前面添加 `publicPath` 的值,当你需要修改静态文件地址时,比如使用 CDN 部署,把 `publicPath` 的值设为 CDN 的值就可以。 + 静态资源 publicPath。当打包的时候在静态文件路径前面添加 `publicPath` 的值,当你需要修改静态文件地址时,比如使用 CDN 部署,把 `publicPath` 的值设为 CDN 的值就可以。 ### router @@ -282,7 +282,7 @@ const defaultTerserOptions = { 配置 [压缩器 terser 的配置项](https://github.com/terser/terser#minify-options) -## webpack 构建专属配置 +## webpack 专属配置 ### analyze diff --git a/docs/zh/reference/plugin/plugins/sass.md b/docs/zh/reference/plugin/plugins/sass.md index c810a20b..b7abd5a9 100644 --- a/docs/zh/reference/plugin/plugins/sass.md +++ b/docs/zh/reference/plugin/plugins/sass.md @@ -1,27 +1,34 @@ # @fesjs/plugin-sass - - ## 介绍 -Fes.js 默认只支持 `less`,通过此插件扩展支持 `sass` + +Fes.js 默认只支持 `less`,通过此插件扩展支持 `sass`。 + +::: tip webpack 构建 sass 插件 +如果使用 Vite 构建,直接装 `sass` 依赖即可,不需要安装此插件。 +::: ## 启用方式 + 在 `package.json` 中引入依赖: + ```json { "dependencies": { "@fesjs/fes": "^2.0.0", "@fesjs/plugin-sass": "^2.0.0" - }, + } } ``` ## global css -添加 `src/global.scss` 和 `src/global.sass` 为全局CSS入口,添加一些通用样式内容。 + +添加 `src/global.scss` 和 `src/global.sass` 为全局 CSS 入口,添加一些通用样式内容。 ## Vue 单文件组件 + Vue 单文件组件的 `` 添加 `lang='scss'`,例如: + ```vue - -``` + +``` diff --git a/packages/fes-build-vite/package.json b/packages/fes-build-vite/package.json index 49dd5ece..988b8032 100644 --- a/packages/fes-build-vite/package.json +++ b/packages/fes-build-vite/package.json @@ -29,6 +29,7 @@ "@vitejs/plugin-vue": "^2.2.4", "@vitejs/plugin-vue-jsx": "^1.3.8", "autoprefixer": "^10.4.4", + "less": "^4.1.2", "postcss-flexbugs-fixes": "^5.0.2", "postcss-safe-parser": "^6.0.0", "rollup-plugin-visualizer": "^5.6.0", diff --git a/packages/fes-build-webpack/src/plugins/registerType.js b/packages/fes-build-webpack/src/plugins/registerType.js index ddeb5791..2e8c1139 100644 --- a/packages/fes-build-webpack/src/plugins/registerType.js +++ b/packages/fes-build-webpack/src/plugins/registerType.js @@ -1,4 +1,4 @@ -import { name } from '../package.json'; +import { name } from '../../package.json'; export default function (api) { api.addConfigType(() => ({ diff --git a/packages/fes-preset-built-in/src/plugins/features/targets.js b/packages/fes-preset-built-in/src/plugins/features/targets.js index 0ff68fc1..03b6ddd5 100644 --- a/packages/fes-preset-built-in/src/plugins/features/targets.js +++ b/packages/fes-preset-built-in/src/plugins/features/targets.js @@ -5,7 +5,7 @@ export default (api) => { default: { chrome: 56, firefox: 67, - safari: 10.4, + safari: 10, edge: 13, }, schema(joi) { diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl b/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl index 0763c160..7c530a39 100644 --- a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl +++ b/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl @@ -8,7 +8,7 @@ const defaultKey = 'default'; {{#plugins}} plugin.register({ - apply: Plugin_{{{ index }}}[defaultKey] ? Plugin_{{{ index }}}[defaultKey] : Plugin_{{{ index }}}, + apply: {...Plugin_{{{ index }}}[defaultKey], ...Plugin_{{{ index }}}}, path: '{{{ path }}}', }); {{/plugins}} diff --git a/yarn.lock b/yarn.lock index 280fa02e..314980c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5094,6 +5094,13 @@ cookie@0.4.2, cookie@^0.4.2: resolved "https://registry.npmmirror.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" @@ -5428,7 +5435,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, d dependencies: ms "2.1.2" -debug@^3.1.1, debug@^3.2.7: +debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -7616,7 +7623,7 @@ husky@^4.3.0: slash "^3.0.0" which-pm-runs "^1.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -8174,6 +8181,11 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -8960,6 +8972,23 @@ less@3.9.0: request "^2.83.0" source-map "~0.6.0" +less@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^2.5.2" + source-map "~0.6.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -9790,6 +9819,15 @@ natural-compare@^1.4.0: resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +needle@^2.5.2: + version "2.9.1" + resolved "https://registry.npmmirror.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.3, negotiator@^0.6.2: version "0.6.3" resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -10472,6 +10510,11 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -11772,6 +11815,11 @@ sass@^1.49.10: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + saxes@^5.0.1: version "5.0.1" resolved "https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -12983,7 +13031,7 @@ tslib@^1.10.0, tslib@^1.9.0: resolved "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.1.0: +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0: version "2.3.1" resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==