webpack是否具有类似“function”的libraryTarget?

时间:2018-05-07 21:35:40

标签: webpack es6-modules

我希望我的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是否可以自己做这样的事情。

是的,这个MCVE是微不足道的......我的真实图书馆不是。

显然,这个特殊的库是微不足道的,我可以很容易地重构它以按照需要行事。问题是我的真实图书馆大约有5到6年的历史,有数十万行代码分布在数百个文件中,并且在现有产品中被广泛使用。我正在尝试慢慢迁移它,我想使用webpack来实现它。预先重构所有将会非常耗时。如果我可以简单地将bundle包装在一个函数中(如图所示),它将很快解决很多问题。

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

1 个答案:

答案 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();