我知道你不能有条件require
一个带有browserify的模块,因为它们是在编译时绑定的,而不是运行时。条件剥离模块怎么样?
假设我有一个允许您创建图片库的应用程序。还可以编辑图库(重新排序图像等)。但是图库的渲染和编辑是耦合的,不能完全分开。但是为了部署画廊,我不需要编辑功能,我知道使用了哪些模块。我想创建两个不同的包,一个具有编辑功能,另一个没有删除大部分编辑代码。我所做的是使用envify
和uglify的死代码消除来从较小的包中排除我自己的代码。
之前(thing.js)
//...some code that only the editor needs...
module.exports = thing;
之后(thing.js)
if(process.env.INCLUDE_EDITOR === 'yes') {
//...some code that only the editor needs...
module.exports = thing;
}
这很好用,编辑器包已经很小了。而且因为我知道另一个bundle永远不会使用thing
的功能,所以只输出一个空模块就可以了。
现在问题就在于此。如果thing.js
需要一个模块,比如说pica
,它仍然会捆绑,即使在删除死代码之后没有人使用它。
之前(thing.js)
var pica = require('pica');
//...some code that uses pica...
module.exports = thing;
之后(thing.js)
if(process.env.INCLUDE_EDITOR === 'yes') {
var pica = require('pica');
//...some code that uses pica...
module.exports = thing;
}
总结一下:我的包现在包含pica
库,但没有人需要它。需要它的代码是死代码,但是uglify显然不能理解它可以完全删除pica
。
答案 0 :(得分:1)
我认为你所追求的是uglifyify
之类的转换。
Uglifyify为您提供了在每个文件包含在捆绑包中之前对每个文件应用Uglify的“挤压”转换的好处,这意味着您可以删除条件要求的死代码路径。
请注意,您仍然希望在结果输出上运行uglifyjs
。
答案 1 :(得分:0)
我想我找到了一个效果很好的解决方案。作为奖励,它不需要触及现有代码(例如,添加process.env.
支票)。我编写了一个browserify转换,给定一个模块/文件列表,用require
替换他们的{}
调用。这样,它们就会从生成的包中完全删除。无论如何,这只是一个黑客攻击。我知道。
在:
var thing = require('./thing.js');
var pica = require('pica');
后:
var thing = {};
var pica = {};
使用https://www.npmjs.com/package/browserify-transform-tools这只是几行代码,因为它已经提供了makeRequireTransform
帮助器。我要在这里转储代码并建议没有人应该使用它,除非你确切知道你在做什么。
derequire.js
var path = require('path');
var resolve = require('resolve');
var transformTools = require('browserify-transform-tools');
var options = {
evaluateArguments: true,
jsFilesOnly: true
};
var cache = {};
var resolveDerequire = function(moduleName) {
var fromCache = cache[moduleName];
if(fromCache) {
return fromCache;
}
return require.resolve(moduleName);
};
var transform = transformTools.makeRequireTransform('derequire', options, function(args, transformOptions, done) {
var requiredModule = args[0];
var basedir = path.dirname(transformOptions.file);
var shouldDerequire = transformOptions.config.modules.some(function(moduleToRequire) {
try {
//The normal require which respects NODE_PATH.
return require.resolve(requiredModule) === resolveDerequire(moduleToRequire);
} catch(ex1) {
try {
//A local require relative to the current file.
return resolve.sync(requiredModule, {basedir: basedir}) === resolveDerequire(moduleToRequire);
} catch(ex2) {
console.error(ex1, ex2);
return false;
}
}
});
if(shouldDerequire) {
done(null, '{}');
} else {
done();
}
});
module.exports = transform;
变换的package.json配置
"browserify": {
"transform": [
"babelify",
[
"./derequire.js",
{
"modules": [
"pica",
"exif-js",
"./src/thing.js",
"components/TextEditor.jsx",
"lib/FileUploader.js"
]
}
],
"browserify-css",
"imgurify",
"glslify"
]
},