我的Webpack应用程序中有一些在构建时创建的JSON-有什么方法可以在构建过程中用路径"注入"它吗?我知道我可以把它写在一个文件中,并以这种方式包含它,但我希望我能做一些更干净的事情。
编辑2020/10/27:webpack虚拟模块是一个可以做到这一点的项目,并且与webpack 5 兼容
Edit 2018/04/09:val加载程序是在构建时实现注入代码和值的另一种方法,但它需要从一个单独的文件加载该代码,如果该文件仅存在于内存中,则该文件可能无法访问OP设置中的JSON数据。
我也在想办法做到这一点。我最终深入研究了webpack的内部结构,并编写了一个似乎可以工作的插件。
它很干净,因为你不必将文件写入磁盘,但它的内部有点混乱,因为我必须了解webpack的CachedInputFileSystem是如何工作的。
使用加载器似乎不可能做到这一点。Webpack需要解析磁盘上的文件位置并读取其中的内容,然后才能进入加载阶段。
通过在compiler.resolvers.normal
的"解析"阶段放置插件函数,可以访问webpack正在使用的文件系统,然后将虚拟文件名和内容添加到该文件系统的缓存中。
完成后,webpack中的其他一切都正常工作,您的虚拟文件/模块将通过您配置的其他加载程序和插件。
请参阅https://github.com/rmarscher/virtual-module-webpack-plugin我写的代码。已发布到npm:https://www.npmjs.com/package/virtual-module-webpack-plugin
以下是插件解析部分的代码。注意,这个例子是针对webpack 1和2的,但插件已经更新,可以使用更新的版本:
compiler.resolvers.normal.plugin('resolve', function resolverPlugin(request, cb) {
// populate the file system cache with the virtual module
const fs = this.fileSystem;
// webpack 1.x compatibility
if (typeof request === 'string') {
request = cb;
cb = null;
}
if (!modulePath) {
modulePath = this.join(compiler.context, moduleName);
}
VirtualModulePlugin.populateFilesystem({ fs, modulePath, contents, ctime });
if (cb) {
cb();
}
});
populateFilesystem
静态方法将内容添加到fs._readFileStorage.data
,并在fs._statStorage.data
高速缓存中为fs.stat()
创建模拟结果。为了创建mock fs.Stats
对象,我借用了mock-fs
包中的一些代码。
到目前为止,我已经用最新的webpack1.x和2.x以及webpack-dev服务器对它进行了测试。我使用了extract-text-webpack-plugin
、json-loader
、raw-loader
和css-loader
。一切似乎都如预期的那样。
以下是使用插件的webpack配置:
'use strict';
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const VirtualModulePlugin = require('virtual-module-webpack-plugin');
module.exports = function webpackConfig() {
const runtimeJsonContents = JSON.stringify({
greeting: 'Hello!',
});
const runtimeStyleContents = `
body { background: #000; color: #ccc; }
.greeting { font: 600 40px/50px fantasy; text-align: center; }
`;
const config = {
context: __dirname,
devtool: 'source-map',
entry: {
index: './src/index',
},
output: {
filename: '[name].js',
path: 'dist',
publicPath: '/',
devtoolModuleFilenameTemplate: '../[resource-path]',
},
module: {
loaders: [
{
test: /.json$/,
loaders: ['json-loader'],
},
{
test: /.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: 'css-loader?sourceMap',
}),
},
],
},
plugins: [
new VirtualModulePlugin({
moduleName: 'src/mysettings.json',
contents: runtimeJsonContents,
}),
new VirtualModulePlugin({
moduleName: 'src/css/generated.css',
contents: runtimeStyleContents,
}),
new ExtractTextPlugin({
filename: '[name].css',
allChunks: true,
}),
],
resolve: {
modules: [
path.join(__dirname, 'src'),
'node_modules',
],
},
};
return config;
};
请参阅https://github.com/rmarscher/virtual-module-webpack-plugin/tree/master/examples获取不同版本的webpack的完整示例。
我还应该注意,此代码需要NodeJS 4.x或更高版本。