最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bundle custom library using webpack and lodash as dependency - Stack Overflow

programmeradmin0浏览0评论

I need help here. I am bundling a custom library (named for the example LibraryJS and it uses lodash as dependency.

In the webpack configuration I setup lodash as an external dependency like so:

{
   externals: {
       "lodash"
   }
}

It works great. But then when I want to use this library inside another project, I got the following error: "libraryjs.js:77 Uncaught ReferenceError: lodash is not defined"

which is the following line:

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

=> module.exports = lodash;

/***/ }),

The fact is, I am using lodash as well in my project, so it should be working. What am I doing wrong?

By the way, I am using gulp + browserify to bundle my project and gulp + gulp-webpack to bundle the library.

Edit: I found a way to fix the error, but I really don't want to stick with this fix because it's really... ugly... See bellow:

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

Thank you for the help!

I need help here. I am bundling a custom library (named for the example LibraryJS and it uses lodash as dependency.

In the webpack configuration I setup lodash as an external dependency like so:

{
   externals: {
       "lodash"
   }
}

It works great. But then when I want to use this library inside another project, I got the following error: "libraryjs.js:77 Uncaught ReferenceError: lodash is not defined"

which is the following line:

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

=> module.exports = lodash;

/***/ }),

The fact is, I am using lodash as well in my project, so it should be working. What am I doing wrong?

By the way, I am using gulp + browserify to bundle my project and gulp + gulp-webpack to bundle the library.

Edit: I found a way to fix the error, but I really don't want to stick with this fix because it's really... ugly... See bellow:

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

Thank you for the help!

Share Improve this question edited Dec 12, 2017 at 15:59 ChainList asked Dec 12, 2017 at 12:53 ChainListChainList 1,2088 silver badges28 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 9

I had a similar situation trying to build a library - this is the solution I found.

Goal: Build a library that depends on Lodash without including Lodash in that library bundle. The consumer of the library is responsible for making Lodash available to our library.

I used the Authoring Libraries section of the documentation to put together this solution.

Specifically these two sections:

  • Externalize Lodash
  • Expose the Library

There is an example project showing this configuration as well: https://github./webpack/webpack/tree/master/examples/externals


Solution:

1. Bundle our library, excluding 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"
    }
}

Here's our example library that imports lodash and uses it. Note that whilst we depend on lodash, it won't be included in our bundle.

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

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

Here's our webpack.config.js that bundles our library, but excludes lodash from the bundle:

// "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./webpack/webpack/issues/6525
        we need to define `globalObject` in Webpack 4 to correctly build a universal library
        (i.e. node and browser patible).
        */
        globalObject: 'this',
    },
    externals: {
        // [3]
        'lodash': {
            monjs: 'lodash',
            monjs2: 'lodash',
            amd: 'lodash',
            root: '_',
        },
    },
    resolve: {
        extensions: ['.js'],
    },
};

[1] This tells Webpack to bundle our library for different environments (so it will work when loaded via: browser scripts, Node CommonJS, AMD, and downstream Webpack projects). NOTE: This is needed otherwise the externals config in [3] will output an incorrect undefined module in your bundle.

[2] Workaround for a Webpack 4 bug (if you're in the future then check if this is still relevant and needed). Also described here: https://stackoverflow./a/49119917/81723

[3] From the documentation: "set the externals option to define dependencies that should be resolved in the target environment". We're telling Webpack to exclude lodash from the library bundle and that consumers of our library are responsible for providing it.

2. Use the library in a downstream application

Define an application that depends on our my-lib library:

// "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"
    }
}

Our application imports lodash into its environment (because our library needs it) and then use our library:

// 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]

Here's the webpack.config.js for our application:

// "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] This alias config means anytime Webpack encounters require('lodash') or import ... from "lodash"; it will resolve it to this one module on disk. I found I had to do this to avoid getting multiple versions of lodash loaded into my bundle. Webpack was including one version for my-app and one for my-lib, but this fixes it so that both get the same version.

发布评论

评论列表(0)

  1. 暂无评论