问题描述
是否可以配置 Webpack 使其摇树足够智能以删除仅依赖于其他摇树导出的导入?
示例:
entry.js
import { apple } from './appleBanana';
console.log(apple());
appleBanana.js
import { mango,orange } from './mangoOrange';
export function apple() {
console.log('apple');
mango();
}
export function banana() {
console.log('banana');
orange();
}
mangoOrange.js
export function mango() {
console.log('mango');
}
export function orange() {
console.log('orange');
}
webpack.config.js 优化
optimization: {
concatenateModules: false,usedExports: true,sideEffects: true
}
当与上面的编译时,我们得到:
/***/ "./client/entry/Test.ts":
/*!******************************!*\
!*** ./client/entry/Test.ts ***!
\******************************/
/*! no exports provided */
/*! all exports used */
/***/ (function(module,__webpack_exports__,__webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _appleBanana__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./appleBanana */ "./client/entry/appleBanana.ts");
console.log(Object(_appleBanana__WEBPACK_IMPORTED_MODULE_0__[/* apple */ "a"])());
/***/ }),/***/ "./client/entry/appleBanana.ts":
/*!*************************************!*\
!*** ./client/entry/appleBanana.ts ***!
\*************************************/
/*! exports provided: apple,banana */
/*! exports used: apple */
/***/ (function(module,__webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__,"a",function() { return apple; });
/* unused harmony export banana */
/* harmony import */ var _mangoOrange__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mangoOrange */ "./client/entry/mangoOrange.ts");
function apple() {
console.log('apple');
return Object(_mangoOrange__WEBPACK_IMPORTED_MODULE_0__[/* mango */ "a"])();
}
function banana() {
console.log('banana');
return Object(_mangoOrange__WEBPACK_IMPORTED_MODULE_0__[/* orange */ "b"])();
}
/***/ }),/***/ "./client/entry/mangoOrange.ts":
/*!*************************************!*\
!*** ./client/entry/mangoOrange.ts ***!
\*************************************/
/*! exports provided: mango,orange */
/*! exports used: mango,orange */
/***/ (function(module,function() { return mango; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__,"b",function() { return orange; });
function mango() {
console.log('mango');
}
function orange() {
console.log('orange');
}
/***/ })
/******/ });
请注意,mango
和 orange
都被标记为已使用,即使 banana()
(调用 orange()
)已被摇树移除。结果,在 Terser/Uglify 缩小包中,它们都包含在内。
有没有办法让 Webpack 或 Terser/UglifyJS 变得更智能,并且还可以移除对 post-tree-shaking 中未使用的符号的导入?
解决方法
它会删除它们,您看到的不是生产包(由于注释而不是压缩代码)。
在开发版本中,webpack 只是用注释标记有未使用的导出/导入,就像在您的示例包中一样。
摇树是一个仅在生产构建中应用的过程,它从包中删除这些未使用的令牌。
尝试在生产模式下运行构建,并检查缩小的包,您应该期望 banana
和 orange
不会存在于其中。