87

我正在探索将WebpackBackbone.js一起使用的想法。

我遵循了快速入门指南,并对 Webpack 的工作原理有了大致的了解,但我不清楚如何加载依赖库,如 jquery / 主干 / 下划线。

它们应该从外部加载<script>还是 Webpack 可以像 RequireJS 的 shim 一样处理?

根据webpack doc: shimming modulesProvidePlugin并且externals似乎与此有关(bundle!某处的 loader 也是如此),但我不知道何时使用哪个。

谢谢

4

3 回答 3

159

两者皆有可能:您可以<script>使用 a 包含库(即使用 CDN 中的库)或将它们包含到生成的包中。

如果您通过<script>标签加载它,您可以使用externals允许写入require(...)模块的选项。

来自 CDN 的库示例:

<script src="https://code.jquery.com/jquery-git2.min.js"></script>

// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }

// inside any module
var $ = require("jquery");

捆绑包中包含库的示例:

copy `jquery-git2.min.js` to your local filesystem

// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }

// inside any module
var $ = require("jquery");

可以将ProvidePlugin模块映射到(自由)变量。所以你可以定义:“每次我xyz在模块中使用(免费)变量时,你(webpack)都应该设置xyzrequire("abc")。”

没有的例子ProvidePlugin

// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);

示例ProvidePlugin

plugins: [
  new webpack.ProvidePlugin({
    "_": "underscore"
  }) 
]

// If you use "_", underscore is automatically required
_.size(...)

概括:

  • CDN 中的库:使用<script>标签和externals选项
  • 来自文件系统的库:将库包含在包中。(也许修改resolve选项以找到库)
  • externals: 使全局变量作为模块可用
  • ProvidePlugin: 使模块可作为模块内的自由变量使用
于 2014-04-29T19:58:09.517 回答
26

值得注意的是,如果您将ProvidePluginexternals属性结合使用,它将允许您jQuery传递到您的 webpack 模块闭包而无需显式地传递require它。这对于重构具有许多不同文件引用的遗留代码很有用$

//webpack.config.js
module.exports = {
  entry: './index.js',
  output: { 
    filename: '[name].js' 
  },
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
    })
  ]
};

现在在 index.js

console.log(typeof $ === 'function');

将有一个编译输出,如下所示传递给webpackBootstrap闭包:

/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    /* WEBPACK VAR INJECTION */(function($) {
        console.log(typeof $ === 'function');

    /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

    module.exports = jQuery;

/***/ }
/******/ ])

因此,您可以看到它$正在从 CDN 引用全局/窗口jQuery,但正在被传递到闭包中。我不确定这是预期的功能还是幸运的 hack,但它似乎对我的用例很有效。

于 2015-06-02T04:18:33.893 回答
11

我知道这是一篇旧文章,但我认为在这种情况下提及 webpack 脚本加载器可能也很有用。来自 webpack 文档:

“脚本:在全局上下文中执行一次 JavaScript 文件(如在脚本标签中),不解析要求。”

http://webpack.github.io/docs/list-of-loaders.html

https://github.com/webpack/script-loader

我发现这在迁移将 JS 供应商文件和应用程序文件连接在一起的旧构建过程时特别有用。一个警告是脚本加载器似乎只能通过重载require()工作,据我所知,通过在 webpack.config 文件中指定它不能工作。虽然,许多人认为重载require是不好的做法,但它对于将供应商和应用程序脚本连接到一个包中非常有用,同时暴露 JS 全局,不必填充到额外的 webpack 包中。例如:

require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');

require('./scripts/main.js');

这将使 $.cookie、History 和 moment 在此捆绑包内部和外部全局可用,并将这些供应商库与 main.js 脚本及其所有required 文件捆绑在一起。

此外,此技术的有用之处在于:

resolve: {
  extensions: ["", ".js"],
  modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
  new webpack.ResolverPlugin(
    new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
   )
]

使用 Bower,将查看main每个required 库 package.json 中的文件。在上面的示例中,History.js 没有main指定文件,因此文件的路径是必需的。

于 2015-01-25T22:14:24.947 回答