0

最近,我一直在考虑将我们的构建过程Gruntwebpack-2. 我们的代码完全使用 requirejs 以 AMD 格式编写。出于演示的目的,我将发布index.js我们正在使用的文件的简约版本。

这是通过提交文件并通过 npm 加载的 jQuery-1.6.4 的链接。请暂时原谅。jQuery-1.6.4

index.js

define(['jQuery', 'arrayUtils'], function ($, arrayUtils) {
  'use strict';
  console.log($); 
  console.log(arrayUtils);

});

对应require-config.js文件:

(function () {
    'use strict';

    require.config({
        baseUrl: '../../src',
        waitSeconds: 0,
        paths: {
            jQuery: '/path to/jquery-1.6.4',
            urlUtils: '/path to/urlUtils',
            // ...
        },
        shim: {
            jQuery: {
                exports: '$'
            },
            urlUtils: {
                exports: 'urlUtils'
            },
            // ...
        }
    });
})();

我尝试使用我们的 AMD 方法,但想使用 webpack-2 捆绑所有内容。我浏览了文档和各种博客,发现了使所有东西都像一个魅力一样工作的配置,除了旧的黄金 jQuery。

这里是webpack.config.js

var webpack = require('webpack');
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

// Import the plugin:
var path = require('path');
var env = require('yargs').argv.mode;
var outputFile;

var options = {
  target: 'this'
};
var libOptions = {
  name: 'heatmap-inject',
  version: JSON.stringify(require("./package.json").version)

};

var plugins = [];


if (env === 'build') {
  plugins.push(new UglifyJsPlugin({
    sourceMap: true,
    minimize: true
  }));
}

// At the end of the file:
module.exports = {
  entry: __dirname + '/src/library.js',
  devtool: 'source-map',
  output: {
    path: __dirname + '/dist/webpack',
    library: 'library.js',
    filename: libOptions.name + '.js', // libOptions.name + (options.target ? '.' + options.target : '') + (env === 'build' ? '.min.js' : '.js')
    libraryTarget: options.target || 'umd',
    umdNamedDefine: true
  },
  module: {
    rules: [{
      test: /(\.js)$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['es2015'],
          plugins: []
        }
      }
    }, {
      enforce: 'pre',
      test: /(\.js)$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'eslint-loader',
        options: {}
      }
    }, { test: /jQuery/, loader: 'exports-loader?$'
    }, { test: /urlUtils/, loader: 'exports-loader?urlUtils'
    }]
  },
  resolve: {
    alias: {
     'jQuery': 'heatmaps/vendor/jquery-1.6.4',
     'urlUtils': 'lib/heatmap/UrlUtils'
    },
    modules: [
      'src/**/*.js',
      'src/bower_components',
      path.resolve('./src')
    ],
    extensions: ['.js']
  },
  plugins: plugins
};

生成的文件会webpack-2抛出一个未定义的错误,$.fn即它不是$一个 jQuery 函数,而是一个普通的空对象。虽然 window.$ 已定义并返回正确的 jQuery 函数,但为什么我没有得到相同的结果$。在 AMD 的情况下,我得到了正确的结果,因为$它处于闭包中并返回 1.6.4 jQuery。使用 webpack,它的行为很奇怪。

!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1), __webpack_require__(13) ], __WEBPACK_AMD_DEFINE_RESULT__ = function ($, urlUtils) { ... }

我还尝试了哪些其他方法:

  1. { test: /jQuery/, loader: 'expose-loader?$'
  2. { test: /jQuery/, loader: 'exports-loader?jQuery=jQuery,$=jQuery,this=>window'
  3. { test: /jQuery/, loader: 'exports-loader?this=>window'
  4. { test: /jQuery/, loader: 'expose-loader?$=jQuery'

不能使用externals属性,因为它会污染 thw window.jQuery,并且由于该库被注入/加载到用户的网站上,这将破坏目标源上的内容。

请帮我!我现在对这个奇怪的 jQuery 事情感到沮丧。

4

2 回答 2

1

这可能是因为您使用的 jQuery 版本在 jQuery AMD 修复之前。使用 jQuery 2.2.1 和 3.0,我将一些大型 AMD 代码库移植到 ES 模块。我曾经在构建环境中解决 jQuery 的 jankiness 的主要堆栈溢出帖子是jhhns 本人的这个非常彻底的答案

解决方案的关键,特别是如果您在 jQuery 之上使用 jQuery UI,则使用提供插件,然后有一个“插件”模块来导入您需要的特定模块。特别是如果他们有特定的订单,他们需要在相关应用程序的其余部分加载。

使用 ES 模块(AMD 也可以):

// jquery-plugins.js
// import $ from 'jquery' is implicit because of the provide plugin
import 'jquery-ui'
import 'malihu-custom-scrollbar'
import 'datatables'

为所有依赖项首先(或接近第一个)导入此模块将为您提供以后需要的 jQuery 命名空间。

于 2017-05-23T20:49:42.837 回答
0

我在我的遗留代码中使用 jQuery 1.9.1 并将其与 Webpack 4 捆绑在一起。我遇到了类似的问题。

经过一整天的挣扎,通过遵循@SamirAguiar 的解决方案和https://webpack.js.org/configuration/other-options/#amd,我在我的 webpack 配置中找到了一种可行的方法:

{
  resolve: {
    alias: {
      'jquery': 'jquery/jquery', // -> node_modules/jquery/jquery.js
      // ...
    },
  },
  amd: {
    jQuery: true
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery', // legacy code tend to use $ without requiring it
      jQuery: 'jquery'
    }),
    // ...
  ]
}

这适用于 jquery-ui 1.10.3 和其他一些基于 jQuery 的插件。

于 2018-06-14T08:26:40.363 回答