挑战21天手写前端框架 day13 解析用户配置文件,将框架行为交到用户手里

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 挑战21天手写前端框架 day13 解析用户配置文件,将框架行为交到用户手里

image.png


阅读本文需要 5 分钟,编写本文耗时 1 小时


到目前为止,我们的框架行为都是由我们的设计开发时制定的,但是实际项目中肯定会涉及到用户需要定制化的一些数据和定制化需求,由于我们并不是要写一个真正的前端框架,因此我们还是以管控能力为主,尽量将最少的配置能力给到用户。尽量只让用户配置一些框架无关的信息和数据,这将意味着用户需要知道的前端工程化的东西非常的少。借此来提升本次框架的用户开发体验。即整个项目技术栈的选择,都有框架设计统一制定。其实这个思路非常适合用在公司内部团队中构建的框架方案中。


首先依旧随便约定一个配置文件的名字 malita.config.ts 然后将它放到根目录下,然后我们还是用昨天构建“生命周期函数”的方式,增加一个生命周期,getUserConfig


比如就按住我们昨天留下的两个配置需求将真正的 keepalive 需求,传递到 中,使用用户配置 title 作为页面 dom 的title。

export default {
    title: 'Hello',
    keepalive: [/./]
}
复制代码


然后我们尝试着将它引入到我们的框架中,

import { existsSync } from 'fs';
import path from 'path';
import type { AppData } from './appData';
import { DEFAULT_CONFIG_FILE } from './constants';
export const getUserConfig = ({ appData }: { appData: AppData; }) => {
    return new Promise((resolve, rejects) => {
        let config = {};
        const configFile = path.resolve(appData.paths.absSrcPath, DEFAULT_CONFIG_FILE);
        if (existsSync(configFile)) {
            config = require(configFile).default;
        }
        resolve(config);
    })
}
复制代码


结果并不像我们设想的那样被成功引入,我们在控制台上看到有如下错误:

