我正在探索将Webpack与Backbone.js一起使用的想法。
我已经按照快速入门指南了解了Webpack的工作原理,但我不清楚如何加载依赖库,如jquery / backbone / underscore。
它们是否应该在<script>
外部加载,或者这是Webpack可以像RequireJS的垫片一样处理的东西吗?
根据webpack doc: shimming modules,ProvidePlugin
和externals
似乎与此相关(某处的bundle!
加载器也是如此),但我无法弄清楚何时使用哪个。
由于
答案 0 :(得分:146)
这两种可能性:您可以包含<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
设置为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(...)
要点:
<script>
代码和externals
选项resolve
选项以查找库)externals
:将全局变量作为模块提供ProvidePlugin
:将模块作为模块内的自由变量提供答案 1 :(得分:21)
值得注意的是,如果将ProvidePlugin
与externals
属性结合使用,它将允许您将jQuery
传递到您的webpack模块闭包中而无需显式{ {1}}它。这对于使用引用require
的许多不同文件重构遗留代码非常有用。
$
现在在index.js
//webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: '[name].js'
},
externals: {
jquery: 'jQuery'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
})
]
};
将有一个编译输出,如下所示传递到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中的全局/窗口$
,但正被传递到闭包中。我不确定这是否是预期的功能或幸运的黑客,但它似乎适用于我的用例。
答案 2 :(得分: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');
这将使$ .cookie,History和moment在这个包内外全局可用,并将这些供应商库与main.js脚本及其所有require
d文件捆绑在一起。
此外,这项技术很有用:
resolve: {
extensions: ["", ".js"],
modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
正在使用Bower的将查看每个main
d库package.json中的require
文件。在上面的示例中,History.js没有指定main
文件,因此需要该文件的路径。