我需要为第三方插件创建一个JavaScript框架,该插件可以使用它想要的任何依赖关系以及依赖关系的任何版本,而又不会与同一页面上使用的其他第三方插件冲突。 / p>
我还必须考虑共享插件之间的依赖关系,以免最终得到x个使用相同依赖关系和版本的插件,并以x个相同依赖关系使页面膨胀。 >
我最初的想法是使用Webpack捆绑第三方插件,但我需要为每个单独的依赖项单独包装以减少页面膨胀。因此,我将此配置添加到了webpack的配置中:
module.exports = {
entry: {
pluginX: './src/index.js',
},
devtool: 'source-map',
target: 'web',
output: {
path: path.resolve(__dirname, './dist'),
library: 'pluginX',
},
optimization: {
moduleIds: 'named',
chunkIds: 'named',
splitChunks: {
chunks: 'all',
name(module, chunk, cacheGroupKey) {
const context = module.context;
const splitContext = context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/);
const packageJson = getPackageJson(context);
const version = packageJson ? packageJson.version : '0.0.0';
const name = splitContext[1].replace('@', '');
return `${cacheGroupKey}-${name}-${version}`;
},
}
},
plugins: [
new CleanPlugin('./dist', {
verbose: false,
}),
]
}
getPackageJson
函数如下所示:
function getPackageJson(context) {
do {
const packageJson = `${context}\\package.json`;
if (fs.existsSync(packageJson)) { return require(packageJson); }
const splits = context.split(/\\/);
splits.pop();
context = splits.length > 0 ? splits.join('\\') : undefined;
} while (context);
return undefined;
}
我已经设置了三个测试插件,一个使用d3 v5.9.1,另外两个使用d3 v3.5.17。使用此配置,我可以正确地分别捆绑插件及其依赖项,我创建了一个测试服务器来服务捆绑的条目捆绑包和依赖项捆绑包。使用d3 v5.9.1的插件1似乎可以正常工作,但是插件2和插件3永远无法协同工作;当我尝试访问插件名称(在output.library
属性中指定)时,其中之一将始终是未定义的。
作为参考,这是index.html页面:
<!DOCTYPE html>
<html>
<head>
<script src="./vendors-d3-3.5.17.js" type="text/javascript"></script>
<script src="./vendors-d3-5.9.1.js" type="text/javascript"></script>
<script src="./plugin1.js" type="text/javascript"></script>
<script src="./plugin2.js" type="text/javascript"></script>
<script src="./plugin3.js" type="text/javascript"></script>
</head>
<body></body>
</html>
我正在使用的HtmlWebpackPlugin自动添加了index.js(我正在使用webpack-dev-server进行测试)。
作为测试页面的index.js页面是这样的:
setTimeout(function () {
plugin1.run();
plugin2.run();
plugin3.run();
}, 1000);
插件1 index.js文件如下所示:
import * as d3 from 'd3';
export function run() {
console.log('plugin1', !!d3.scaleLinear, !!(d3.scale || {}).linear);
}
插件2和3将此作为其index.js文件:
import * as d3 from 'd3';
export function run() {
console.log('pluginX', !!d3.scale.linear, !!d3.scaleLinear);
}
控制台输出应为:
plugin1 true false
plugin2 true false
plugin3 true false
但是我实际上得到了其中一个:
plugin1 true false
plugin2 true false
Uncaught TypeError: Cannot read property 'run' of undefined
或者这个:
plugin1 true false
Uncaught TypeError: Cannot read property 'run' of undefined
因为plugin2或plugin3(总是只有其中之一)始终未定义。
我怀疑这与webpack插入的引导程序代码有关,但我不能100%确定。