巨石应用解决方案 ❌ 📦

2021-11-01 01:45:14 +08:00
 kaiduo

hi, all 分享一下大型系统与 esm 开发的故事 原文链接: https://github.com/xiaoxiaojx/blog/issues/20

背景

最近一段时间陆续有同学吐槽, 现有的开发环境打包太慢了, 原话如下

也确实, 3 分 45 秒 🐢🐢🐢 的等待时间谁又受得了 😣 ! 那么我们现在的脚手架的问题出在哪里 ?

现有脚手架是基于 webpack 打包,其实做了 如 babel, ts 等缓存优化,甚至 hard-source 这样的持久缓存。但是由于需求的快速迭代,一切换分支导致了大量 node_modules 依赖变化需要重新生成新的缓存,使得每次打包缓存等优化等都失效了, 此时我也埋下了 nopack (不打包 ❌📦 ) 的仇恨种子!

所以当现有的优化手段都命中的时候,时间才能勉强减少到 40s 🐢 左右。

webpack5 也尝试去解决慢的这个问题, 比如新增了一个比较重量级的持久缓存的功能, 不过从 esbuild 官方给大家的数据来看, webpack5 却是最慢的 ! 😢

这可能是 webpack5 被黑得最惨的一次... 因为第一次打包有一部分时间是在生成缓存了, 怎么不拿第二次缓存生效后的时间来遛一遛比一比了?在这种情况下, 我们升级 webpack5 可能还是解决不了痛点, 分支一来回切换又回到了解放前!

当项目逐渐膨胀时, 似乎是已经到了 webpack 的瓶颈, 近期特别火的 vite 与 snowpack 或许才是真正的解决方案 ?

vite 、snowpack

最终我想到的是接入 vite 或者 snowpack 解决现有的问题, 关于提到的这些工具的原理, 有不少文章都讲得很好了, 这里就不做过多的介绍。

snowpack 刚出来不久就认真充满好奇的读了他的代码, 发现里面有不少写死的地方, 比如 define 是通过字符串的替换去实现, 这明显就会误伤无辜, css 的 import 也没处理, 最近作者也说会交给社区去维护, 自己有些力不从心了。

Real-world testing is super important. I'm sure that sounds cliche, but its true. We had a few starter projects that we could test Snowpack against, but they were all small and simple. This created a huge experience gap between our internal projects and our actual users.

文章出自 6 More Things I Learned Building Snowpack to 20,000 Stars (Part 2), 而我们更接近业务, 近 100 个大型项目, 包含各类系统与 h5, 几乎能踩完所有的坑。

To be honest, I'm not sure where Snowpack goes from here. I burnt out on it at the end of last year, and haven't found the energy to return. Usage and downloads began to trend down and the community has gotten quieter.

At the same time, Vite (that Snowpack alternative that now powers SvelteKit) is taking off. To their credit, they do a lot of things really well. The good news is that two tools are very similar and easy to switch out. Even Astro is experimenting with moving from Snowpack to Vite in a future release.

虽如此 snowpack 依然是个可敬的产品 🔥 ~

所以综合体验下来还是 vite 值得信赖, 如果此时是新项目毫无疑问我推荐大家使用 vite, 但是我们这是老项目...

何为老项目? 就是之前升级了一个 ts-loader 的大版本, 有俩项目测试环境白屏了。在试图接入 vite 时遇见了 cssModules 解析报错、js scss import 解析路径失败等问题。

到这里我认为 vite 是没有任何问题的, 有些稀奇古怪, 百花齐放的问题的代码就得你自己去改, 当然实际继续挣扎下去可能会发现更多的奇葩问题, 其解决沟通成本和时间成本是无法估计的。

nopack

最终我决定自己开发, 并且过渡阶段希望可以随意切换新的 esm 开发模式与现有的 webpack 模式。

nopack 将以全局安装的形式存在, 即对现有项目 0 侵入,对线上环境 0 危险,对接入的项目源代码可以做到 0 修改就可以运行起来。

Q: 如何做到项目 0 改动接入 ?

Q: nopack 这个名字是啥意思 ?

Q: 如何彻底消除 cjs 这些语法了 ?

Q: nopack 不是坚决不打包吗 ?

Q: 这样看来比 vite 更快 ?

Q: 最终接入的效果如何 ?

Q: esm 开发是不是一本万利 ?

Q: 生产环境能用上了吗 ?

A: nopack 也支持生产环境构建, 但是核心的老项目是不会使用 ⚠️⚠️⚠️ (不会为了这三分钟丢了饭碗 😨 , 还是有风险 ⚠️ )。不过新的内部项目将会默认采用 nopack (其实这里可以用 vite 了, 为了不存在重复的工具就用 nopack 吧)。另外 nopack 生产环境打包是采用的 esbuild ⚡️ , vite 采用的是 rollup 📦 。

Q: esm 开发的时代是不是已经来了 ?

Q: vite 、snowpack 、unbundled 这些推荐用哪个 ?

swc 、esbuild

选择编译器的时候, 调研了 swc 与 esbuild

swc

nextjs 已经实验性使用 swc 。

// https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts#L442

const getBabelOrSwcLoader = (isMiddleware: boolean) => {
    return useSWCLoader
      ? {
          loader: 'next-swc-loader',
          options: {
            isServer: isMiddleware || isServer,
            pagesDir,
            hasReactRefresh: !isMiddleware && hasReactRefresh,
          },
        }
      : {
      // ...
      }

esbuild

vite 与 snowpack 都是使用的 esbuild 。

目前仅发现范型函数赋值给变量编译会有问题。

const Demo = <T>(num): T => {
  return num
}

测试数据

下面是 webpack 模式下测试 esbuild 与 swc 相关的测试数据

@evanw decorator spec unfortunately still seems like it's a long way off, both based on low activity and based on how many things it looks like they still have to figure out.

彩蛋

10 月 27 日看到了字节大佬开源了基于 esbuild 的工具 unbundled, 当时还在想要是自己英语学好一点, 不用中式英语, 还指不一定也叫 unbundled 了 😄

5427 次点击
所在节点    Node.js
2 条回复
kkocdko
2021-11-01 22:56:10 +08:00
感觉这规模好吓人。。。
kaiduo
2021-11-02 01:28:56 +08:00
@kkocdko 有一些都是迭代 3 ,4 年的项目了。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/811979

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX