精华内容
下载资源
问答
  • 前端架构--从入门到微前端

    千次阅读 2019-11-18 19:08:12
    – 一个前端开发者的个人思考)时,考量了一段时间「微前端」,也关注到了《微前端的那些事儿》的文章,从而了解了作者「黄峰达」,也就购买了下面将要聊的书《前端架构:从入门到微前端》 本书围绕前端架构的实施...

    年中,自己做规划(2019Thinking(上) – 一个前端开发者的个人思考)时,考量了一段时间「微前端」,也关注到了《微前端的那些事儿》的文章,从而了解了作者「黄峰达」,也就购买了下面将要聊的书《前端架构:从入门到微前端》

    本书围绕前端架构的实施,从基础的架构规范,到如何设计前端架构,再到采用微前端架构拆分复杂的前端应用。

    • 设计:架构设计的模式,以及设计和制定前端工作流
    • 基础:通过深入构建系统、单页面应用原理、前端知识体系等,来构建出完整的前端应用架构体系
    • 实施:通过与代码结构的方式,介绍如何在企业级应用中实施组件化架构、设计系统和前后端分离架构
    • 微前端:引入6种微前端的概念,以及如何划分、设计微前端应用,并展示了如何实现这6种微前端架构
    • 演进:提出更新、迁移、重构、重写、重新架构等架构演进方式,来帮助开发人员更好地设计演进式架构

    本书虽“厚重”,但是内容上并不复杂。比较适合初、中级的前端开发人员或者想了解前端的小伙伴。在此并不想呈现太多的书中内容摘要,而是想通过作者的一些表达来结合自身和自己团队来谈一下观点和想法,特别是在架构方面。

    为啥需要架构

    长期项目面临的主要挑战是团队的士气、能力的增长以及架构的演进;
    短期项目的主要挑战是技术实践与业务进度的冲突。

    就我而言,架构带来的直观收益是:减少了大量的重复开发工作以及一些复杂问题的场景化处理。我们可以专注到业务上来,而不必去处理那些复杂的数据流、事件交互等。对于前端而言,业务性和交互越来越重,架构的重要性不言而喻。页面整体渲染 => 结构行为表现分离 => 插件化/模块化 => MVC/MVVM => 组件化。整个发展历程,都是在尽可能的保证职责单一性,来达到复用更高、维护更便捷。

    一个老生常谈的话题,前端日新月异,我们如何选择前端框架呢?业务+团队能力+浏览器支持范围+框架星数+社区活跃度+未来切换成本。选择了一个框架,代表接收了一种开发理念和思想,这个至关重要,一定要和自己团队的调调契合。与此同时,选择了一个框架,也不能一味的只用该框架。对于不同的项目,架构和选型,不能一概而论。接收变化、迎接变化、主动变化才能更好的发展。

    “大而全还是小而美”,没有标准答案。不要想着一个框架可以满足所有;也不要手里拿个锤子,看啥都是钉子。没有一种架构能满足未来的所有需求。我们要「因地制宜」,一些场景下,jQuery/Bootstrap 依然具有很大的用武之地。对于开发人员来说,要永远坚信:实践出真知

    架构需要些啥

    架构需要发展、需要迭代! 好的架构:20%的计划式设计,80%的演进式设计(只凭一系列的架构蓝图,没有相应的实施规范和原则,便无法按我们预期的方式来实施)。

    《Linux/Unix 设计思想》中提及了这样一段:

    1. 在背水一战的情况下,设计了第一个系统
    2. 专家们在第一个系统的基础上,做出来伟大而臃肿的第二个系统
    3. 受累于第二个系统的人,设计出了第三个系统

    所以,关于架构的重要决定 – 要延迟决策(在条件充分的时候再做决策),而不是直接拍脑袋。花费大量的时间盲目地修改架构,那样只会造成资源的浪费。

    • 不多也不少:不做多余的设计,也不缺少关键的部分
    • 演进式:不断地演进以使架构适应当前的环境
    • 持续性:长期的架构改进比什么都重要

    架构的产生不是一蹴而就,需要过程:架构设计 => 概念验证 PoC(Proof of Concept)=> 迭代0,搭建系统的基础设施。

    我们做了哪些

    整个公司前端团队20多人,自己团队(平台前端)人数10人左右。两年间、我们经历了大大小小近50个项目。项目的相似度很高,更多的时间大家都在写页面、改bug,每周奔波于多个项目之间。除了劳累,其他收获微乎其微。 因此,对于我们的挑战:

    1. 和业务关系不大、相同部分如何抽离+维护?
    2. 业务相关的内容,相同部分如何抽离+维护?

    业务关系不大

    首当其冲,组件库啊!!!但是组件库的可扩展性、维护成了拦路虎。同时,我们划分不同的前端边界(和业务关系不大)不是一件容易的事。

    罗列一下大致内容(看似简单,过程艰辛漫长):

    • 第一阶段:从项目中抽离了组件库和图表库(两个独立工程、项目中通过 git subtree引用)
    • 第二阶段:对 charts、components 按照组件思路进行改造(merge + extend + template)
    • 第三阶段:建立 Demo 站,为 charts、components 提供开发和展示环境(无特殊诉求无需查看源码)
    • 第四阶段:抽离 charts、components 共同的 utils(独立仓库 git subtree 引用)
    • 第五阶段:通过 yarn workspace 来处理公共依赖(关键点)
    • 第六阶段:解决 charts、components、utils 多仓提交的问题(monorepo)

    有了上述组件库的基础上,衍生了可视化大屏生成器。对于我们而言,组件+模式库仍然是一个长期积累过程:风格指南(Style Guide) => UI库 => 设计系统。总之,实现业务是我们的首要任务。技术的发展源于业务;反之也会更好的推动业务发展。业务着眼的是今天或明天,技术放眼未来;商业模式无壁垒,技术才是王道;技术会推动行业变革。

    业务相关内容

    微前端?目前预演中,对于目前我们思考的点:

    • 业务边界如何划分?
    • 应用的标识化或者注册中心的方式如何考量?
    • 应用通信机制:嵌入业务的特定通信机制 或 剥离业务的通用通信机制?
    • 数据共享机制,两部分:状态 和 应用数据?
    • 应用生命周期如何管理?

    综述,人为了逃避真正的思考,愿意做任何事。 最小MVP行动起来才是王道。没有脚踏实地,又哪里来的志存高远。杜绝纸牌屋心理(它可以工作,可我不知道为什么,所以谁也别碰它)。

    展开全文
  • 前端架构 从入门到微前端I am starting a series of articles on architecture of projects, especially Front-End. The posts will have an emphasis on explaining everything “in English”, without so much ...

    前端架构 从入门到微前端

    I am starting a series of articles on architecture of projects, especially Front-End. The posts will have an emphasis on explaining everything “in English”, without so much code. Perhaps, in another moment, the practical part will come up in a series of videos. I will post the texts based on a list of several subjects, from folders and files to versioning, continuous integration and DevOps, not necessarily in that order — and, in the end, I will get everything together in an ordered list. For now, I decided to start with Tests. Leave your suggestions in the comments. :)

    我开始撰写有关项目体系结构的系列文章,尤其是Front-End 。 这些帖子将重点说明没有太多代码的所有“英语”内容。 也许再过一会,实用的部分将出现在一系列视频中。 我将根据几个主题的列表发布文本,从文件夹和文件到版本控制,持续集成和DevOps,而不必按此顺序进行-最后,我将所有内容整理在一个有序列表中。 现在,我决定从Tests开始。 将您的建议留在评论中。 :)

    Before starting, it is important to remember the existence of a universe of Formatters and Linters, but I prefer to leave them for an article on standards, where we can talk about the choices that are the reason for which linters exists: reinforce patterns, either by convention, security or whatever technical reasons.

    在开始之前,重要的是要记住存在FormattersLinters的世界,但是我更喜欢将它们留在一篇有关标准的文章中,在这里我们可以讨论构成linters的原因的选择:加强模式,或者根据惯例,安全性或任何技术原因。

    We will talk about:

    我们将谈论:

    • Unit

      单元
    • Integration

      积分
    • End-to-end

      端到端
    • Regression

      回归

    Each of these will be structured with:

    每一个都将具有以下结构:

    • What it is

      这是什么
    • When to use it

      什么时候使用
    • Pros

      优点
    • Cons

      缺点
    • Tools

      工具类
    Image for post

    单元(Unit)

    这是什么(What it is)

    As the name says, it refers to the units, and, as the word suggest, it means that it is something that cannot be divided, since it is the smallest possible part. When referring to software, it means that they are functions that only do one thing. Unit tests are responsible for attesting that such functions (or units) are behaving properly. As we are talking about Front-End, these functions are written in Javascript or any other language that compiles to it.

    顾名思义,它指的是单位,而顾名思义,则表示它是不可分割的,因为它是最小的部分。 当提到软件时,这意味着它们是只能做一件事的功能。 单元测试负责证明此类功能(或单元)的行为正常。 当我们谈论前端时,这些函数是用Javascript或编译成它的任何其他语言编写的。

    Whether using the TDD process or not, it is difficult for a developer to take into account all possible scenarios, especially when programming such functions. Writing unit tests can help you to prepare your code for situations that are not “optimal”. In addition, they can make sure that during the life of the project, the “little guys” (unit tests) will complain before you notice such errors, in case something goes out of the established format or architecture,. By writing them, you are creating an army of robots with a life of their own, whose only mission is to observe their functions and ensure that they are correct.

    无论是否使用TDD流程,开发人员都难以考虑所有可能的情况,尤其是在对此类功能进行编程时。 编写单元测试可以帮助您为非“最佳”情况准备代码。 此外,他们可以确保在项目生命周期中,“小家伙”(单元测试)会在您发现此类错误之前进行投诉,以防万一某些内容超出了既定的格式或体系结构。 通过编写它们,您将创建一支拥有自己生命的机器人大军,其唯一任务是观察其功能并确保其正确。

    An example, in the case of a function that formats dates, would be to guarantee the outputs, for practically all types of input — which happens when someone uses a date in different formats, invalid dates, and so on, including how the function handles errors and exceptions.

    例如,对于格式化日期的函数,将保证几乎所有类型的输入的输出-当某人使用不同格式的日期,无效日期等(包括该函数如何处理)时会发生这种情况错误和异常。

    什么时候使用 (When to use it)

    • The project has a considerable amount of logic

      该项目具有大量逻辑
    • There are many functions that are reused in many places

      有很多功能可以在许多地方重用
    • You have a business rule or a code that is crucial to the success of how the business flow goes

      您拥有对于成功实现业务流程至关重要的业务规则或代码
    • It is a product or project with a long life

      它是使用寿命长的产品或项目
    • It is an open-source project with contributors

      这是一个有贡献者的开源项目

    Note: How can you tell when it’s a logic code or not? Logic, most of the time, is pure Javascript — that is, if you are accessing the DOM, changing classes or animating, this is already the consequence of logic, or, in other words, it is a side effect of a decision. Usually, logical functions are composed of conditionals (if-else, switch) and loops.

    注意:您怎么知道什么时候是逻辑代码? 逻辑在大多数情况下都是纯Javascript,也就是说,如果您访问DOM,更改类或设置动画,这已经是逻辑的结果,或者换句话说,这是决策的副作用。 通常,逻辑功能由条件(if-else,switch)和循环组成。

    优点 (Pros)

    • Bugs are found faster

      发现错误的速度更快

    • Run-time errors are treated preventively

      运行时错误得到预防

    • More confidence in deploys

      部署更有信心

    • It makes it easier the use of refactor (rewriting functions while keeping the same inputs and outputs)

      它使重构的使用更加容易(重写函数,同时保持相同的输入和输出)

    缺点 (Cons)

    • More time spent in developing

      开发上花费了更多时间
    • More time spent with the project

      在项目上花费更多的时间
    • It is difficult to rewrite. Unlike the refactor, if a function or module has been poorly designed and needs to be redone, the test will need to be rewritten as well

      很难重写。 与重构不同,如果功能或模块的设计不良,并且需要重做,则测试也需要重写

    工具类(Tools)

    覆盖范围(Coverage)

    This is a controversial point. When using unit tests as a synonym for more stability and security, it is very common to compromise or require some “coverage”, usually measured in percentage. At first, the more of your Javascript files, functions, lines, conditions — in short, the more operation is covered by tests, the better. But there is “too much testing”. A happy medium would be to manually choose critical files, with a business rule or logic, and measure their coverage, instead of doing that with all files.

    这是一个有争议的观点。 当使用单元测试作为更多稳定性和安全性的代名词时,折衷或要求一定的“覆盖率”是很常见的,通常以百分比来衡量。 首先,您的Javascript文件,函数,行,条件越多—简而言之,测试覆盖的操作越多,效果越好。 但是有“太多的测试”。 一个不错的方法是手动选择具有业务规则或逻辑的关键文件,并衡量其覆盖范围,而不是对所有文件都这样做。

    积分(Integration)

    它是什么(What is it)

    There are a lot of gifs on the internet exemplifying the difference between unit and integration tests. It basically means testing units together. While in unit tests it is often necessary to mock (simulate data locally, removing the need for external integrations) parameters, data and dependencies, in the integration test the “real units” are used as much as possible.

    互联网上有很多gif图像,说明了单元测试和集成测试之间的区别。 从根本上讲,这意味着一起测试单元。 在单元测试中,通常需要模拟(本地模拟数据,无需外部集成)参数,数据和相关性,而在集成测试中,尽可能使用“真实单元”。

    Image for post
    Image for post

    Here’s an example, in the case of dates. You would probably have at least one function to format dates and another to format time (hours of the day). And here’s the question: would a simple integration test be sufficient to verify what would happen, for example, if the date and time formats are different — even if the date and time formatting works in isolation? Will the output be the date in the format of a specific country and will the time be in the format of another one — or is that an exception?

    这是一个有关日期的示例。 您可能至少具有一个用于格式化日期的函数,以及另一个用于格式化时间(一天中的小时)的函数。 问题是:简单的集成测试是否足以验证发生的事情,例如,日期和时间格式是否不同-即使日期和时间格式是单独工作的? 输出将是特定国家/地区格式的日期,还是时间将是另一个国家/地区的格式-还是例外?

    什么时候使用 (When to use it)

    The word “integration” in this context means a lot. Basically, these tests aim to answer the question that still remains: how do two units tested together work together? However, in this case, unity can have several meanings:

    在本文中,“整合”一词意义重大。 基本上,这些测试旨在回答仍然存在的问题:两个测试单元如何一起工作? 但是,在这种情况下,统一可以具有多种含义:

    • To test two or more functions, when one is used by the other and the unit test was solved by the mock

      为了测试两个或多个函数,当一个函数被另一个函数使用并且单元测试由模拟解决时

    • To test functions or modules that use external dependencies (like NPM packages) and the unit test was solved by mock

      测试使用外部依赖项的功能或模块(例如NPM软件包),并通过模拟解决了单元测试

    • To connect APIs or external services to tests that were previously mocked

      API或外部服务连接到先前模拟的测试

    • On microservice architectures, to test functions or modules from different repositories that work together

      微服务架构上,测试可一起工作的不同存储库中的功能或模块

    优点(Pros)

    • It provides you even more security in the application, mainly as a validation before deploying

      它为您提供了更多的应用程序安全性,主要是作为部署之前的验证
    • It quickly warns you of any failures as a result of a refactor, either from your own code or from the others, which otherwise might only be caught in production

      它会Swift警告您因重构而导致的任何失败,无论是您自己的代码还是其他代码,否则可能只会在生产中出现

    缺点(Cons)

    • Depending on the stack and the architecture of the project, it might take some considerable setup time, specially when provisioning instances in the cloud, including setup and teardown services

      根据项目的堆栈和体系结构,可能会花费一些可观的设置时间,尤其是在云中设置实例(包括设置和拆卸服务)时
    • It can be slow, increasing the build time considerably

      它可能很慢,大大增加了构建时间

    工具类(Tools)

    The same as for unit tests, but depending on the architecture of the project you may need to run a browser to access some specific functionalities.

    与单元测试相同,但是根据项目的体系结构,您可能需要运行浏览器才能访问某些特定功能。

    端到端 (End-to-end)

    它是什么(What is it)

    It is what the name says: “from end to end”. We are talking about “applications”, which have data, logic and interface, so “end-to-end” tests must encompass all three. They are focused on the interface as a way to automatically test behaviors, interactions and flows, whether they contain data and logic or not.

    顾名思义,它是“从头到尾”。 我们谈论的是具有数据,逻辑和接口的“应用程序”,因此“端到端”测试必须包含所有这三个。 它们专注于界面,可以自动测试行为,交互和流,无论它们是否包含数据和逻辑。

    An example: through this option, it would be to possible to automate an interface test in which the user accesses a calendar and chooses dates, and in another column he/she would be able to choose the hours of the day, attesting that the correct options are shown, that the success and error messages appear and so on.

    一个示例:通过该选项,可以自动化界面测试,使用户可以访问日历并选择日期,在另一列中,他/她将可以选择一天中的小时,以证明正确显示选项,显示成功和错误消息,依此类推。

    什么时候使用 (When to use it)

    Whenever you and your team find yourselves performing the same interface test dozens of times and there is time to schedule automated tests. The most important question that defines whether this is the case or not is: how long will these tests continue to be done, or how long will this project take? If the answer is at least a few months, it is certainly the case.

    每当您和您的团队发现自己执行相同的接口测试数十次时,就有时间安排自动测试。 定义是否是这种情况的最重要的问题是:这些测试将继续执行多长时间,或者该项目需要多长时间? 如果答案至少是几个月,那就一定是这样。

    优点 (Pros)

    • It shortens considerably the time you spend doing manual tests

      它大大缩短了您进行手动测试的时间
    • If configured correctly, it makes it easier to find cross-browser divergences

      如果配置正确,则可以更轻松地发现跨浏览器的差异

    缺点(Cons)

    • It demands considerable time to schedule tests

      安排测试需要大量时间
    • Drivers, browsers headless and different browsers have an unstable behavior when it comes to automated tests, leading to many exceptions that must be skipped and retested manually

      驱动程序,无头浏览器和其他浏览器在进行自动测试时会出现不稳定的行为,从而导致许多异常必须手动跳过并重新测试

    工具类(Tools)

    回归(Regression)

    它是什么(What is it)

    All integration and end-to-end (unit) tests have much more value when monitored over time. It is possible to configure them to use a log that clearly shows what has been successful or failed. If you are on a well-structured project, it is possible that there are dedicated QA professionals — and, in this case, they are probably doing exploratory manual tests as well, and writing down the test results over time.

    随着时间的推移,所有集成和端到端(单元)测试的价值都将大大提高。 可以将它们配置为使用清楚显示成功或失败内容的日志。 如果您是一个结构良好的项目,则可能有专门的QA专业人员-在这种情况下,他们可能也在进行探索性的手动测试,并随着时间的推移写下测试结果。

    While the uses mentioned above focus primarily on the layer of data and the logic of an application, there is another use, perhaps one of the most useful for large-scale projects. For example, to observe automatically the interface differences during the lifetime of a product or project, using past references. This is extremely useful in a project with hundreds or thousands of pages, since it would take several days or weeks to certify that everything is okay if you check it manually. So it is valid to use regression testing.

    尽管上述用途主要集中在数据层和应用程序逻辑上,但还有另一种用途,也许是对大型项目最有用的用途。 例如,使用过去的引用自动观察产品或项目生命周期中的界面差异。 这在具有成百上千个页面的项目中非常有用,因为如果您手动检查所有内容,则需要几天或几周的时间来证明一切正常。 因此,使用回归测试是有效的。

    什么时候使用 (When to use it)

    In complex software where there is a well-used design system, that is, a component system with some consistent design rules. In such systems, it is possible to infer through automated scripts that changes that are poorly made in design are likely to be a break in the design system. In addition, it is possible to have too many pages to remember, especially when considering all multiple releases and timelines.

    在具有良好使用的设计系统的复杂软件中,即具有一些一致设计规则的组件系统。 在这样的系统中,有可能通过自动脚本推断出设计不善的更改很可能会破坏设计系统。 此外,可能有太多页面需要记住,尤其是在考虑所有多个发行版和时间表时。

    优点 (Pros)

    • It can help you to ensure that new releases conform to the previous ones that were successful.

      它可以帮助您确保新版本符合以前成功的版本。

    缺点 (Cons)

    • It requires end-to-end testing to be effective.

      它要求端到端测试有效。
    • It requires considerable setup time.

      这需要大量的设置时间。
    • Depending on your compatibility matrix, it may not remove the need for excessive manual testing.

      根据您的兼容性矩阵,它可能不会消除对过多手动测试的需求。
    • There is no perfect solution yet, since it’s problematic to deal with responsiveness, threshold proportionality and screenshots of all possible interactions.

      目前还没有完美的解决方案,因为处理响应性,阈值比例和所有可能的交互的屏幕截图是有问题的。

    工具类 (Tools)

    Note: In addition to the tests mentioned above, there are also specific test tools for you to use with a framework, such as Protractor from Angular and Enzyme for React.

    注意:除了上述测试外,还有一些特定的测试工具可用于框架,例如Angular的Protractor和React的Enzyme。

    Tests are a whole different world and there are many new challenges. It is a very old and popular subject in software development, mainly in the Back-End, but it is recent in the Front-End debate, especially in Brazil. More and more companies request this knowledge, even though it is still very rare! Thus, it is a good way for you to stand out in the job market.

    品鉴是一个完全不同的世界,并且存在许多新的挑战。 它是软件开发中非常古老且流行的主题,主要是在后端,但是在前端辩论中却是最近的,尤其是在巴西。 尽管仍然很少,但是越来越多的公司要求获得这种知识! 因此,这是您在就业市场上脱颖而出的好方法。

    If you are interested and don’t know where to start, send me a message on Linkedin, I will be happy to help you with content references.

    如果您有兴趣并且不知道从哪里开始,请在Linkedin上给我发送消息,我将很乐意为您提供内容参考。

    Image for post
    The Gods of Olympus, trompe l’oeil ceiling from the Sala dei Giganti, 1528 (fresco) by Romano, Giulio (1492–1546)
    奥林匹斯众神(The Gods of Olympus),从萨拉·德·吉甘蒂(Sala dei Giganti)的错视画天花板,1528年(壁画),朱利奥·罗曼诺(1492-1546)

    翻译自: https://medium.com/swlh/front-end-architecture-tests-edad10f4a8a4

    前端架构 从入门到微前端

    展开全文
  • 前端架构 从入门到微前端 微型前端的机会 (Opportunities of Micro Frontends) Micro Frontend is not a technical thing in the first place Micro Frontend首先不是技术性的东西 From my point of view, Micro ...

    前端架构从入门到微前端

    微型前端的机会 (Opportunities of Micro Frontends)

    Micro Frontend is not a technical thing in the first place

    Micro Frontend首先不是技术性的东西

    From my point of view, Micro Frontend is not a technical thing in the first place. The main benefit of Micro Frontend is the ability to organize small teams around software modules with end-to-end character. In the best case, these modules are aligned with bounded contexts.

    在我看来,Micro Frontend首先不是技术性的东西。 Micro Frontend的主要优点是能够围绕具有端到端特征的软件模块组织小型团队。 在最佳情况下,这些模块与有限的上下文对齐。

    In their article about Microservices Martin Fowler and James Lewis stated, that “there is a natural correlation between service and context boundaries”. The notion of bounded contexts originates from Domain Driven Design (DDD). The strategic design of DDD helps dividing a system into smaller less dependent pieces along a real world process. Those pieces are called bounded contexts and according to the statement above, they have a natural correlation with Microservices.

    Martin Fowler和James Lewis在有关微服务的文章中说,“ 服务和上下文边界之间存在自然的联系 ”。 有界上下文的概念起源于域驱动设计(DDD)。 DDD的战略设计有助于在现实世界中将系统划分为较小的,较少依赖的部分。 这些片段称为有界上下文,根据上面的陈述,它们与微服务具有自然的关联。

    Focussing the modularisation aspect, the only difference between Microservices and Micro Frontend is that the latter includes the frontend. Not including the frontend makes it harder to establish teams with end-to-end responsibility and it often leads to a new monolith in the frontend.

    着眼于模块化方面,微服务和微前端之间的唯一区别是后者包括前端。 不包括前端将使建立具有端到端责任的团队变得更加困难,并且通常会导致前端出现新的局面。

    Teams with end-to-end responsibility are closer to the customer needs, which enables them to fulfill them directly. Micro Frontends aligned with bounded contexts increase the team independency. Those two factors combined enable the teams to build products without losing productivity and the focus of the customer in enterprise organisations and hierarchies.

    具有端到端责任的团队更贴近客户需求,这使他们能够直接满足他们的需求。 Micro Frontends与有限的上下文保持一致,可以提高团队的独立性。 这两个因素相结合,使团队能够构建产品而又不损失生产力以及客户对企业组织和层次结构的关注。

    In my opinion this aspect is the main advantage of Micro Frontends and having that said, I’ll shift the focus to the technical part of this article.

    我认为这是Micro Frontends的主要优势,因此,我将把重点转移到本文的技术部分。

    今天的微型前端联合会 (Micro Frontend federation today)

    A little more than two years ago, we started to see the advantages of Micro Frontends in our business context. At the beginning, we played around building small products out of different Micro Frontends. Our first integration approach was using i-frames, but in our context it felt cumbersome and we especially hit its border, when we integrated multiple Micro Frontends on a single page, where each one was required to get an oauth2 access token using an active login session (oauth2 recommends to not allow the login page loaded within an i-frame). Of course, there would have been options to solve that problem (for example using the oauth2 auth code flow with pkce to handover long living tokens into the i-frames), but we already hit an eye on the new Web Component standard by that time, which addresses the integration purpose more intuitively.

    大约两年前,我们开始在我们的业务环境中看到Micro Frontends的优势。 最初,我们围绕着使用不同的Micro Frontends来构建小型产品的过程进行了研究。 我们的第一个集成方法是使用i-frame,但是在我们的上下文中,这感觉很麻烦,而且特别是在将多个Micro Frontends集成到单个页面上时遇到了麻烦,在每个页面上,每个人都需要使用活动登录名来获取oauth2访问令牌会话( oauth2建议不允许在i框架内加载登录页面 )。 当然,可以选择解决该问题的方法(例如,使用带有pkce的oauth2 auth代码流将长期有效的令牌移交给i框架),但是那时我们已经着眼于新的Web组件标准,可以更直观地解决集成目的。

    In the beginning, we built Web Components in different ways. We exported Vue.js components as Web Components or used less comprehensive frameworks such as stencil.js or polymer. Today, we are mainly building Web Components using lit-element with typescript and a custom Webpack configuration.

    在开始时,我们以不同的方式构建Web组件。 我们将Vue.js组件导出为Web组件,或者使用了不太全面的框架,如stencil.js或polymer。 今天,我们主要使用带有打字稿和自定义Webpack配置的lit-element构建Web组件。

    In our real world application, we are already integrating quite a lot of Micro Frontends from different domains. Although integrating Web Components is our preferred approach, practice taught us to be more flexible and allow whatever fits best for the teams integrating their frontends.

    在我们的实际应用程序中,我们已经集成了许多来自不同领域的Micro Frontends。 尽管集成Web组件是我们的首选方法,但是实践告诉我们要更加灵活,并允许最适合团队集成其前端的方法。

    The fact, that there is no Web Component UI library implementing our corporate identity/design or at least a considerably amount of material design Web Components, is actually the reason for many teams to still avoid Web Components. For them it is easier to use a <you-name-it> single page application framework, for which such a UI component library exists. However, the disadvantage of this approach is, that the team is losing the possibility to integrate as Web Component. Have you tried to integrate a complex Vue component with a React application? Even though you may be able to convert the component into a Web Component, it doesn’t feel right. This is what I mean with “losing the possibility to integrate as Web Component”. (Btw. from my point of view, the most promising project to solve the lack of material-design Web Components is: material-components-web-components at the moment)

    事实上,没有Web组件UI库实现我们的公司标识/设计,或者至少有大量的材料设计Web组件,这实际上是许多团队仍然避免使用Web组件的原因。 对于他们来说,使用<you-name-it>单页应用程序框架会更容易,对于该框架,存在这样的UI组件库。 但是,这种方法的缺点是团队失去了作为Web组件进行集成的可能性。 您是否尝试过将复杂的Vue组件与React应用程序集成在一起? 即使您可以将组件转换为Web组件,也感觉不合适。 这就是我“失去作为Web组件集成的可能性”的意思。 (顺便说一句,以我的观点,解决材料设计Web组件缺乏的最有前途的项目是:目前, material-components-web-components )

    Our container application integrating all those frontends is built with Vue.js and therefore we have Micro Frontends integrating as Vue component libraries, i-frames, Web Components and by adding a link (if such a lightweight approach is applicable).

    我们的容器应用程序集成了所有这些前端,是使用Vue.js构建的,因此,我们可以将Micro Frontends集成为Vue组件库,i-frame,Web组件并通过添加链接(如果适用这种轻量级方法)。

    As Web Components are evolving from day to day, I think that its proportion will steadily increase.

    随着Web组件的日新月异,我认为其比例将稳步增长。

    Focussing on Web Components the integration scenario is quite intuitive, but there are still deficits to overcome. One important example is the handling of dependencies. Imagine, that there is an application container A and a Micro Frontend Web Component B that is going to be integrated with A. Furthermore, there is another Web Component C used by A and B. To be more specific, let’s say that C is a simple button component, B is a Web Component that loads images frequently and allows to like them using the button C. A could be a Vue.js application that uses C as a login button and integrates B to ask users for likes about images. When integrating A with B, there are challenges regarding C. In case A and B are using the same version of C, it should only be loaded once. Related to that, it must be ensured, that the custom-element of C is only defined once. In case different versions of C are used, possible version conflicts must be avoided. If A stops using C, it shouldn’t affect B on runtime.

    专注于Web组件,集成方案非常直观,但是仍然有很多不足之处需要克服。 一个重要的例子是依赖关系的处理。 想象一下,有一个应用程序容器A和一个Micro Frontend Web组件B将与A集成在一起。 此外, AB使用了另一个Web组件C。 更具体地说,假设C是一个简单的按钮组件, B是一个Web组件,它经常加载图像并允许使用按钮C来喜欢它们。 A可能是一个Vue.js应用程序,它使用C作为登录按钮,并集成了B以询问用户对图像的喜欢。 将AB集成时,会遇到C方面的挑战。 如果AB使用的是相同版本的C ,则只能加载一次。 与此相关的是,必须确保C自定义元素仅定义一次。 如果使用不同版本的C,则必须避免可能的版本冲突。 如果A停止使用C ,那么它将不会在运行时影响B。

    Today, those challenges might be tackled with Webpack externals or similar approaches, which are quite opaque, especially when it comes to huge integration scenarios with complex dependency trees.

    如今,这些挑战可以通过Webpack外部组件或类似方法来解决,这些方法相当不透明,尤其是在涉及具有复杂依赖关系树的大型集成方案时。

    Fortunately, there are already solutions in development addressing this problem. Among others, Webpack 5 module federation is one of them.

    幸运的是,开发中已经有解决此问题的解决方案。 其中,Webpack 5模块联合就是其中之一。

    明天的微型前端联合会 (Micro Frontend federation tomorrow)

    using Webpack 5 module federation

    使用Webpack 5模块联合

    As Webpack 5 module federation is a promising candidate to solve Web Component integration deficits, this section describes how it could be used in a plain Web Component scenario in practice.

    由于Webpack 5模块联合会有望解决Web组件集成不足的问题,因此本节将介绍如何在实践中将其用于普通的Web组件场景。

    示例Web组件(远程) (Sample Web Component (the remote))

    To demonstrate its capabilities, I implemented a simple native Web Component (without lit-element, to keep it even more simple). The purpose of this sample Web Component is to load a new random picture from https://picsum.photos/. The update frequency in milliseconds and the length of the quadratic picture can be defined via the custom-element:

    为了演示其功能,我实现了一个简单的本机Web组件(不带元素),以使其更加简单。 此示例Web组件的目的是从https://picsum.photos/加载新的随机图片。 可以通过custom-element定义更新频率(以毫秒为单位)和二次画面的长度:

    <random-pic update-freq-ms="15000" image-length-px="300"></random-pic>

    Here is how it may look like:

    看起来是这样的:

    Image for post
    random-pic component rendered in the browser
    浏览器中呈现的随机图片组件

    to see the component in action, go to: https://josros.gitlab.io/random-pic-component/

    要查看运行中的组件,请访问: https : //josros.gitlab.io/random-pic-component/

    The goal is to provide the component as a “remote module“. “Remote modules are modules that are not part of the current build and loaded from a so-called container at the runtime”.

    目的是将组件提供为“远程模块”。 “ 远程模块是不属于当前版本的模块,而是在运行时从所谓的容器加载的模块 ”。

    To transform the sample component into a remote module, the following things are required to do:

    要将示例组件转换为远程模块,需要执行以下操作:

    // install Webpack 5 (beta version, v.20 is used in this example)npm i webpack@5.0.0-beta.20 -D

    Add a module federation configuration in the webpack.config.js file. The key part is:

    webpack.config.js文件中添加模块联合配置。 关键部分是:

    randomPic is the name of the module. The module exposes the sample component under the name ./component, which refers to the actual Web Component implementation.

    randomPic是模块的名称。 该模块以名称./component公开示例组件,该名称指的是实际的Web组件实现。

    Given the full webpack.config.js, executing a Webpack build

    给定完整的webpack.config.js ,执行Webpack构建

    webpack --mode production

    transpiles the component using babel and it creates a randomPicEntry.js file, used as an entrypoint to load the component from elsewhere, which will be demonstrated in the next section. (If you look at the actual webpack.config.js file, simply ignore the shared part for the moment.)

    使用babel编译组件,并创建一个randomPicEntry.js文件,用作从其他位置加载组件的入口点,这将在下一部分中进行演示。 (如果您查看实际的webpack.config.js文件,则暂时忽略共享部分。)

    Together with a demonstration page of the component, the sample component project deploys the files built with Webpack under gitlab pages using a simple gitlab-ci.yml file.

    与组件的演示页面一起,示例组件项目使用简单的gitlab-ci.yml文件在gitlab页面下部署使用Webpack构建的文件。

    In case you are interested in a way to configure this example with typescript, have a look at: https://gitlab.com/josros/random-pic-component-ts

    如果您对使用打字稿配置此示例的方法感兴趣,请查看: https : //gitlab.com/josros/random-pic-component-ts

    组件集成(主机) (Component integration (the host))

    The counterpart of the remote is a simple Webpack project, that integrates the random-pic component using module federation. I’ll refer to this component as “the host” subsequently.

    遥控器的对应项是一个简单的Webpack项目,该项目使用模块联合集成了随机图片组件。 随后,我将该组件称为“主机”。

    The following things are required to load the remote in our host project:

    要在我们的宿主项目中加载遥控器,需要执行以下操作:

    First, the host project also needs to use Webpack 5:

    首先,宿主项目还需要使用Webpack 5:

    // install Webpack 5 (beta version, v.20 is used in this example)npm i webpack@5.0.0-beta.20 -D

    In its index.html file it needs to import the remotes entry point script:

    在其index.html文件中,需要导入远程入口点脚本:

    <script src="https://josros.gitlab.io/random-pic-component/randomPicEntry.js"></script>

    and before the custom-element of the remote can be used, the host needs to import the remote using a dynamic import function, which loads the component asynchronously:

    并且在可以使用遥控器的自定义元素之前,主机需要使用动态导入功能来导入遥控器,该功能会异步加载组件:

    after the module is loaded, the custom-element is created and appended to the DOM.

    加载模块后,将创建自定义元素并将其附加到DOM。

    To tell Webpack how to resolve the remote module (randomPic/component) the webpack.config.js file also needs some additional information within the host project:

    为了告诉Webpack如何解析远程模块( randomPic / component ), webpack.config.js文件还需要宿主项目中的一些其他信息:

    The name of the module in this project is integration and the configuration for remotes tells Webpack to resolve randomPic as remote module.

    该项目中模块的名称是Integration,并且远程控制器的配置告诉Webpack将randomPic解析为远程模块。

    All other parts are not different from a standard configuration in Webpack < 5. The full webpack.config.js file defines that ./src/index.js transpiles to a main.js file using the babel-loader, which I refer to in the index.html file:

    所有其他部分与Webpack <5中的标准配置没有什么不同。完整的webpack.config.js文件定义了使用babel-loader将./src/index.js转换为main.js文件的过程,我在中提到了这一点。 index.html文件:

    <script type=”module” src=”main.js”></script>

    If you go to: https://josros.gitlab.io/random-pic-component-integration/ you will see the remote component rendered as part of the host project, where the component is loaded using Webpack 5 module federation.

    如果您转到: https ://josros.gitlab.io/random-pic-component-integration/,您将看到作为主机项目一部分呈现的远程组件,该主机项目是使用Webpack 5模块联合加载的。

    Now that we have seen a basic integration scenario using Webpack 5 module federation, the next section will show how module federation handles shared modules.

    现在,我们已经看到了使用Webpack 5模块联合的基本集成方案,下一节将展示模块联合如何处理共享模块。

    共享模块 (Shared modules)

    As you might have noticed, there is a like button above the image in the remote component. The same kind of button you can find in the host project (like app).

    您可能已经注意到, 远程组件中图像上方有一个“ 喜欢”按钮。 您可以在宿主项目 ( 如app )中找到相同类型的按钮。

    Image for post
    mwc-button as part of host an remote component
    mwc-button作为主机的一部分,是远程组件

    The button is part of the material-components-web-components project and it is used as a dependency in our remote component as well as in the host project:

    该按钮是material-components-web-components项目的一部分,并且在我们的远程组件和宿主项目中用作依赖项:

    As we don’t want the dependency to be loaded multiple times, we instruct Webpack 5 to resolve the dependency for us.

    因为我们不想多次加载依赖项,所以我们指示Webpack 5为我们解决依赖项。

    To achieve that, the remote component project webpack.config.js file needs to define the mwc-button as shared module, adjusting the ModuleFederationPlugin config as follows:

    为此,远程组件项目webpack.config.js文件需要将mwc-button定义为共享模块,如下调整ModuleFederationPlugin配置:

    Compared to the version shown earlier, a shared object has been added here. The definition tells Webpack, that the mwc-button can be shared across modules. However, it requires a specific version, which in this case is the one defined in the package.json file. For more information about how to configure shared objects, you may want to read this article.

    与之前显示的版本相比,此处添加了共享库 。 该定义告诉Webpack, mwc按钮可以在模块之间共享。 但是,它需要一个特定的版本,在这种情况下,它是package.json文件中定义的版本。 有关如何配置共享对象的更多信息,你可能需要阅读文章。

    The mwc-button must be defined as shared module in the host project as well. Here is how ModuleFederationPlugin config is adjusted there:

    mwc按钮也必须在宿主项目中定义为共享模块。 这里是如何在此处调整ModuleFederationPlugin配置的方法:

    Running the host locally, we can see what is happening during the page load:

    在本地运行主机,我们可以看到页面加载期间发生了什么:

    Image for post

    localhost:3013 is where the host runs. index.html is loaded first. Next is the randomPicEntry.js file from our remote component on localhost:3003. Afterwards the main.js file is loaded, which is basically the host application bundle. From there, the mwc-button is resolved. It comes from localhost:3013, because it is used in both parts.

    主机在其中运行localhost:3013index.html首先被加载。 接下来是localhost:3003上来自远程组件的randomPicEntry.js文件 之后,将加载main.js文件,该文件基本上是主机应用程序捆绑包。 从那里,解决了mwc按钮 。 它来自localhost:3013,因为这两个部分都使用了它。

    axios, is not a shared module and it is only used as dependency within the remote component, that is why it is loaded from there. Finally the remote component bundle is retrieved from localhost:3003.

    axios不是一个共享模块,它仅用作远程组件中的依赖项,因此它是从那里加载的。 最后,从localhost:3003检索远程组件包。

    The key part is, that the mwc-button is only loaded once, even though it is used in the remote component as well as in the host project.

    关键部分是,即使在远程组件以及宿主项目中使用了mwc按钮 ,该按钮也只能加载一次。

    摘要 (Summary)

    At the moment of writing this, Webpack 5 is still in beta, but as this article tries to show, it has the potential to overcome some deficits, that currently exist with Micro Frontend integration.

    在撰写本文时,Webpack 5仍处于测试阶段,但正如本文试图显示的那样,它具有克服Micro Frontend集成当前存在的一些缺陷的潜力。

    Besides the benefit, that Webpack 5 module federation provides a scaleable solution of integrating application code at runtime, it tackles the challenge of sharing dependencies in a flexible way. If a dependency is used within multiple modules of a federated application, it automatically uses the highest available package. Doing that, it considers numerous restrictions configurable for a shared dependency. As a fallback, it takes the dependency provided by the remote module itself. Because conditions may change at runtime, this is particularly helpful.

    除了好处之外,Webpack 5模块联合还提供了在运行时集成应用程序代码的可伸缩解决方案,它以灵活的方式解决了共享依赖项的挑战。 如果在联合应用程序的多个模块中使用了依赖项,它将自动使用最高可用包 。 这样做,它认为可以为共享依赖项配置许多限制。 作为后备,它采用了远程模块本身提供的依赖性。 由于条件可能会在运行时发生变化,因此这特别有用。

    Building a portal for multiple domains and also integrating legacy applications, Webpack 5 module federation will not help us with all of our integration scenarios. Where i-frames were chosen for good reasons, their integration specific problems will still remain. But for not less than our preferred integration approach of native Web Components, Webpack 5 promises to be an evolution.

    Webpack 5模块联合会构建用于多个域的门户并集成遗留应用程序,将无法帮助我们解决所有集成问题。 如果有充分的理由选择i框架,它们的集成特定问题仍然存在。 但是对于不少于我们首选的本机Web组件集成方法,Webpack 5有望发展。

    Taking one step back, to be successful with Micro Frontends or even software development in general, it is not sufficient to chose the right tool. More than that, it is important to align teams with context boundaries and to give them end-to-end responsibilities. The latter enables them to measure and fulfill customer needs directly, instead of getting caught on technical daydreams. Still I am convinced that viewing teams as strategical instead of delivery units, is much more important than having the best technology in place. For this reason, the main benefit of Micro Frontend is, that it supports that goal directly.

    退一步,要想成功使用Micro Frontends或什至是一般的软件开发,仅仅选择正确的工具是不够的。 除此之外,使团队与上下文边界保持一致并赋予他们端到端的责任非常重要。 后者使他们能够直接衡量和满足客户需求,而不会陷入技术上的白日梦。 我仍然坚信,将团队视为战略团队而不是交付团队,比拥有最佳技术要重要得多。 因此,Micro Frontend的主要优点在于,它直接支持该目标。

    翻译自: https://medium.com/@jh.rossa/micro-frontend-federation-today-and-tomorrow-4eda3ab69409

    前端架构从入门到微前端

    展开全文
  • 《前端架构:从入门到微前端》子系统 购买链接: 京东:《尖端》 目录 ├── chapter04 │ ├── angular-examples │ ├── docker-react │ ├── gulp-examples │ ├── gulp-grunt-webpack-compare │...
  • 考虑广大群友的需求,会推出的『前端架构:从入门到微前端』。相关情况如下:售价暂定99 元快递顺丰限中国内地京东官方的上架日期是 6.25,所以日期你懂的所以,有兴趣的可...
        

    考虑广大群友的需求,会推出的『前端架构:从入门到微前端』。相关情况如下:

    1. 售价暂定 99 元

    2. 快递顺丰

    3. 限中国内地

    4. 东官方的上架日期是 6.25,所以日期你懂的

    所以,有兴趣的可以:


    或者直接入群,哈哈


    640?wx_fmt=jpeg

    展开全文
  • 本书是一本围绕前端架构的实施手册,基础的架构规范,如何设计前端架构,再采用微前端架构拆分复杂的前端应用。本书通过系统地介绍前端架构世界的方方面面,来帮助前端工程师更...
  • 前端入门书籍已经很多了,《JavaScript 高级程序设计》《精通 CSS:高级 Web 标准解决方案》前端的框架书籍已经很多了,《深入浅出 Node.js》(...
  • 前端入门书籍已经很多了,《JavaScript 高级程序设计》《精通 CSS:高级 Web 标准解决方案》 前端的框架书籍已经很多了,《深入浅出 Node.js》(笑~)《JavaScript 框架设计》 所以,两年前当我想总结我...
  • 微前端入门:single-spaqiankun

    千次阅读 2020-09-27 17:33:58
    一、关于微前端 1.What?什么是微前端? 微前端就是将不同的功能按照不同的维度拆分成多个子应用。通过主应用来加载这些子应 用。 微前端的核心在于拆, 拆完后在合! 2.Why?为什么去使用他? 不同团队间开发同一个应用...
  • spa开发项目,然后打包部署上线刨析single-spa的源码原理手写一个自己的single-spa框架过程编写示例项目打包部署框架源码解读手写框架关于微前端的介绍这里就不再赘述了,网上有很多的文章,本文的重点在于刨析...
  • 手写框架 关于微前端的介绍这里就不再赘述了,网上有很多的文章,本文的重点在于刨析微前端框架single-spa的实现原理。 single-spa是一个很好的微前端基础框架,qiankun框架就是基于single-spa来实现的,在single-...
  • 来源:李永宁 ... 前序 目的 会使用single-spa开发项目,然后打包部署上线 ...关于微前端的介绍这里就不再赘述了,网上有很多的文章,本文的重点在于刨析微前端框架single-spa的实现原理。 single-...
  • html5前端入门视频教程从入门到精通小白需学 第一部分:课程体系解读 http://pan.baidu.com/s/1o7B9OYA 第二部分:案例讲解 https://pan.baidu.com/s/1nwyNFg1 第三部分:知识点讲解 ... Vue组件之手机通讯录实战...
  • 12月19日10:00 - 2月8日23:00课程时长:7周课程负载:3.5小时/周内容类型:视频 文档 随堂测验 富文本 讨论课程分类:前端开发实践 前端开发 技术开发页面制作课程以解决实际案例为导向,基础表现原理深入再...

空空如也

空空如也

1 2 3
收藏数 53
精华内容 21
关键字:

从入门到微前端