Webpack:避免多个 jquery 实例

aim*_*eld 7 javascript jquery webpack

我们目前正在重构我们的代码库以使用 webpack,但是我们遇到了 jQuery 的问题。例如,在一个 js 文件中触发的更改事件不会再在其他 js 文件中监听。

看起来 jQuery 被实例化了多次。当我$.expando在 js 文件中查看触发更改事件时,它与$.expando附加事件侦听器的 js 文件中不同。这两个js文件属于不同的webpack入口点,我怀疑jQuery是为每个入口点单独实例化的。

所以我想问题是我们如何在多个入口点之间共享单个 jQuery 实例?我怀疑使用单个 jQuery 实例可以解决事件侦听器问题。

此外,看起来整个 jQuery 代码在 webpack 生成的每个 js 文件中都是重复的。我们的 webpack 设置肯定有问题。另外,我不确定我们是否应该有这么多入口点。

这是我们的 webpack 配置:

const webpack = require('webpack');
const path = require('path');

const Dotenv = require('dotenv-webpack');
const ManifestPlugin = require('webpack-manifest-plugin');
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin');
const WebpackWatchedGlobEntries = require('webpack-watched-glob-entries-plugin');

const distPath = path.resolve(__dirname, 'public');
const globEntries = require('./entry-globs');

module.exports = {
  entry: WebpackWatchedGlobEntries.getEntries(
    globEntries.globs, {
      ignore: globEntries.ignore
    }
  ),
  output: {
    path: distPath,
    filename: '[name].[chunkhash:4].js'
  },
  watchOptions: {
    poll: true // to make it work with vagrant
  },
  module: {
    rules: [{
      test: require.resolve('jquery'),
      use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },
        {
          loader: 'expose-loader',
          options: '$'
        }
      ]
    }]
  },
  resolve: {
    alias: {
      surveylabJsAssets: path.resolve(__dirname, './vendor/cloud-solutions/surveylab/assets/js'),
    }
  },
  plugins: [
    new WebpackWatchedGlobEntries(),
    new Dotenv(), // used to access .env vars eg: process.env.SENTRY_API_KEY
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new ManifestPlugin({
      fileName: 'manifest.js.json',
      publicPath: '/',
      basePath: '/',
    }),
    // clean the plugin just for the js dist folder since we handle the other assets with gulp
    new CleanWebpackPlugin({
      // Simulate the removal of files. default: false. Set to true to test the cleanOnceBeforeBuildPatterns
      //dry: true,
      cleanOnceBeforeBuildPatterns: ['js/*', 'manifest.js.json']
    }),
  ]
};
Run Code Online (Sandbox Code Playgroud)