我正在將應用程式從 Webpack 4 升級到 Webpack 5。它使用 babel-loader。我有生產代碼作業,但在升級到 karma-webpack v5 后卡在我們的 Karma/Sinon 集成測驗中。
此代碼以前有效,但現在拋出錯誤:
// useEditUI.ts
export default function useEditUI() {}
// integration.ts
import sinon from 'sinon';
import * as useEditUI from 'useEditUI';
const spy = sinon.spy(useEditUI, 'default');

我的理解是,這是因為如何在后臺管理匯入/匯出:

以前,間諜邏輯正在查看一個可配置物件,其值設定為默認匯出。現在,該物件是不可配置的,沒有 value 屬性,而是有一個映射到默認函式的 getter

這破壞了 sinon.spy 的功能。
在研究了一段時間后,我發現了一些可以提供幫助的潛在庫:
- https://www.npmjs.com/package/babel-plugin-rewire
- https://www.npmjs.com/package/babel-plugin-add-module-exports
- https://www.npmjs.com/package/proxyquire
這些庫似乎都沒有“正常作業”,其中一些似乎被遺棄了。一般來說,它們似乎強制期望使用 commonjs 模塊語法。所有其他研究都導致發布了解決方案的帖子,因為import * as Module這就是最初的解決方案是如何存在的。
在使用更現代的測驗工具(例如 Jest)時,我沒有這個問題。這只是我試圖減輕的 sinon 的一個限制。
有人在這里有可行的指導嗎?謝謝
uj5u.com熱心網友回復:
啊啊啊啊啊啊 我花了一些時間在這里找到正確的答案,但我找到了一個有效的答案!它有點脆弱,可能會在未來的 webpack 版本中中斷,但在撰寫本文時適用于最新版本 (5.72.0)
首先,創建一個新的臨時插件。使用它來重寫 Webpack 生成的源代碼。尋找管理匯出的代碼并重寫源代碼,使其包含configurable: true
AllowMutateEsmExports.prototype.apply = function (compiler) {
compiler.hooks.compilation.tap(
'AllowMutateEsmExports', function (compilation) {
compilation.hooks.processAssets.tapPromise(
{
name: 'AllowMutateEsmExports',
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
additionalAssets: true,
},
async (assets) => {
const oldSource = assets['runtime.js'];
const { ReplaceSource } = compiler.webpack.sources;
const newSource = new ReplaceSource(oldSource, 'AllowMutateEsmExports');
const oldCode = 'Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });';
const newCode = 'Object.defineProperty(exports, key, { configurable: true, enumerable: true, get: definition[key] });';
const start = oldSource.source().indexOf(oldCode);
const end = start oldCode.length;
newSource.replace(start, end, newCode, 'AllowMutateEsmExports');
await compilation.updateAsset('runtime.js', newSource);
}
);
}
);
};
確保插件已加載
plugins: [
new AllowMutateEsmExports(),
],
使用 * 符號匯入要受影響的模塊。重寫默認匯出并為其賦予一個自參考的傳統值。這僅在首先將屬性設定為可配置時才有效。
import * as useEditUI from 'useEditUI';
Object.defineProperty(useEditUI, 'default', {
writable: true,
value: useEditUI.default,
});
間諜現在將按預期作業。:)
const spy = sinon.spy(useEditUI, 'default');
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/468859.html
標籤:javascript 网页包 业力跑者 诗乃
