如何把 Vue 网页打包体积增大 1500%

前端桃园

共 6001字,需浏览 13分钟

 · 2021-11-26

免责声明:这篇文章主要是讽刺。我并不因为我曾经写过一些 TypeScript 就认为我比你强。我也不认为把网页的体积做大对我们来说是好事。请随意歪曲这些观点,以帮助我骗更多点击量。

作者:伯克·霍兰 译者:ssh

https://css-tricks.com/how-to-increase-your-page-size-by-1500-with-webpack-and-vue/

你懂的,有很多文章告诉你如何使你的页面尺寸变小:优化你的图像,删除无关的 CSS 规则,在 Dreamweaver 中使用框架集重写整个东西。看,沃尔玛又缩小了他们的页面大小,差不多这样。

为啥我们没有足够的文章告诉你怎么让页面变大?其实我能找到的唯一的文章就是这篇[1]来自 Geek Squad 的文章,它最后是关于把字体变大的。不错的开始,但我们可以做得更好!

增加点体重

那么,为什么要增大页面大小呢?这对那些使用低带宽网络的人不太好吧?我有几个很好的理由,而且不是刻意的,这里是其中的三个,因为三这个数字更令人满意[2]

  1. 你有千兆的网络连接,而且你住在田纳西州(译者注:网速慢),所以肯定其他人的状况都比你好。
  2. 浏览器会缓存,傻瓜。这意味着你只需要下载一次站点。别抱怨了,第一世界问题[3]
  3. 你并不关心人们是否访问过你的网站,因为你“工作是为了生活,而生活不是为了工作”。

如果这些完全能够认同的原因与你产生了共鸣,我想向你展示我是如何将我的 CSS 的大小增加 1500%,我行,你也行!用一个简单的 webpack 技巧足矣。

一个奇怪的技巧

这一切都始于我决定重构我的退休计划项目 The Urlist[4],用Bulma CSS 框架[5]

网站的最初版本是纯手工研发的,我的 Sass 看起来就像《囤积者》(Hoarders)中的一集。

“伯克,你给我搞出 13 种不同的 .button 样式?你就不能挑一个,我们把剩下的 12 个都干掉这样你就有地方睡觉了?”

Bulma 还包括模态框,我之前一直使用第三方 Vue 组件来搞定它。

它还有一个汉堡式菜单,因为有一个众所周知的科学事实,没有汉堡就没有成功的网站。

听着,规则不是我定的。这就是商业运作的方式。

我对结果很满意。Bulma 风格鲜明,布局系统很容易学习。这就好像世界上有个地方的人理解 CSS,而且不讨厌我。这是一个很难找到的组合。

经过几周的重构之后(在此期间我会问自己,“你在做什么?!?网站明明正常运行的!),我终于完成了。顺便提醒一下,下次你考虑重构时,不要这样做。别管它了。如果你不给下一代留下任何技术债务,他们就会非常无聊,而这将是你的责任。

当我构建这个项目时,我注意到一些奇怪的事情:我的 CSS 的大小明显增加了。我手写的鬼东西东西压缩后只有 30KB,重构后却增加到 260KB。

更糟糕的是,Vue CLI 还在教训我……

当然,我没有理会。我不接受机器人的指令。

我所做的是部署它,到生产环境上,到互联网上。因为我没有花这么多时间重构,却不部署它。对,沉没成本之类的……恕我直言,我比你那些逻辑谬误的海报更务实。我想说的是,我来参加派对可不想没喝酒就回家。

然后我在推特上向矛盾的大伙宣布了我的成就,像往常一样。

此后不久,Jeremy Thomas,也就是 Bumla 的创始人(而且显然很喜欢龙珠[6])回应了。真的很快,就像有个白痴发推,就会发射出蝙蝠信号一样。(译者注:布尔玛是龙珠角色,悟空名场面那个。)

(译者注:这里作者回应的意思大概是说同一个样式出现了 13 次,比如 .section.is-medium[data-v-xxx],看起来是 Vue CSS 命名空间的问题)

