用了十多年Erlang和Elixir之后,再回头写面向对象代码是什么体验?一位开发者决定不玩"Hello World",直接上手用Dart和Flutter搭个真正的网页——这个选择本身就值得琢磨。

为什么偏偏是Flutter?

打开网易新闻 查看精彩图片

原文作者的开场很诚实:函数式语言用久了,面向对象那套确实别扭。但更值得注意的不是技术偏好,而是他的切入点——拒绝"复杂项目"和"简单演示"两个极端,选了一个对自己"有用"的目标。

这透露出一种典型的资深开发者思维:学习新工具时,动机比难度更重要。没有真实需求驱动的技术尝鲜,往往半途而废。

Flutter官方文档提供了从零开始的快速教程,但作者没急着复制粘贴。他先列了一个需求清单,然后锁定核心文档《Building a web application with Flutter》。这种"先规划再动手"的习惯,大概是函数式编程训练出来的副作用——Erlang社区历来强调系统设计先于代码。

创建项目的命令很直接:

flutter create www --platforms web

cd www

加上--platforms web参数,明确指定目标平台。默认生成的模板包含一个演示页面,源代码放在web目录下。启动服务器同样一行命令:

flutter run

编译稍有延迟,浏览器会自动打开或新建标签页,展示来自localhost的演示站点。作者在Chromium上截了图,但关键信息是:这个过程对非前端开发者足够友好,不需要手动配置Webpack或Vite。

编译产物里藏着什么?

真正让作者停下来的是flutter build之后的产物。他进入build/web目录,用tree命令列出所有文件——这个举动本身就说明问题:他想知道"黑盒"里到底装了什么。

输出结果分成几个区块:

资源层(assets):字体清单、材质图标、Cupertino图标、着色器片段(ink_sparkle.fragstretch_effect.frag)。

渲染引擎(canvaskit):这是Flutter Web的核心依赖,包含JavaScript接口、符号表和WebAssembly二进制文件。值得注意的是,canvaskit分了两个版本——标准版和Chromium优化版,后者体积和性能可能有差异。

辅助运行时flutter.js负责初始化,flutter_service_worker.js支持离线缓存,flutter_bootstrap.js处理启动流程。

应用本体main.dart.js,Dart代码编译后的JavaScript输出。

作者的原话是:"Hmm. Lot of files have been generated indeed." 然后坦白:自己不是前端出身,上次从零建站已经是多年前的事。这种坦诚很重要——它设定了整篇文章的视角:一个后端/函数式背景的人,如何重新理解现代Web开发工具链。

辩论:Flutter Web是捷径还是弯路?

把这段个人记录放在更大的语境里,能看到两种对立的声音。

正方:跨平台的价值被低估了

Flutter的核心卖点是一套代码跑多端。对于作者这样的开发者,这意味着不需要重新学习React/Vue/Angular的生态系统,就能输出可用的Web界面。Dart语言本身兼具AOT编译和JIT热重载,对习惯了Erlang/Elixir运行时反馈的人来说,学习曲线相对平缓。

更实际的是团队成本。如果移动端已经用Flutter,Web端沿用同一套技术栈,能大幅减少上下文切换。canvaskit渲染虽然增加了初始加载体积,但对B端后台系统或内部工具而言,这点代价可以接受。

反方:Web平台不是Flutter的主场

批评者会指出,Flutter Web的渲染架构(Skia/CanvasKit)和浏览器原生DOM是两条路。这意味着:SEO需要额外处理,无障碍访问(a11y)支持滞后,与现有JavaScript库的互操作总有摩擦。

产物体积是硬伤。canvaskit.wasm alone就超过3MB,对移动端Web用户不友好。作者列出的文件清单里,光是canvaskit目录就有多个变体,说明Flutter团队自己在权衡兼容性和性能——这种复杂性最终会转嫁到开发者身上。

更重要的是"为什么"问题。如果目标是学习现代Web开发,绕过HTML/CSS/JavaScript的生态,等于跳过了整个行业十年积累的工程实践。作者自己也承认多年没碰前端,用Flutter重建Web技能,会不会是一种逃避?

我的判断:工具选择暴露的是组织约束,而非技术优劣

回到原文的有限信息,作者没有给出最终评价——文章停在产物清单的展示,留下开放的观察空间。但这恰恰是最有价值的部分。

他的选择逻辑很清晰:现有技能组合(函数式背景)+ 具体目标(有用的单页应用)+ 时间约束(不想从零学前端工具链)。Flutter Web在这个三角里找到了位置。这不是"最佳技术"的评选,而是特定约束下的可行解。

值得注意的细节是--platforms web参数和flutter_service_worker.js的存在。前者说明Flutter的多平台支持是显式声明的,不是默认全开;后者暗示PWA(渐进式网页应用)能力被纳入基础模板。这些设计选择反映了Google对Flutter Web的定位:不是替代React,而是填补"跨平台覆盖"的缺口。

作者最后没说完的话大概是:这些文件到底是必要的复杂,还是历史包袱?canvaskit的Chromium特供版会不会走向Edge/WebKit适配?函数式编程的思维模式,在Flutter的Widget树里能找到对应吗?

这些问题没有标准答案。但对于一个用惯了Erlang监督树和Elixir宏系统的开发者来说,Flutter的声明式UI和单向数据流,或许比jQuery时代的DOM操作更容易建立直觉映射——如果他能熬过Dart的类型系统和OOP语法的话。

当跨平台框架承诺"一套代码 everywhere"时,真正该问的是:你的团队准备好为这个" everywhere"支付什么隐性成本?