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

标签 javascript webpack gulp lodash

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

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

{
   externals: {
       "lodash"
   }
}

它工作得很好。
但是当我想在另一个项目中使用这个库时,我得到了以下错误:“libraryjs.js:77 Uncaught ReferenceError: lodash is not defined”

这是以下行:
/***/ }),
/* 1 */
/***/ (function(module, exports) {

=> module.exports = lodash;

/***/ }),

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

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

编辑:我找到了修复错误的方法,但我真的不想坚持这个修复,因为它真的......丑陋......见下文:
const lodash = require('lodash')
window.lodash = lodash; // <= The fix, ugh

感谢您的帮助!

最佳答案

我在尝试建立一个库时遇到了类似的情况——这是我找到的解决方案。

目标:
构建一个依赖 Lodash 的库,而不在该库包中包含 Lodash。
图书馆的消费者负责使 Lodash 可用于我们的图书馆。

我用了Authoring Libraries文档的部分以组合此解决方案。

具体这两个部分:

  • Externalize Lodash
  • Expose the Library

  • 有一个示例项目也显示了此配置:
    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 项目加载时可以工作)。注意:这是必需的,否则 externals [3] 中的配置将输出不正确的 undefined包中的模块。

    [2] Webpack 4 错误的解决方法(如果您在 future ,请检查这是否仍然相关和需要)。也在这里描述:https://stackoverflow.com/a/49119917/81723

    [3] 来自文档:“设置 externals 选项以定义应在目标环境中解决的依赖关系”。我们告诉 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 config 表示任何时候 Webpack 遇到 require('lodash')import ... from "lodash";它会将其解析为磁盘上的这一模块。我发现我必须这样做以避免将多个版本的 lodash 加载到我的包中。 Webpack 包含一个用于 my-app 的版本一个用于 my-lib ,但这修复了它,以便两者都获得相同的版本。

    关于javascript - 使用 webpack 和 lodash 作为依赖捆绑自定义库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47773160/

    相关文章:

    javascript - 为什么我无法渲染 View 的两个实例?

    plugins - 如何编写一个 Webpack 插件来按需生成 index.js 文件?

    javascript - Internet Explorer 11 不支持滚动方法

    gulp - 为什么 gulp-livereload 崩溃并出现错误 : listen EADDRINUSE?

    wordpress - 构建文件夹应该包含在 git repo 中吗?

    javascript - 什么是 gulp 任务异步运行提示?

    javascript - Onchange 不触发

    javascript - 未捕获的索引大小错误 : Failed to execute 'getRangeAt' on 'Selection' : 0 is not a valid index

    javascript - 从字符串中找到最接近 0 的数字?

    vue.js - 如何使用 Vue.js SPA 将索引机器人重定向到不同的路由,以服务器渲染页面以便它们被抓取和索引?