我希望我的webpack编译库成为函数的返回值。
通过将我的配置文件中的libraryTarget
设置为var
,Webpack将允许我编译输出和assign the result to a variable,给我这样的内容:
var MyLibrary = function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,expo...;
如果我只是在我的网页中按原样包含此输出文件,我最终会得到window.MyLibrary
,这与我之后的情况不同,但越来越接近。
我有一个高级用例(如果不写一本关于它的书,很难完全解释)。我只想说,我更愿意通过一个函数“初始化”库,如下所示:
function init(){
return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,expo...;
}
我原本希望在这些行中找到libraryTarget
option,但唉,文档中似乎没有。{/ p>
我是否应该使用其他构建工具将我的输出文件连接到另一个文件,例如模板?或者webpack中有一个我忽略的功能吗?也许这个结果可以通过使用其他几个高级功能来实现?我并不反对插件,但显然我更喜欢原生功能。
这是我想要完成的更全面的例子。
utils.js
let d = new Date();
export default {
getInitDateTime(id){
return d;
}
};
lib.js
import utils from "./utils.js";
export let lib = ({
test: function(){
return utils.getInitDateTime();
}
});
webpack.config.js
const path = require('path');
module.exports = {
mode: 'production',
entry: './lib.js',
output: {
filename: 'bundle.js',
libraryTarget: 'var',
libraryExport: 'lib',
library: 'mylib',
}
};
bundle.js (已编译)
var mylib=function(e){var t={};function n(r){if(t[r])return t[r].exports;var u=t[r]={i:r,l:!1,exports:{}};return e[r].call(u.exports,u,u.exports,n),u.l=!0,u.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);let r=new Date;var u={getInitDateTime:e=>r};n.d(t,"lib",function(){return o});let o={test:function(){return u.getInitDateTime()}}}]).lib;
的index.html
<html>
<head></head>
<body>
<button id="btn">Click Me</button>
<div id="root"></div>
<script src="dist/bundle.js"></script>
<script>
var btn = document.getElementById('btn');
var root = document.getElementById('root');
btn.onclick = function(){
var div = document.createElement('div');
div.innerHTML = 'Test: ' + mylib.test();
root.appendChild( div );
}
</script>
</body>
</html>
如果您点击按钮三次,则会出现以下情况:
测试:2018年5月8日2018 10:28:41 GMT-0400(美国东部时间)
测试:周五08年8月8日2018 10:28:41 GMT-0400(美国东部时间)
测试:2018年5月8日2018 10:28:41 GMT-0400(美国东部时间)
以下是我喜欢在index.html
中使用我的库的方式:
<html>
<head></head>
<body>
<button id="btn">Click Me</button>
<div id="root"></div>
<script src="dist/bundle.js"></script>
<script>
var btn = document.getElementById('btn');
var root = document.getElementById('root');
btn.onclick = function(){
// ******************************************
// Create a new instance of the library:
var mylib = initmylib();
// ******************************************
var div = document.createElement('div');
div.innerHTML = 'Test: ' + mylib.test();
root.appendChild( div );
}
</script>
</body>
</html>
所以如果我点击我的按钮三次,我会得到类似的东西:
测试:2018年5月8日星期二08:40:41 GMT-0400(美国东部时间)
测试:2018年5月8日2018 10:40:42 GMT-0400(美国东部时间)
测试:2018年5月8日2018 10:40:43 GMT-0400(美国东部时间)
我已经可以通过手动修改我的bundle.js
来完成此操作:
function initmylib(){
return function(e){var t={};function n(r){if(t[r])return t[r].exports;var u=t[r]={i:r,l:!1,exports:{}};return e[r].call(u.exports,u,u.exports,n),u.l=!0,u.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);let r=new Date;var u={getInitDateTime:e=>r};n.d(t,"lib",function(){return o});let o={test:function(e,t){return u.getInitDateTime()}}}]).lib;
}
但这需要手动修改或额外的构建步骤。我想知道webpack是否可以自己做这样的事情。
显然,这个特殊的库是微不足道的,我可以很容易地重构它以按照需要行事。问题是我的真实图书馆大约有5到6年的历史,有数十万行代码分布在数百个文件中,并且在现有产品中被广泛使用。我正在尝试慢慢迁移它,我想使用webpack来实现它。预先重构所有将会非常耗时。如果我可以简单地将bundle包装在一个函数中(如图所示),它将很快解决很多问题。
我可以使用额外的构建步骤来实现我的目标...我只想知道webpack是否可以为我做。
答案 0 :(得分:0)
我认为webpack不能自动为您调用该功能。 webpack第一次看到你的模块时,它会获得导出并缓存它。在后续导入中,它从缓存中返回。
但你可以尝试这样的事情:
export default function createLibraryInstance () {
let myPrivateValue = 1;
return {
getValue: function () {
return myPrivateValue;
}
}
}
然后在webpack配置中:
{
output: {
library: 'createLibraryInstance',
libraryTarget: 'var'
}
}
像这样使用它:
let myInstance = window.createLibraryInstance();