Webpack ProvidePlugin与外部?


84

我正在探索将WebpackBackbone.js结合使用的想法。

我遵循了快速入门指南,对Webpack的工作原理有一个大致的了解,但是我不清楚如何加载依赖库,例如jquery / boneer / underscore。

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

按照的WebPack DOC:垫补模块ProvidePlugin并且externals似乎与此有关(因此是bundle!装载机的地方),但我不能想出什么时候使用。

谢谢

Answers:


153

两者都有:您可以在库中包含一个<script>(即使用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)应该设置xyz为的模块内使用(free)变量时require("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:使模块作为模块内部的自由变量可用

应该newwebpack.ProvidePlugin webpack.github.io/docs/list-of-plugins.html
MK Yung

为什么不只使用脚本加载器呢?这要容易得多,就像@dtothefp所做的解释一样
timaschew

如果我的webpack.config文件在一个名为javascript的文件夹中,并且在其中有一个名为jerry文件的名为vendor的文件夹。路径应该不是。解决:{别名:{jquery:“ vendor / jquery-1.10.2.js”}}。使用别名仍然对我不起作用
me-me,

3
只需将绝对路径传递给alias选项。如果传递相对路径,则它相对于webpack 1中require / import的位置。在webpack 2中,它相对于webpack.config.js文件相对。上下文选项。
Tobias K.

@TobiasK。绝对路径与默认导出不配合。我正在获取一个对象,{__esModule: true, default: MY_DEFAULT_EXPORT}而不是MY_DEFAULT_EXPORT在文件中。
mgol 16/09/22

25

需要注意的一件很酷的事是,如果您将ProvidePlugin结合使用和externals属性,它将使您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,但是正在传递给闭包。我不确定这是预期的功能还是幸运的破解,但对于我的用例来说似乎效果很好。


如果您不打算使用任何插件,都不需要require/import$之所以会奏效,是因为无论如何它都会扩展到全球范围。在ProviderPlugin需要解析AST所以这是一个昂贵的插件,并会添加到您的构建时间明显。因此,这基本上是一种浪费。
faceyspacey.com

@dtohefp这个答案真是天赐。除非我将模块添加到外部ProvidePluginmyModule.default否则您能否解释为什么返回类似的对象?我从来不知道会有任何直接的关系。
Slbox

11

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

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

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

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

在迁移将JS供应商文件和应用程序文件连接在一起的较早的构建过程时,我发现这特别有用。值得一提的是,脚本加载器似乎只能通过重载来工作,require()而据我所知,在webpack.config文件中指定该脚本加载器就无法工作。尽管许多人认为重载require是不好的做法,但对于将供应商和应用程序脚本打包到一个捆绑包中,同时将不必将其填充到其他webpack捆绑包中的JS Globals暴露出来,它可能非常有用。例如:

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,历史记录和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指定文件,因此该文件的路径是必需的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.