我在尝试构建库时遇到了类似的情况 - 这是我找到的解决方案。
目标:
构建一个依赖 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] 来自文档:“设置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 配置意味着任何时候Webpack 遇到require('lodash') 或import ... from "lodash"; 都会将其解析为磁盘上的这个模块。我发现我必须这样做以避免将多个版本的 lodash 加载到我的包中。 Webpack 包含一个用于my-app 的版本和一个用于my-lib 的版本,但这修复了它,以便两者获得相同的版本。