重复的样式?13 次?命名空间到底是什么?那是 π 符号还是 Jeremy Thomas 的个性化标志?

就在那一刻,我意识到我不知道我在做什么。

抛弃 Sass,慢慢回退

我首先承认我对 CSS 了解不多,对 Sass 了解更少。Get 到我的点没?关于 Sass 更少!算了忘了吧。我不想要你怜悯的笑。(译者注:作者这里用的是 even Less about Sass,Less 有更少的意思,双关梗)

当我在 Vue CLI 项目中接入 Bulma 时,我创建了一个src/styles文件夹,并放入了一个 bulma-but-not-all-of-bulma-only-some-of-it.scss 文件。他们说命名很难,但我想不通为什么。

那个文件导入了我想用的 Bulma 样式的片段。是 Bulma,但不是全部。只有一部分。(译者注:和 scss 文件的命名相呼应)

@import 'bulma/sass/utilities/_all.sass';
@import 'bulma/sass/base/_all.sass';

@import 'bulma/sass/form/shared.sass';
@import 'bulma/sass/form/input-textarea.sass';

// etc...

然后我把这个文件导入一个自定义的 Sass 文件,我称之为…… site.scss。我喜欢把命名简单化。

@import "./bulma-but-not-all-of-bulma-only-some-of-it.scss";

html,
body {
  background-color: #f9fafc;
}

// etc...

我想全局地将这些文件导入 Vue,这样我就可以在每个组件中使用它们。我想用正确的方法、规范的方法。我觉得已经很明显了,从我愿意在生产中部署 2+ MB 的 CSS 来看,我想用“正确的方式”做事情。

我读了 Sarah Drasner 写的一篇很棒的博文[7],名为《如何将 Sass 文件导入到你的 Vue 应用的每个组件中》。她展示了如何通过修改 vue.config.js 文件来实现这一点。

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        additionalData`@import "~@/styles/site.scss";`,
      },
    },
  },
};

我不明白的是,这会把 Sass 导入到 Vue 应用的每个组件中。你知道,就像这篇博客文章的标题所说的那样。这也是我如何以一堆有着 data-v- 属性选择器的重复的样式收尾。感谢它,我才有了 scoped styles。

Vue 如何处理 scoped

Vue 允许你在组件中 “scope” 样式。这意味着样式只影响它所在的组件,而不影响页面的其余部分。并不是什么神奇的浏览器 API 来做到这一点的。Vue 是通过在元素和选择器中动态插入一个 data- 属性来搞定的。例如这个:

<template>
  <button class="submit">Submitbutton>
  <template>
    <style lang="scss" scoped>
      .submit {
        background-color#20ae96;
      }
    
style>template
  >template
>

……变成这样:

<button class="submit" data-v-2929>Submitbutton>

<style>
  .submit[data-v-2929] {
    background-color#20ae96;
  }
style>

这个动态 data 标记也被添加到组件中的每个子元素中。因此,这个组件的每个元素和每个样式在运行时都会有一个 data-v-2929

如果你导入一个 Sass 文件到你的组件中,其中有实际的样式,Vue(通过 Webpack)将拿到这些样式,并使用动态 data- 属性“命名空间”它们。结果就是你丫的把 Bulma 包含在你的应用中整整 13 次,并且前面有一堆奇怪的 data-v

但这引出了一个问题:如果 webpack 在每个组件中都渲染 CSS,为什么你还想使用 vue.config.js 的手段呢?一句话:变量

变量共享问题

你不能在一个组件中定义 Sass 变量,然后从另一个组件引用它。这也很难管理,因为你会到处定义和使用变量。只有我才会写出这样的代码。

另一方面,你可能会把所有的变量放到一个 variables.scss 文件中。然后,每个组件将引用这个变量的中心存储仓库。在每个组件中导入变量文件是多余的。这也是过度的。没有必要的。且冗长的。

这正是 Sarah 的文章所要解决的问题:将 Sass 文件导入项目中的每个组件。

