基本上,我想实现以下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
后立即立即渲染,而不是取决于任何其他资源。 真的,我想这是每个人都想要的...
但是debault的Vue配置为将已编译的styles
包含到<head>
标记中,该标记会阻止页面的呈现,直到加载这些样式为止。我找不到任何有关如何更改它的文档。
因此,我设法手动模拟了两种变体:
<head>
(默认)注入<body>
中(需要)以下是视觉差异的图片:
<head>
注入(默认):<body>
注入(需要):图片上的标签“ html渲染开始”表示用户实际上能看到正在完全在html中定义的加载动画(在我的情况下为svg和样式的一小部分,在一般情况下可以是任何东西)并且不依赖任何其他外部资源来呈现它。
答案 0 :(得分:1)
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)
;
// ...
}
// ...
};
最终,这与Vue.js无关。可以轻松将其与其他框架或裸露的webpack一起使用。
如果HtmlWebpackPlugin
为样式提供一些inject-css
选项,而为脚本提供has,则可能会容易得多。
参见:https://github.com/jantimon/html-webpack-plugin/blob/e2c6990e94b298ff66bcd885c9a03a78221479f6/index.js#L548