我試圖捆綁一個nestjs應用程式以在 lambda 中運行它。但是放棄了。過了一會兒,我試圖做同樣的一個新創建的nestjs應用程式連接到mysql。該問題是,sequelize需要mysql2 這樣:
require(moduleName);
嗯,它需要我要求它需要的方言,但在這種情況下它是mysql2. 顯然webpack,它自己無法做太多事情并退出。我按照他們的建議解決了它。但后來我想,“我想知道是否webpack可以替換特定檔案中的特定行?” 或者更確切地說,假裝它有所不同。假裝它不是require(moduleName)讀取require('mysql2').
有一個類似的問題,但我專門針對nodejs. 而且我擔心人們可能會在-speak 中稱之為背景關系依賴webpack。一個依賴,它的請求是一個運算式,而不是一個字串。
ContextReplacementPlugin不能在這里應用,因為對于單個識別符號,請求總是.(這樣的請求是無法區分的)。NormalReplacementPlugin不適用,因為這是背景關系依賴項。并且DefinePlugin似乎不能勝任這項任務,因為它不允許您替換您喜歡的任何內容,尤其是區域變數和函式引數。
如果您對捆綁nodejs應用程式感興趣,您可能需要查看此問題。在這里,我關注webpack和背景關系相關性。
PS 雖然我找到了一個不需要解決背景關系依賴關系的解決方案,但我可能會在路上遇到它。或者其他人。
UPD這是一個無法像nestjs sequelize 那樣解決的案例mysql2。sequelize-typescript在運行時加載模型:
https://github.com/RobinBuschmann/sequelize-typescript/blob/v2.1.1/src/sequelize/sequelize/sequelize-service.ts#L51
uj5u.com熱心網友回復:
免責宣告。提供的實作可能不適合您。您可能需要修改它以適用于您的webpack. 另外,我的目標是nodejs(不是瀏覽器),因此我忽略了源映射。
假設你有src/index.js:
const mysql2 = require('whatever');
以及以下軟體包:
{
"dependencies": {
"mysql2": "2.3.3",
"webpack": "5.64.2",
"webpack-cli": "4.9.1"
}
}
和webpack.config.js:
const path = require('path');
const RewriteRequirePlugin = require('./rewrite-require-plugin');
module.exports = {
mode: 'development',
target: 'node',
module: {
rules: [
// {test: path.resolve('src/index.js'),
// use: [
// {loader: path.resolve('rewrite-require-loader.js'),
// options: {
// search: "'whatever'",
// replace: JSON.stringify('mysql2'),
// }},
// ]}
],
},
plugins: [
// new RewriteRequirePlugin([
// [path.resolve('src/index.js'),
// "'whatever'",
// JSON.stringify('mysql2')],
// ])
],
stats: {
modulesSpace: Infinity,
groupModulesByPath: false,
}
};
它不會建立。但是如果你取消對插件或加載器的注釋,它就會。
rewrite-require-loader.js:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
function escapeRegExp(string) {
return string.replace(/[.* ?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function processFile(source, search, replace) {
const re = `require\\(${escapeRegExp(search)}\\)`;
return source.replace(
new RegExp(re, 'g'),
`require(${replace})`);
}
module.exports = function(source) {
const options = this.getOptions();
return processFile(source, options.search, options.replace);
};
rewrite-require-plugin.js:
const path = require('path');
const NormalModule = require('webpack/lib/NormalModule');
// https://github.com/webpack/loader-runner/blob/v4.2.0/lib/LoaderRunner.js#L9-L16
function utf8BufferToString(buf) {
var str = buf.toString("utf-8");
if(str.charCodeAt(0) === 0xFEFF) {
return str.substr(1);
} else {
return str;
}
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
function escapeRegExp(string) {
return string.replace(/[.* ?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function processFile(source, search, replace) {
source = Buffer.isBuffer(source) ? utf8BufferToString(source) : source;
const re = `require\\(${escapeRegExp(search)}\\)`;
return source.replace(
new RegExp(re, 'g'),
`require(${replace})`);
}
class RewriteRequirePlugin {
constructor(rewrites) {
this.rewrites = rewrites.map(r => [path.resolve(r[0]), r[1], r[2]]);
}
apply(compiler) {
compiler.hooks.compilation.tap('RewriteRequirePlugin', compilation => {
// https://github.com/webpack/webpack/blob/v5.64.2/lib/schemes/FileUriPlugin.js#L36-L43
const hooks = NormalModule.getCompilationHooks(compilation);
hooks.readResource
.for(undefined)
.tapAsync("FileUriPlugin", (loaderContext, callback) => {
const { resourcePath } = loaderContext;
loaderContext.addDependency(resourcePath);
loaderContext.fs.readFile(resourcePath, (err, data) => {
if (err) return callback(err, data);
callback(
err,
this.rewrites.reduce(
(prev, cur) =>
resourcePath == cur[0]
? processFile(data, cur[1], cur[2])
: data,
data));
});
});
});
}
};
module.exports = RewriteRequirePlugin;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/366304.html
