[譯] 在 HTTP/2 的世界裏管理 CSS 和 JS

使用了 HTTP/2,在網站中傳輸 CSS 和 JS 將變得徹底不一樣,本文是結合我實踐的一份指南。css

咱們已經據說 HTTP/2 不少年了。咱們甚至寫了一些關於它的博客。但咱們的真正實踐並很少。一直到如今。在一些最近的項目中,我把使用 HTTP/2 做爲一個目標,並弄清楚如何更好地應用多路複用。本文並不會主要去講你爲何應該使用 HTTP/2,而是要討論我是如何管理 CSS 和 JS 的從而解釋這一範式轉變。html

拆分 CSS

這是咱們多年來做爲最佳實踐的反例。但爲了汲取多路複用的好處,最好的方式仍是把你的 CSS 拆分紅更小的文件,這樣在每一頁只加載必要的CSS。應該像這個例子這樣:前端

<html>
<head>
    <!--每一頁都是用的全局樣式, header/footer/etc -->
    <link href="stylesheets/global/index.css" rel="stylesheet">
</head>
<body>

    <link href="stylesheets/modules/text-block/index.css" rel="stylesheet">
    <div class="text-block">
        ...
    </div>

    <link href="stylesheets/modules/two-column-block/index.css" rel="stylesheet">
    <div class="two-column-block">
        ...
    </div>

    <link href="stylesheets/modules/image-promos-block/index.css" rel="stylesheet">
    <div class="image-promos-block">
        ...
    </div>

</body>
</html>複製代碼

沒錯,<link> 標籤放在了 <body> 內部,但沒必要驚慌,這徹底合規。所以對於每個小的標籤塊,均可以擁有一個獨立的只包含相應 CSS 的樣式。假如你正在使用模塊化風格構建你的頁面,這很容易設置。node

管理 SCSS 文件

通過一些實踐,這是我整理的 SCSS 文件結構:react

CONFIG 文件夾android

我使用這個文件夾設置一堆變量:ios

這裏的入口文件是 _index.scss,它引入了全部其餘 SCSS 文件,因此我能夠訪問到一些變量和 mixins。它是這樣的:git

@import "variables";
@import "../functions/*";複製代碼

FUNCTIONS 文件夾es6

顧名思義,它包含了一些常見的 mixins 和函數,每個 mixin 或函數都對應一個文件。github

GLOBAL 文件夾

這個文件夾包含我每一頁都使用的 CSS。特別適合放一些相似網站的 header、footer、reset、字體和其餘通用樣式之類的東西。

index.scss 看起來是這樣的:

@import "../config/index";
@import "_fonts.scss";
@import "_reset.scss";
@import "_base.scss";
@import "_utility.scss";
@import "_skip-link.scss";
@import "_header.scss";
@import "_content.scss";
@import "_footer.scss";
@import "components/*";複製代碼

最後一行引入了全部 components 的子目錄,這是將額外全局樣式模塊化的捷徑。

MODULES 文件夾

這是咱們 HTTP/2 體系中最重要的文件夾。當我拆分樣式到對應的模塊,這個文件夾會包含很是很是多的文件。因此我從拆分每個模塊到子目錄開始:

每一個模塊中的 index.scss 是這樣的:

// 導入全部的全局變量和 mixin
@import "../../config/index";

// 導入這個模塊文件夾中的全部部分
@import "_*.scss";複製代碼

這樣我能夠訪問到變量和 mixin,而後我能夠把模塊的 CSS 拆分爲許多部分,它們組合成一個單獨的 CSS 模塊文件。

PAGES 文件夾

實質上這個文件夾和 modules 文件夾同樣,但我爲了頁面特定的內容使用它」。這種更模塊化的方式在咱們最近作的東西里絕對罕見,可是它很好地把頁面的特殊樣式拆分出來了。

適配 Blendid

最近全部的項目咱們都是用 Blendid 來構建的 。爲了實現上文描述的 SCSS 配置,我須要添加 node-sass-glob-importer。一旦裝好它,我只需把它添加到 Blendid 的 task-config.js 中。

var globImporter = require('node-sass-glob-importer');

module.exports = {
    stylesheets: {
        ...
        sass: {
            importer: globImporter()
        },
          ...
}複製代碼

duang,這樣就完成了管理 SCSS 的 HTTP/2 配置。

彩蛋:Craft 宏

很長一段時間以來,咱們在 Viget 都主張使用 Craft,我就寫了一個宏來減小這種引入樣式的方式:

{%- macro css(stylesheet) -%}
    <link rel="stylesheet" href="/stylesheets{{ stylesheet }}/index.css" media="not print">
{%- endmacro -%}複製代碼

當我想要引入一個模塊的 CSS 文件,我只需這樣:

{{ macros.css('/modules/image-block') }}複製代碼

若是我須要在整個網站上放置樣式表引用,這就更簡單了。

管理 JS

就像 CSS 同樣,我想要把 JS 拆分爲模塊,這樣每一頁只加載必要的 JS。同樣的,使用 Blendid 配置,爲了一切正常運轉我只須要作一點點微調。

我使用的是 import(),而非 Webpack 的require(),。所以如今的 modules/index.js 文件須要看起來是這樣的:

const moduleElements = document.querySelectorAll('[data-module]');

for (var i = 0; i < moduleElements.length; i++) {
    const el = moduleElements[i];
    const name = el.getAttribute('data-module');

    import(`./${name}`).then(Module => {
        new Module.default(el);
    });
}複製代碼

正如 Webpack 文檔中所說:」這個特性內部依賴 Promise。若是你在舊版本瀏覽器使用 import(),記得使用一個 polyfill 來兼容 Promise,好比 es6-promise 或者 promise-polyfill「。

所以我把 es6-promise polyfill 加入到個人入口文件 app.js 中,使其自動兼容。

require('es6-promise/auto');複製代碼

是的,而後你就能夠在 Blendid 開箱即用的模式觸發模塊生成對應特定的 JS。

<div data-module="carousel">複製代碼

這很完美嗎?

還不,但至少能夠引領你開始以合理的方式管理 HTTP/2 資源。隨着咱們對如何拆分代碼來更好地使用 HTTP/2 的思考,我真切地但願這個配置將會愈來愈完善。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索