如何跨多个Webpack包共享jQuery的同一实例? [英] How to share the same instance of jQuery across multiple Webpack packs?

查看:146
本文介绍了如何跨多个Webpack包共享jQuery的同一实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Rails应用程序,从Sprockets迁移到Webpack.我们当前的JavaScript依赖于全局分配给window的库.为了进行迁移,我希望保持全局分配,直到我们稍后再解决为止.我想在不对JavaScript进行任何更改的情况下将Sprockets换成Webpack.

I'm working in a Rails app, migrating from Sprockets to Webpack. Our current JavaScript relies on libraries globally assigned to window. In order to migrate over, I'd like to maintain global assignment until we address it at a later date. I'd like to swap from Sprockets to Webpack without any JavaScript changes.

我们有几个JavaScript捆绑包,这些捆绑包是为提高性能而手动拆分的:

We have several JavaScript bundles, which have been manually split up for performance:

  • core.js,其中包含jQuery和其他几个文件.这是一个捆绑包.
  • vendor.js,其中包含所有其他库和jQuery插件.这是递延的捆绑包.
  • application.js,其中包含我们的自定义应用程序代码.也是延期捆绑包.
  • core.js, which contains jQuery and a couple other files. It's a blocking bundle.
  • vendor.js, which contains all other libraries and jQuery plugins. It's a deferred bundle.
  • application.js, which contains our custom application code. Also a deferred bundle.

所有捆绑包均依赖jQuery,而application.js依赖于vendor.js.对于Sprockets来说很好,但是Webpack就是一个问题.

All the bundles rely on jQuery, and application.js relies on vendor.js. That's fine for Sprockets, but is an issue with Webpack.

如何将jQuery保留在core.js中,但将其从Webpack中的vendor.jsapplication.js中排除?或另一种询问方式是我如何共享相同的内容跨多个Webpack捆绑包的jQuery的实例?我需要使用同一实例,因为application.js依赖于vendor.js

How can I keep jQuery in core.js, but exclude it from vendor.js and application.js in Webpack? or another way to ask this is How do I share the same instance of jQuery across multiple webpack bundles? I need to use the same instance because application.js relies on jQuery plugins defined in vendor.js

我的配置文件同时包含expose-loaderProvidePlugin,但它们在捆绑包本身中包括jQuery,这不是同一实例.换句话说,我将jQuery捆绑了多次(已用splitChunks()修复),但是我不能保证我正在使用哪个实例,因此不能保证该插件可用.

My config file includes both expose-loader and ProvidePlugin, but these include jQuery in the bundle itself, which is not the same instance. In other words, I'm getting jQuery bundled multiple times (which is fixed with splitChunks()), but I can't guarantee which instance I'm using, therefore can't guarantee the plugin is available.

// Webpacker environment.js config

const { environment } = require('@rails/webpacker');
const path = require('path');
const webpack = require('webpack');

environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [
    {
      loader: 'expose-loader',
      options: 'jQuery'
    },
    {
      loader: 'expose-loader',
      options: '$'
    }
  ]
});

environment.plugins.append(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
);


module.exports = environment;

推荐答案

我已经成功完成了splitChunks,它强制jquery的单个实例与您所描述的exports-loader配置相结合.

I have had success with splitChunks forcing a single instance for jquery combined with the exports-loader config like you have described.

这是我使用的Webpack配置的关键部分:

Here's the key part of the Webpack config I'm using:

environment.splitChunks((config) => {
  return Object.assign({}, config, {
    optimization: {
      splitChunks: {
        chunks: 'all',
        name: true,
        cacheGroups: {
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
          },
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
          },
        },
      },
    },
  })
})

这里的关键是要了解Webpack splitChunks取代了手动代码拆分的需要.换句话说,无需显式创建core.jsvendor.js包;将所有导入合并为application.js依赖关系树的一部分. 让Webpack为您完成代码拆分.

The key here is to understand that Webpack splitChunks replaces the need for manual code splitting. In other words, let go of the need to explicitly create core.js and vendor.js packs; consolidate all your imports as part of the application.js dependency tree. Let Webpack do the code-splitting for you.

要提的另一点警告是,Webpacker对splitChunks的实现意味着在视图中放置一个javascript_packs_with_chunks_tag,以便共享的运行时"块将确保不会复制像jQuery这样的模块.

Another caveat to mention is that Webpacker's implementation of splitChunks means placing a single javascript_packs_with_chunks_tag in the view so that the shared "runtime" chunk will ensure that modules, like jQuery, aren't duplicated.

在以前的项目中,我以前曾像Sprockets一样手动拆分捆绑包.当我不得不自己迁移到Webpack时,这种新方法花了一段时间.我作了一个演讲,这将使我在这里的答案更加清楚: https://youtu.be/fKOq5_2qj54?t=185

I used to split my bundles manually like you in my previous projects with Sprockets. When I had to do my own migration to Webpack, it took awhile for this new approach to sink in. I gave a talk about it which will shed some more light on my answer here: https://youtu.be/fKOq5_2qj54?t=185

这篇关于如何跨多个Webpack包共享jQuery的同一实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