我已经升级到Rails的webpack 4。我在Vue.js 2中使用它。在配置中也使用了块。但是自升级以来,我注意到页面加载顺序很奇怪。该页面先加载HTML,然后再加载样式和JS,而这并不是以前发生的事情。我为视频添加了前后链接,以更好地了解问题。
我一直在这里和任何地方寻找任何遇到相同问题的人,但我无法...
这是我的配置文件:
const environment = require('./environment')
const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
environment.plugins.append(
'BundleAnalyzerPlugin',
new BundleAnalyzerPlugin()
)
module.exports = environment.toWebpackConfig()
const { environment } = require('@rails/webpacker')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const vue = require('./loaders/vue')
const additionalConfig = {
plugins: [
new VueLoaderPlugin(),
],
optimization: {
splitChunks: {
cacheGroups: {
default: false,
vendor: {
name: 'vendor',
chunks: 'all',
test: /[\\/]node_modules[\\/]/,
minChunks: 3,
},
}
}
},
module: {
rules: [{
test: /\.pug$/,
loader: 'pug-plain-loader'
}, {
test: /\.sass$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader']
}]
},
output: {
},
devtool: 'source-map',
}
environment.config.merge(additionalConfig);
environment.loaders.prepend('vue', vue)
module.exports = environment
import 'element-ui/lib/theme-chalk/index.css';
import 'element-ui/lib/theme-chalk/display.css';
import 'flexboxgrid/css/flexboxgrid.css';
import Vue from 'vue/dist/vue.esm';
import VueCookies from 'vue-cookies';
import { DateTime } from 'luxon';
// ElementUI Components
import ElementUI from 'element-ui';
import locale from 'element-ui/lib/locale/lang/en';
// Custom Components
import TextSection from '../components/TextSection.vue';
import TopNavigation from '../components/navigation/TheTopNavigation.vue';
import { store } from '../store';
Vue.use(ElementUI, { locale });
Vue.use(VueCookies);
const app = new Vue({
el: '#app',
store,
mounted() {
var selector = document.querySelector("#app");
var errors = selector.dataset.errors;
if (selector) {
store.commit('base_states/authenticate',
JSON.parse(selector.dataset.signedIn)
);
}
if (errors) {
this.$message({
dangerouslyUseHTMLString: true,
message: JSON.parse(errors).join("\n"),
type: 'error'
});
}
},
components: { TextSection, TopNavigation },
});
if (!app.$cookies.get('timezone')) {
app.$cookies.set("timezone", DateTime.local().zoneName);
}
#app{ data: { signed_in: "#{user_signed_in?}", errors: flash[:errors] } }
.landing-top
.row.banner
%top-navigation{ ":user" => user, "logo" => logo }
.row.start-sm.around-sm.middle-sm.center-xs.landing-hero
.col-lg-4.col-md-4.col-sm-4.col-xs-12
%h1= t 'static.banner.headline'
%p= t 'static.banner.subtitle'
.actions
%a.no-decoration{ class: "el-button el-button--success", href: "/events" }
See upcoming events
.col-lg-6.col-md-6.col-sm-6.col-xs-12
= video_tag("https://s3.eu-west-2.amazonaws.com/vras-assets/product_preview_new.webm",
poster: preview_poster,
class: "preview-video", autoplay: "true",
muted: "true", loop: "true" )
.landing-body.site-padding
.row.around-lg.middle-lg.middle-md.features
.col-md-4.col-xs-12.feature-column
= inline_svg 'icons/potion.svg', class: 'svg-icon'
%text-section{ "title" => t('static.first_section.title_one'),
"text" => t('static.first_section.text_one') }
.col-md-4.col-xs-12.feature-column
= inline_svg 'icons/map.svg', class: 'svg-icon'
%text-section{ "title" => t('static.first_section.title_two'),
"text" => t('static.first_section.text_two') }
.col-md-4.col-xs-12.feature-column
= inline_svg 'icons/unicorn.svg', class: 'svg-icon'
%text-section{ "title" => t('static.first_section.title_third'),
"text" => t('static.first_section.text_third') }
.row.center-lg.center-xs.video-showcase
.col-lg-10.col-md-10.col-xs-12
= video_tag('https://s3.eu-west-2.amazonaws.com/vras-assets/preview.mp4',
poster: 'meta_cover.jpg',
class: 'preview-video',
autoplay: 'true',
muted: 'true',
loop: 'true')
.col-lg-8.col-md-8.col-xs-10{ style: "padding-top: 20px" }
%h3
= image_tag("bigscreen_logo.png", width: "250px")
%br
= t('static.third_section.title')
%text-section{ "text" => t('static.third_section.text') }
.landing-body.site-padding
.row.around-lg.middle-lg.middle-md{ style: "margin-bottom: 100px" }
.col-lg-6.col-md-6.col-xs-12
%text-section{ "title" => t('static.second_section.title'),
"text" => t('static.second_section.text') }
.col-lg-6.col-md-6.col-xs-12.first-xs.last-lg.last-md{ style: "text-align: center" }
%iframe{:title => "Discord Widget", :allowtransparency => "true", :frameborder => "0", :height => "519", :src => "https://discordapp.com/widget?id=402246704252059648&theme=dark", :width => "320"}
= render "footer"
= javascript_packs_with_chunks_tag 'landing_page'
= stylesheet_packs_with_chunks_tag 'landing_page'
我的研究使我相信这个问题:
之所以发生这种情况,是因为您与样式加载器捆绑在一起,这会将CSS作为字符串放入Javascript捆绑包中。
因此,当浏览器解析JS包时(非常慢),HTML将呈现(非常快)。在该捆绑包的末尾,浏览器将找到包含您的CSS字符串的模块。然后它将对其进行解析,并使用Javascript来应用样式。
我找不到改善此方法的方法,因此,到目前为止,我已经将所需的CSS提取到Rails app/assets
文件夹中,以便在webpack和Vue之外加载。这在一定程度上解决了弹出窗口问题,但我仍然觉得这是错误的解决方法,并且只是一种解决方法...
答案 0 :(得分:0)
使用webpack3进行的配置看起来像在生成的html的顶部注入css,而webpack4在其底部进行注入。尝试将= stylesheet_packs_with_chunks_tag 'landing_page'
移动到顶部。我不确定landing_page
标记中有什么CSS。它可能不完整,其余的CSS从js异步加载。检查webpack3和webpack4生成的html代码,并检查生成的css块的列表及其加载顺序。
答案 1 :(得分:0)
为确保样式表正常工作,我建议添加:
= content_for :head
= stylesheet_packs_with_chunks_tag 'landing_page'
,然后在应用程序布局(或主布局)中
= yield :head
这将确保样式表在之前加载,并且在javascript生效后就可以使用。
答案 2 :(得分:0)
虽然我还没有完全了解这一点,但是我发现了一个临时的简单解决方案,可以返回到最初的webpack 3行为,即JS / CSS阻止页面的加载,受此{{3 }}
window.addEventListener('load', () => {
### Initialise Vue app
});
它会强制等到窗口加载所有JS / CSS资产后再加载Vue。这适用于所有页面,但只有一页,因为除登录页面外的所有内容均仅由Vue组件构建。
对于登录页面,我采用了@Berto建议,以将JS / CSS包加载委托给头部,并产生收益。因此,现在我们也阻止了登录页面上的执行。综合来看,我看到的加载行为与以前完全一样。