2

基本上,我想实现这个index.html结构:

<html>
<head>
    <!-- titles, metas and other "static" stuff -->
    <link rel="preload/prefetch" ...> <!-- injected by webpack (ok) -->
    <!-- By default compiled styles are injected here, in head, I want them in body -->

</head>
<body>
<div>
    My static loading animation
    All possible styling is inlined
    It doesn't depend on anything!
    It also could be anything, even just a plain "Loading..." text.
    You still WON'T see it until all style's in head are loaded.
</div>

<div id="app">Vue application goes here</div>

<link rel="stylesheet" href="..."> <!-- Styles injected by webpack (WANTED!) -->
<script src="..."></script> <!-- Scripts injected by webpack (by default, OK) -->

</body>

我想要这个的原因是,我的 html 完全能够向用户显示初始加载动画,我希望它在加载后立即index.html呈现,而不依赖于任何其他资源。真的,我想这是每个人都想要的,只是说...

但是 Vue by debault 被配置为包含它被编译styles<head>标签中,这会阻止页面的呈现,直到这些样式被加载。我找不到任何关于如何更改它的文档。


更新:图片!

因此,我设法手动模拟了两种变体:

  1. 样式被注入<head>(默认)
  2. 样式被注入<body>(需要)

以下是视觉差异的图片:

1)样式被注入<head>(默认):

样式注入头部

2)样式被注入<body>(想要):

样式注入主体

图片上的“html 渲染开始”标签意味着用户实际上看到加载动画,完全在 html 内部定义(在我的例子中,一小块 svg 和样式,一般情况下可以是任何东西)并且不依赖于任何其他外部资源让它渲染。

4

1 回答 1

3

解决方案

vue.config.js

class InjectStylesInBody {
    apply(compiler) {
        compiler.hooks.compilation.tap('inject-styles-in-body', (compilation) => {
            if (!compilation.hooks.htmlWebpackPluginAlterAssetTags) return;
            compilation.hooks.htmlWebpackPluginAlterAssetTags.tap('inject-styles-in-body', function(pluginArgs) {
                const { head, body } = pluginArgs;
                head
                    .filter(asset => asset.tagName === 'link' && asset.attributes && asset.attributes.rel === 'stylesheet')
                    .forEach(asset => {
                        head.splice(head.indexOf(asset), 1);
                        body.push(asset);
                    });
            });
        });
    }
}

module.exports = {
    // ...
    chainWebpack: config => {
        // ...
        config
            .plugin('inject-styles-in-body')
            .use(InjectStylesInBody)
        ;
        // ...
    }
    // ...
};

笔记

于 2019-10-07T08:39:45.267 回答