草庐IT

javascript - 带有小初始脚本和异步加载所有其他脚本的 Webpack

coder 2024-05-09 原文

在开发由多个页面和不同页面类型组成的普通网站时,我已经开始使用 Webpack。我习惯了 RequireJs 脚本加载器,它在需要时按需加载所有依赖项。页面加载时只下载一小段 javascript。

我想实现的是:

  • 一个小的初始 javascript 文件,用于异步加载依赖项
  • 每种页面类型都可以有自己的 javascript,它们也可能有依赖关系。
  • 公共(public)模块, vendor 脚本应该捆绑在公共(public)脚本中

我已经尝试了很多配置来实现这个但没有成功。

entry: {
    main: 'main.js', //Used on all pages, e.g. mobile menu
    'standard-page': 'pages/standard-page.js',
    'start-page': 'pages/start-page.js',
    'vendor': ['jquery']
},
alias: {
    jquery: 'jquery/dist/jquery.js'
},
plugins: [
    new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js"),
    new webpack.optimize.CommonsChunkPlugin('common.js')
]

在 html 中,我想像这样加载 javascripts:

<script src="/Static/js/dist/common.js"></script>
<script src="/Static/js/dist/main.js" async></script>

并在特定的页面类型上(起始页)

<script src="/Static/js/dist/start-page.js" async></script>

common.js 应该是一个用于快速加载页面的小文件。 main.js 在里面加载 async 和 require('jquery')。

Webpack 的输出看起来很有希望,但我无法让 vendor bundle 异步加载。其他依赖项(我自己的模块和 domReady)加载到自动生成的 block 中,但不是 jquery。

我可以找到很多几乎可以做到这一点的例子,但不是异步加载 vendor 的重要部分。

webpack 构建的输出:

                  Asset       Size  Chunks             Chunk Names
            main.js.map  570 bytes    0, 7  [emitted]  main
                main.js  399 bytes    0, 7  [emitted]  main
       standard-page.js  355 bytes    2, 7  [emitted]  standard-page
c6ff6378688eba5a294f.js  348 bytes    3, 7  [emitted]
          start-page.js  361 bytes    4, 7  [emitted]  start-page
8986b3741c0dddb9c762.js  387 bytes    5, 7  [emitted]
              vendor.js     257 kB    6, 7  [emitted]  vendor
              common.js    3.86 kB       7  [emitted]  common.js
2876de041eaa501e23a2.js     1.3 kB    1, 7  [emitted]  

最佳答案

这个问题的解决方案有两个:

  1. 首先你需要了解how code-splitting works in webpack
  2. 其次,您需要使用类似 CommonsChunkPlugin 的东西生成该共享包。

代码拆分

在开始使用 webpack 之前,您需要摆脱对配置的依赖。 Require.js 是关于配置文件的。这种心态让我很难过渡到 webpack,它更接近于 node.js 中的 CommonJS 建模,不依赖于任何配置。

考虑到这一点,请考虑以下内容。如果您有一个应用程序并且希望它异步加载 javascript 的其他部分,您需要使用以下范例之一。

要求.确保

require.ensure是您可以在应用程序中创建“拆分点”的一种方法。同样,您可能认为需要通过配置来完成此操作,但事实并非如此。在我点击 require.ensure 的示例中在我的文件中,webpack 将自动创建第二个包并按需加载它。在该拆分点内执行的任何代码都将捆绑在一个单独的文件中。

require.ensure(['jquery'], function() {
    var $ = require('jquery');
    /* ... */
});

要求([])

您也可以使用 AMD 版本的 require() 实现同样的效果,接受一系列依赖关系的那个。这也将创建相同的分割点:

require(['jquery'], function($) {
    /* ... */
});

共享包

在上面的示例中,您使用了 entry创建一个 vendor有 jQuery 的包。您不需要手动指定这些依赖包。相反,使用上面的分割点,webpack 将自动生成它。

使用 entry仅适用于单独的 <script>您想要在页面中添加的标签

现在您已经完成了所有这些,您可以使用 CommonsChunkPlugin进一步优化你的 block ,但同样大部分魔法都是为你完成的,除了指定应该共享哪些依赖项之外,你不需要做任何其他事情。 webpack将自动拉入共享 block 而不需要额外的 <script>标签或 entry配置。

结论

您描述的场景(多个 <script> 标签)实际上可能不是您想要的。使用 webpack,所有的依赖项和包都可以从一个 <script> 开始自动管理。标签。在经历了从 require.js 到 webpack 的多次重构迭代后,我发现这通常是管理依赖项的最简单和最好的方法。

祝一切顺利!

关于javascript - 带有小初始脚本和异步加载所有其他脚本的 Webpack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33001985/

有关javascript - 带有小初始脚本和异步加载所有其他脚本的 Webpack的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  7. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  8. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  9. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  10. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

随机推荐