把变量之类的东西导入到每个组件中没问题,因为变量不会被渲染。如果导入 200 个变量,只引用其中一个,谁会在意呢?这些变量在渲染后的 CSS 中并不存在。

例如,这个:

<style lang="scssscoped>
$primary#20ae96;
$secondary#336699;

.submit {
  background-color: $primary
}
style>

……变成这样:

<style>
.submit[data-v-2929] {
  background-color#20ae96;
}
style>

所以,这里有两个问题:

  1. Bulma 需要全局化。
  2. Bulma 的变量应该在组件中可访问。

我们需要的是和 Sarah 的技术巧妙结合,以及关于 Bulma 结构的一些专有知识。

在 Vue 中使用 Bulma

通过在src/styles目录下创建三个文件,我们将以最少的重复来完成这一任务:

variables.scss:这个文件将是你拉入 Bulma 的变量和覆盖/定义你自己的。请注意,必须包括以下三个文件,以获得所有 Bulma 的变量。它们的顺序是这样的……

// Your variables customizations go up here

// Include Bulma's variables
@import 'bulma/sass/utilities/initial-variables.sass';
@import 'bulma/sass/utilities/functions.sass';
@import 'bulma/sass/utilities/derived-variables.sass';

bulma-custom.scss:在这个文件里你可以按需引入 Bulma 的变量。它应该引用 variables.scss 文件。

@import './variables.scss';

/* UTILTIES */
@import 'bulma/sass/utilities/animations.sass';
@import 'bulma/sass/utilities/controls.sass';
@import 'bulma/sass/utilities/mixins.sass';

// etc...

site.scss:这里引入了 bulma-custom.scss 文件,也是定义整个项目使用的全局样式的地方。

@import url('https://use.fontawesome.com/releases/v5.6.3/css/all.css');
@import './bulma-custom.scss';

html,
body {
  height100%;
  background-color#f9fafc;
}

// etc...

在你的 main.js 中导入 site.scss。或者在我的例子中,main.ts。用了 TypeScript 所以我比你更强吗?是的。是的确实是的。

import Vue from 'vue';
import App from './App.vue';
import router from './router';

// import styles
import '@/styles/site.scss';

这使得我们在每个组件中都可以使用所有的 Bulma 片段。它们是全局性的,但只会包含一次。

根据 Sarah 的文章,添加 variables.scss 文件到 vue.config.js文件。

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        additionalData`@import "~@/styles/variables.scss";`,
      },
    },
  },
};

这让你可以从任何 .vue组件中引用任何 Bulma 变量或自己的变量。

现在两全其美了:Bulma 在全局范围内可用,并且你仍然可以在所有组件中访问所有的 Bulma 变量。

现在的 CSS 总大小?约比以前小 1500%……

拿去吧,沃尔玛。

一个 PR 的救赎

为了弥补自己的错误,我向 Bulma 文档提交了一份 PR,讲述了如何在 Vue CLI 项目中定制 Bulma。这是一种悔悟,因为我发了推特让布尔玛看起来像个问题,其实伯克才是个问题。

你可能察觉到我已经弄明白的事情:伯克一直都是问题所在。

参考资料

[1]

这篇: https://www.bestbuy.com/site/tech-tips/change-web-page-size/pcmcat748301880661.c?id=pcmcat748301880661&intl=nosplash

[2]

令人满意: https://en.wikipedia.org/wiki/Rule_of_three_%28writing%29

[3]

第一世界问题: https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E4%B8%96%E7%95%8C%E9%97%AE%E9%A2%98

[4]

The Urlist: https://www.theurlist.com/

[5]

Bulma CSS 框架: https://css-tricks.com/how-to-increase-your-page-size-by-1500-with-webpack-and-vue/#:~:text=over%20to%20the-,Bulma%20CSS%20framework,-.

[6]

龙珠: https://dragonball.fandom.com/wiki/Bulma

[7]

一篇很棒的博文: https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app

浏览 12
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报