javascript - Webpack 4 不按顺序加载页面

标签 javascript ruby-on-rails vue.js webpack webpack-4

我已经升级到 Rails 的 webpack 4。我将它与 Vue.js 2 一起使用。我还在我的配置中使用 block 。但是自升级以来,我注意到页面加载顺序很奇怪。页面在加载样式和 JS 之前加载 HTML,这不是以前发生的情况。我附上了之前和之后的视频链接,以便更好地理解问题。

我一直在这里和到处寻找有同样问题的人,但我不能...

With Webpack 3(before)

With Webpack 4(after)

这是我的配置文件:

开发配置

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);
}

该页面的 Rails View

#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'

更新

我的研究让我相信这是一个问题:

This is happening because you're bundling with style-loader, which puts your CSS as a string inside your Javascript bundle.

So the HTML will render (very fast) while the browser is parsing your JS bundle (very slow). Towards the end of that bundle, the browser will find the module containing your CSS string. Then it'll parse that and apply the styles with Javascript.

我找不到改进它的方法,所以现在我已经将我需要的 CSS 提取到 Rails app/assets 文件夹中,以便在 webpack 和 Vue 之外加载。这在一定程度上解决了弹出问题,但我仍然觉得这是错误的解决方法,只是一种解决方法...

最佳答案

我建议为确保样式表正常工作添加:

= content_for :head
  = stylesheet_packs_with_chunks_tag 'landing_page'

然后在应用布局(或主布局)

= yield :head

这将确保样式表在 DOM 之前加载,并在 javascript 开始运行时准备就绪。

关于javascript - Webpack 4 不按顺序加载页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55210110/

相关文章:

javascript - 在 Angular 指令中访问父 Controller

vue.js - 如何激活 Vue-Cli 4 的源映射?

javascript - node.js 创建隐藏目录 (Windows)

javascript - 将 Canvas 图像发送到服务器格式 JPG javascript 或 jquery

javascript - 如何使用 jquery 和 javascript 只返回数据而不是 html?

ruby-on-rails - 在事件记录中动态查找条件

ruby-on-rails - 用户路由 - Rails

javascript - 如何在 Vue.js 中传递 $router.push 中的数组?

vue.js - Vuex 更改不影响模块

javascript - 在 React.js 中,我试图在图像之上的叠加层之上添加文本和其他一些元素