/Users/congxiaochen/Documents/malita/examples/app/malita.config.ts:1
export default {
^^^^^^
SyntaxError: Unexpected token 'export'
复制代码


这是因为我们的 malita dev 是运行在 es5 的环境下的。但是我们的配置文件使用的却是 es6 的语法。 我们可以尝试着修改配置文件``,将它改成 es5 的语法

module.exports = {
    title: 'Hello',
    keepalive: [/./]
}
复制代码


这是便可以正确获取到配置信息了

> malita dev
App listening at http://127.0.0.1:8888
{ title: 'Hello', keepalive: [ /./ ] }
复制代码



配置构建

所有当你在框架开发中遇到类似的错误时,你就可以往语法未正确转换,即文件未编译这个思路上去分析和定位,做同样的尝试,如果修改后文件可用,那么你就可以确定下来问题所在。在提出针对性的解法,比如这里文件未转译,我们就使用 esbuild 对文件进行构建。


构建方法与我们构建主入口文件一直,需要注意的是我们需要导出使用,因此需将 format 改为 cjs:

import { existsSync } from 'fs';
import path from 'path';
import { build } from 'esbuild';
import type { AppData } from './appData';
import { DEFAULT_CONFIG_FILE } from './constants';
export const getUserConfig = ({ appData, sendMessage }: { appData: AppData; sendMessage: (type: string, data?: any) => void; }) => {
    return new Promise(async (resolve, rejects) => {
        let config = {};
        const configFile = path.resolve(appData.paths.cwd, DEFAULT_CONFIG_FILE);
        if (existsSync(configFile)) {
            await build({
                format: 'cjs',
                logLevel: 'error',
                outdir: appData.paths.absOutputPath,
                bundle: true,
                watch: {
                    onRebuild: (err, res) => {
                        if (err) {
                            console.error(JSON.stringify(err));
                            return;
                        }
                        sendMessage('reload');
                    }
                },
                define: {
                    'process.env.NODE_ENV': JSON.stringify('development'),
                },
                external: ['esbuild'],
                entryPoints: [configFile],
            });
            try {
                config = require(path.resolve(appData.paths.absOutputPath, 'malita.config.js')).default;
            } catch (error) {
                console.error('getUserConfig error', error);
                rejects(error);
            }
        }
        resolve(config);
    })
}
复制代码



配置使用

keepalive

keepalive 配置传递到 generateEntry 函数中 ,修改 malita.config.ts 中的配置,验证配置是否有效。我们将状态保持配置修改为只有 users 页面能够被保持。

export default {
    title: 'Hello',
    keepalive: ['/users']
}
复制代码


值得注意的是,我们的 keepalive 配置是支撑正则表达式的,但是正则表达式在 JSON.stringify 会被转换成 {},因此我们需要编写一个工具类,来对这个配置做特殊的处理,

const configStringify = (config: (string | RegExp)[]) => {
    return config.map((item) => {
        if (item instanceof RegExp) {
            return item;
        }
        return `'${item}'`;
    });
};
复制代码


然后修改 KeepAliveLayout 配置的获取方式

`
const App = () => {
    return (
        <KeepAliveLayout keepalive={[${configStringify(
            (userConfig.keepalive) || [],
        )}]}>
            <HashRouter>
                <Routes>
                    ${routesStr}
                </Routes>
            </HashRouter>
        </KeepAliveLayout>
    );
}
`
复制代码


执行 malita dev 验证效果。


title

title 配置传递到 generateHtml 函数中

const title = userConfig?.title ?? appData.pkg.name ?? 'Malita';
 <title>${title}</title>
复制代码


打开页面重控制台查看页面的 html

<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
复制代码


至此我们就简单的完成了用户配置的功能,不知道有没有细心的小伙伴发现了,在 malita dev 启动之后,修改配置之后,虽然页面有重新加载,但是配置数据的变更并没有被真正的覆盖到原来的逻辑,原因是我们仅仅重启了我们的浏览器端,但是并没有重启我们的服务端,这个问题我们将会在明天解决。


感谢阅读,明天我们将会解决上面提到的问题,并且添加框架内置的 http 请求方法,用于在项目中请求服务端数据。其中将会涉及到本地 mock 文件的解析和代理中间件的编写。如果你对这些内容感兴趣,请持续 follow 这个专题。


源码归档

目录
相关文章
|
1月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
75 9
|
1月前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
31 9
|
1月前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
48 12
|
1月前
|
机器学习/深度学习 编解码 前端开发
探索无界:前端开发中的响应式设计深度解析####
【10月更文挑战第29天】 在当今数字化时代,用户体验的优化已成为网站与应用成功的关键。本文旨在深入探讨响应式设计的核心理念、技术实现及最佳实践,揭示其如何颠覆传统布局限制,实现跨设备无缝对接,从而提升用户满意度和访问量。通过剖析响应式设计的精髓,我们将一同见证其在现代Web开发中的重要地位与未来趋势。 ####
45 7
|
1月前
|
编解码 前端开发 UED
探索无界:前端开发中的响应式设计深度解析与实践####
【10月更文挑战第29天】 本文深入探讨了响应式设计的核心理念,即通过灵活的布局、媒体查询及弹性图片等技术手段,使网站能够在不同设备上提供一致且优质的用户体验。不同于传统摘要概述,本文将以一次具体项目实践为引,逐步剖析响应式设计的关键技术点,分享实战经验与避坑指南,旨在为前端开发者提供一套实用的响应式设计方法论。 ####
52 4
|
2月前
|
JavaScript 前端开发 测试技术
前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架
本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。
130 7
|
22天前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
1月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
66 1
|
1月前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
36 1
|
2月前
|
人工智能 资源调度 数据可视化
【AI应用落地实战】智能文档处理本地部署——可视化文档解析前端TextIn ParseX实践
2024长沙·中国1024程序员节以“智能应用新生态”为主题,吸引了众多技术大咖。合合信息展示了“智能文档处理百宝箱”的三大工具:可视化文档解析前端TextIn ParseX、向量化acge-embedding模型和文档解析测评工具markdown_tester,助力智能文档处理与知识管理。

推荐镜像

更多