使用webpack和lodash捆绑自定义库作为依赖项

时间:2017-12-12 12:53:08

标签: javascript webpack gulp lodash

我需要帮助。 我正在捆绑一个自定义库(以示例 LibraryJS 命名,它使用lodash作为依赖。

在webpack配置中,我将lodash设置为外部依赖,如下所示:

{
   externals: {
       "lodash"
   }
}

效果很好。 但是当我想在另一个项目中使用这个库时,我收到以下错误:“ libraryjs.js:77 Uncaught ReferenceError:lodash未定义

这是以下一行:

/***/ }),
/* 1 */
/***/ (function(module, exports) {

=> module.exports = lodash;

/***/ }),

事实是,我在我的项目中也使用lodash,所以它应该正常工作。 我做错了什么?

顺便说一句,我使用gulp + browserify捆绑我的项目和gulp + gulp-webpack来捆绑库。

编辑:我发现了一种修复错误的方法,但我真的不想坚持这个修复,因为它真的......丑陋......见下文:

const lodash = require('lodash')
window.lodash = lodash; // <= The fix, ugh

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

我有类似的情况试图建立一个库 - 这是我找到的解决方案。

<强>目标: 构建一个依赖于Lodash的库,而不在该库包中包含Lodash。 图书馆的消费者负责向我们的图书馆提供Lodash。

我使用文档的Authoring Libraries部分来整理此解决方案。

特别是这两个部分:

还有一个显示此配置的示例项目: https://github.com/webpack/webpack/tree/master/examples/externals

解决方案:

1。捆绑我们的库,不包括lodash

// "my-lib" package.json
{
    "name": "my-lib",
    "version": "0.5.0",
    "main": "my-lib.js",
    "peerDependencies": {
        "lodash": "^4.17.5"
    },
    "devDependencies": {
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14"
    }
}

这是我们导入lodash并使用它的示例库。请注意,虽然我们依赖于lodash,但它不会包含在我们的捆绑包中。

// lib-entry.js
import _ from "lodash";

export default function doubleUp(listOfNum){
    // Do something using lodash
    let result = _.flatMap(listOfNum, (i) => [i, i]);
    return result;
}

这是我们的webpack.config.js捆绑我们的图书馆,但不包括lodash:

// "my-lib" webpack.config.js
module.exports = {
    entry: {
        'my-lib': './lib-entry.ts', 
    },
    output: {
        filename: '[name].js',

        // [1]
        libraryTarget: 'umd',

        /*
        [2]
        NOTE: until this issue is fixed: https://github.com/webpack/webpack/issues/6525
        we need to define `globalObject` in Webpack 4 to correctly build a universal library
        (i.e. node and browser compatible).
        */
        globalObject: 'this',
    },
    externals: {
        // [3]
        'lodash': {
            commonjs: 'lodash',
            commonjs2: 'lodash',
            amd: 'lodash',
            root: '_',
        },
    },
    resolve: {
        extensions: ['.js'],
    },
};

[1]这告诉Webpack将我们的库捆绑到不同的环境中(因此它在通过以下方式加载时可以工作:浏览器脚本,Node CommonJS,AMD和下游Webpack项目)。注意:这是必需的,否则[3]中的externals配置将在您的包中输出不正确的undefined模块。

[2] Webpack 4错误的解决方法(如果您将来再检查这是否仍然相关且需要)。此处还介绍了:https://stackoverflow.com/a/49119917/81723

[3]从文档中:&#34;设置externals选项以定义应在目标环境中解决的依赖关系&#34;。我们告诉Webpack将lodash从库包中排除,并且我们库的消费者负责提供它。

2。在下游应用程序中使用库

定义依赖于my-lib库的应用程序:

// "my-app" package.json
{
    "name": "my-app",
    "version": "1.0.0",
    "dependencies": {
        "lodash": "^4.17.5",
        "my-lib": "^0.5.0"
    },
    "devDependencies": {
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14"
    }
}

我们的应用程序将lodash导入其环境(因为我们的库需要它),然后使用我们的库:

// app-entry.js
import _ from "lodash";
import doubleUp from "my-lib";

let result = doubleUp([1, 2, 3]);
console.log(result);    // [1, 1, 2, 2, 3, 3]

这里是我们申请的webpack.config.js

// "my-app" webpack.config.js
const path = require('path');

module.exports = {
    entry: {
        'my-app': './app-entry.ts', 
    },
    output: {
        filename: '[name].js',
    },
    resolve: {
        extensions: ['.js'],
        alias: {
            /*
            [1]
            Resolve all `lodash` requests to the same location otherwise
            we end up with two versions loaded into the bundle, one
            for `my-lib` and one for `my-app`.
            */
            lodash: path.resolve('./node_modules/lodash/index.js'),
        }
    },
};

[1]这个alias配置意味着任何时候Webpack遇到require('lodash')import ... from "lodash";它都会将其解析为磁盘上的这个模块。我发现我必须这样做以避免将多个版本的lodash加载到我的包中。 Webpack包含my-app的一个版本和my-lib的一个版本,但这样做会修复它以便两者都获得相同的版本。