gpt4 book ai didi

javascript - 在内存中编译 Webpack 但解析为磁盘上的 node_modules

转载 作者:IT老高 更新时间:2023-10-28 21:57:44 28 4
gpt4 key购买 nike

我正在尝试使用 web pack 来编译内存中的有效 javascript 代码字符串。我正在使用此处概述的内存 fs:https://webpack.github.io/docs/node.js-api.html#compile-to-memory .

所以我正在获取一个包含原始 javascript 的字符串,将其写入内存 fs,然后 web pack 解析到该入口点。但是在第一个 require 语句上编译失败,大概是因为它无法在真正的 fs 中查找 node_modules。

关于如何实现这一点的任何想法?

import webpack from 'webpack';
import MemoryFS from 'memory-fs';
import thenify from 'thenify';

function* compile(code) {
const fs = new MemoryFS();
fs.writeFileSync('/file.js', code);
const compiler = webpack({
entry: { file: '/file.js' },
output: {
path: '/build',
filename: '[name].js'
},
module: {
loaders: [
{ test: /\.json$/, loader: 'json' }
],
}
});
compiler.run = thenify(compiler.run);

compiler.inputFileSystem = fs;
compiler.resolvers.normal.fileSystem = fs; //this is needed for memfs
compiler.outputFileSystem = fs;
const stats = yield compiler.run();
//retrieve the output of the compilation
const res = stats.compilation.assets['file.js'].source();
return res;
}

用法

var code = "var _ = require('underscore'); console.log(_);";
var bundle = yield compile(code); //should be a bundle containing the underscore source.

错误是

ModuleNotFoundError: Module not found: Error: Cannot resolve module underscore in /

这个问题表明其他人也尝试过同样的事情:https://github.com/webpack/webpack/issues/1562 .在 https://gist.github.com/DatenMetzgerX/2a96ebf287b4311f4c18 中引用了一个要点我相信这是为了做我希望完成的事情,但以目前的形式,我不知道如何做。它将 MemoryFs 的一个实例分配给所有解析器。我试过分配 Node 的 fs 模块,但没有骰子。

简而言之,我正在尝试将入口点设置为内存中的原始 javascript 字符串,但仍需要将 require 和 import 语句解析为磁盘上的 node_modules。

更新

我已经能够得到我正在寻找的结果,但它并不漂亮。我基本上覆盖了 MemoryFS 中 #stat 和 #readFile 的实现检查真实文件系统是否收到对内存中不存在的文件的任何请求。我可以通过子类化 MemoryFS 而不是在运行时交换方法实现来稍微清理一下,但想法仍然是一样的。

工作解决方案

import webpack from 'webpack';
import JsonLoader from 'json-loader';
import MemoryFS from 'memory-fs';
import UglifyJS from "uglify-js";
import thenify from 'thenify';
import path from 'path';
import fs from 'fs';
import root from 'app-root-path';
/*
* Provide webpack with an instance of MemoryFS for
* in-memory compilation. We're currently overriding
* #stat and #readFile. Webpack will ask MemoryFS for the
* entry file, which it will find successfully. However,
* all dependencies are on the real filesystem, so any require
* or import statements will fail. When that happens, our wrapper
* functions will then check fs for the requested file.
*/
const memFs = new MemoryFS();
const statOrig = memFs.stat.bind(memFs);
const readFileOrig = memFs.readFile.bind(memFs);
memFs.stat = function (_path, cb) {
statOrig(_path, function(err, result) {
if (err) {
return fs.stat(_path, cb);
} else {
return cb(err, result);
}
});
};
memFs.readFile = function (path, cb) {
readFileOrig(path, function (err, result) {
if (err) {
return fs.readFile(path, cb);
} else {
return cb(err, result);
}
});
};


export default function* compile(code) {
// Setup webpack
//create a directory structure in MemoryFS that matches
//the real filesystem
const rootDir = root.toString();
//write code snippet to memoryfs
const outputName = `file.js`;
const entry = path.join(rootDir, outputName);
const rootExists = memFs.existsSync(rootDir);
if (!rootExists) {
memFs.mkdirpSync(rootDir);
}
memFs.writeFileSync(entry, code);
//point webpack to memoryfs for the entry file
const compiler = webpack({
entry: entry,
output: {
filename: outputName
},
module: {
loaders: [
{ test: /\.json$/, loader: 'json' }
]
}
});
compiler.run = thenify(compiler.run);

//direct webpack to use memoryfs for file input
compiler.inputFileSystem = memFs;
compiler.resolvers.normal.fileSystem = memFs;

//direct webpack to output to memoryfs rather than to disk
compiler.outputFileSystem = memFs;
const stats = yield compiler.run();
//remove entry from memory. we're done with it
memFs.unlinkSync(entry);
const errors = stats.compilation.errors;
if (errors && errors.length > 0) {
//if there are errors, throw the first one
throw errors[0];
}
//retrieve the output of the compilation
const res = stats.compilation.assets[outputName].source();
return res;
}

用法

var code = "var _ = require('underscore'); console.log(_);";
var bundle = yield compile(code); //is a valid js bundle containing the underscore source and a log statement logging _.

如果没有更好的方法,那我肯定会把它封装到 MemoryFS 的一个子类中,但我希望有一种更理智的方法可以通过 Webpack 的 api 来完成。

最佳答案

unionfs/memfs/linkfs 的组合应该有帮助,而不是 memory-fs。

关于javascript - 在内存中编译 Webpack 但解析为磁盘上的 node_modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38779924/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com