Webpack ProvidePlugin vs externals?

Hen*_*nry 81 amd requirejs backbone.js webpack

我探索使用的想法的WebPackBackbone.js的.

我已经按照快速入门指南了解了Webpack的工作原理,但我不清楚如何加载依赖库,如jquery/backbone/underscore.

它们应该在外部加载<script>吗?或者这是Webpack可以处理的东西,如RequireJS的垫片?

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

谢谢

Tob*_* K. 148

这两种可能性:您可以包含库<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");
Run Code Online (Sandbox Code Playgroud)

包中包含库的示例:

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");
Run Code Online (Sandbox Code Playgroud)

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

示例没有ProvidePlugin:

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

示例ProvidePlugin:

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

// If you use "_", underscore is automatically required
_.size(...)
Run Code Online (Sandbox Code Playgroud)

摘要:

  • 来自CDN的图书馆:使用<script>标签和externals选项
  • 来自文件系统的库:在库中包含库.(也许修改resolve选项来查找库)
  • externals:使全局变量可用作模块
  • ProvidePlugin:使模块可用作模块内的自由变量

  • 只需将绝对路径传递给别名选项即可.如果你传递一个相对路径它相对于webpack中的require/import的位置1.在webpack 2中它相对于webpack.config.js文件resp.上下文选项. (3认同)

dto*_*efp 24

值得注意的是,如果你使用ProvidePluginexternals属性的组合,它将允许你jQuery传递到你的webpack模块闭包,而不必明确require它.这对于使用大量不同文件引用重构遗留代码非常有用$.

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

现在在index.js

console.log(typeof $ === 'function');
Run Code Online (Sandbox Code Playgroud)

将有一个编译输出与下面的东西传递到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;

/***/ }
/******/ ])
Run Code Online (Sandbox Code Playgroud)

因此,您可以看到它$正在引用jQueryCDN中的全局/窗口,但正被传递到闭包中.我不确定这是否是预期的功能或幸运的黑客,但它似乎适用于我的用例.


dto*_*efp 11

我知道这是一篇很老的帖子,但我认为在这种情况下提及webpack脚本加载器可能会很有用.来自webpack文档:

"script:在全局上下文中执行一次JavaScript文件(比如在脚本标记中),不需要解析需求."

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

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

我发现这在迁移将JS供应商文件和应用程序文件连接在一起的旧构建过程时特别有用.一句警告是,脚本加载器似乎只能通过重载require()工作,并且在我在webpack.config文件中指定时无法正常工作.尽管许多人认为重载require是不好的做法,但是在一个捆绑包中同意供应商和应用程序脚本非常有用,同时暴露出JS Globals,而不必将其整合到其他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');
Run Code Online (Sandbox Code Playgroud)

这将使$ .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"])
   )
]
Run Code Online (Sandbox Code Playgroud)

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