Webpack 网页包是否有类似“图书馆目标”的东西;功能;?

Webpack 网页包是否有类似“图书馆目标”的东西;功能;?,webpack,es6-modules,Webpack,Es6 Modules,我希望我的webpack编译库是函数的返回值 Webpack将允许我编译输出,通过将配置文件中的libraryTarget设置为var,我可以得到如下结果: 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...; function init(){ return function(e){var t={};function r(n

我希望我的webpack编译库是函数的返回值

Webpack将允许我编译输出,通过将配置文件中的
libraryTarget
设置为
var
,我可以得到如下结果:

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...;
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...;
}
  export default function createLibraryInstance () {
    let myPrivateValue = 1;

    return {
      getValue: function () {
        return myPrivateValue;
      }
    }
  }
  let myInstance = window.createLibraryInstance();
如果我只是在我的网页中按原样包含这个输出文件,我最终得到的是
window.MyLibrary
,这并不完全是我想要的,但越来越近了

我有一个高级用例(如果不写一本书就很难完全解释)。我更愿意通过函数“初始化”库,如下所示:

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...;
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...;
}
  export default function createLibraryInstance () {
    let myPrivateValue = 1;

    return {
      getValue: function () {
        return myPrivateValue;
      }
    }
  }
  let myInstance = window.createLibraryInstance();
我曾希望找到一个类似的方法,但可惜的是,文档中似乎没有这样的方法

我是否应该使用其他构建工具将我的输出文件连接到另一个文件,即模板?或者网页中是否有我忽略的功能?也许通过同时使用其他几个高级功能可以实现这个结果?我并不反对插件,但显然我更喜欢原生功能


这里有一个更全面的例子,说明我想完成的任务

现行代码 utils.js

let d = new Date();

export default {
    getInitDateTime(id){
        return d;
    }
};
import utils from "./utils.js";

export let lib = ({
    test: function(){
        return utils.getInitDateTime();
    }
});
const path = require('path');

module.exports = {
    mode: 'production',
    entry: './lib.js',
    output: {
        filename: 'bundle.js',
        libraryTarget: 'var',
        libraryExport: 'lib',
        library: 'mylib',
    }
};
lib.js

let d = new Date();

export default {
    getInitDateTime(id){
        return d;
    }
};
import utils from "./utils.js";

export let lib = ({
    test: function(){
        return utils.getInitDateTime();
    }
});
const path = require('path');

module.exports = {
    mode: 'production',
    entry: './lib.js',
    output: {
        filename: 'bundle.js',
        libraryTarget: 'var',
        libraryExport: 'lib',
        library: 'mylib',
    }
};
webpack.config.js

let d = new Date();

export default {
    getInitDateTime(id){
        return d;
    }
};
import utils from "./utils.js";

export let lib = ({
    test: function(){
        return utils.getInitDateTime();
    }
});
const path = require('path');

module.exports = {
    mode: 'production',
    entry: './lib.js',
    output: {
        filename: 'bundle.js',
        libraryTarget: 'var',
        libraryExport: 'lib',
        library: 'mylib',
    }
};
bundle.js(已编译)

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日星期二10:40:41 GMT-0400(美国东部时间)
测试:2018年5月8日星期二10:40:42 GMT-0400(美国东部时间)
测试:2018年5月8日星期二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是否可以自己做类似的事情

是的,这个MCVE很小。。。我真正的图书馆不是。 显然,这个特定的库很简单,我可以很容易地重构它,使其按需要运行。问题是,我真正的库大约有5-6年的历史,有数十万行代码分布在数百个文件中,并且在现有产品中被积极使用。我正在尝试慢慢地迁移它,我想用webpack来完成。提前重构所有内容将非常耗时。如果我可以简单地将bundle包装成一个函数(如演示的那样),它将很快解决很多问题


我可以使用额外的构建步骤来实现我的目标。。。我只是想知道webpack是否可以为我做这件事。

我认为webpack无法自动为您调用该功能。webpack第一次看到您的模块时,会获取导出并缓存它。在后续导入时,它从缓存返回

但您可以尝试以下方法:

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...;
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...;
}
  export default function createLibraryInstance () {
    let myPrivateValue = 1;

    return {
      getValue: function () {
        return myPrivateValue;
      }
    }
  }
  let myInstance = window.createLibraryInstance();
然后在网页包配置中:

  {
    output: {
      library: 'createLibraryInstance',
      libraryTarget: 'var'
    }
  }
像这样使用它:

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...;
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...;
}
  export default function createLibraryInstance () {
    let myPrivateValue = 1;

    return {
      getValue: function () {
        return myPrivateValue;
      }
    }
  }
  let myInstance = window.createLibraryInstance();

您是否尝试过将模块导出作为函数并将libraryTarget设置为var?部分问题在于模块导出由所有导入者共享,这很好。。。但是,如果我希望库的第二个实例具有自己的副本/实例,那么我必须显著增加库的复杂性以支持多个实例。通过将所有内容包装到函数中,我可以利用JS作用域并“免费”获得该行为。谢谢。。。我更新了我的问题,以展示我期望的结果,并解释为什么这种方法不理想。