如何将自定义内容转换为 webpack 中的 javascript 模块?
How can I transform custom content into a javascript module in webpack?
我有一个自定义格式,我想将其转换为 Javascript,以便可以将其导入到我的 React 应用程序中。这个改造的细节已经解决了,不重要了。
为了实现这一点,我编写了一个执行转换的自定义加载程序(实际上,将执行转换的可执行文件打包)。这部分看起来效果不错!
var child_process = require('child_process');
module.exports = function(source) {
const callback = this.async();
const exepath = "..\xml-converter\xml-converter\bin\debug\xml-converter.exe"
const child = child_process.exec(exepath, { shell: false }, function(error, stdout, stderr) {
return callback(error, stdout);
});
child.stdin.write(source);
child.stdin.end();
}
我已经将它添加到 webpack 中,我知道它正在被使用。
//...
module: {
rules: [
//...other rules...
{
test: /\.xml$/,
use: [
{ //more on this later
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
},
{
loader: path.resolve(__dirname, 'room_loader.js')
}
]
}
]
}
然后,我尝试在代码中使用这个加载器:
import myAwesomeData from './myData.xml'
console.log(myAwesomeData.aPropertyThatIsDefinitelyThere)
console.log(myAwesomeData)
这输出:
undefined
/static/media/myData.05d816d8.xml
它不是给我我的 javascript,而是将其视为图像或其他东西,然后返回 javascript 来构建 URL。如果我手动加载提供的 URL,我会得到预期的源代码:
export let myAwesomeData = {
aPropertyThatIsDefinitelyThere: "whatever..."
}
然而,这显然不是我想要的
我尝试将 babel 加载器链接到等式中(见上文),虽然它起作用了(正确转译代码),但它没有解决核心问题。
我想做的事情可行吗?如果可以,怎么做?
所以,我过度简化了我的问题陈述,结果我的问题不是我想的那样。
我正在使用 create-react-app
,但这并不能按照我需要的方式自定义 Webpack(加载自定义加载器),所以我添加了 react-app-rewired
。然后我将其添加到我的自定义文件中:
module.exports = function override(config, env) {
config.module.rules.push({
test: /\.xml$/,
use: [
{
loader: path.resolve(__dirname, 'room_loader.js')
}]
});
return config;
};
然而,仔细检查预定义的规则(最容易通过弹出来完成,但您可以在其他地方找到它们)表明这是不正确的。放置它们的正确位置是在第三条规则中,它有一个以通用 "we don't know how to handle this, so we'll treat it like an image" 加载器结尾的子规则列表。
因此你真正想做的是:
module.exports = function override(config, env) {
var rules = config.module.rules[2].oneOf;
var position = rules.length - 2;
rules.splice(position, 0, {
test: /\.xml$/,
use: [
{
loader: path.resolve(__dirname, 'room_loader.js')
}]
});
return config;
};
效果很好,比我想象的要容易得多。
我有一个自定义格式,我想将其转换为 Javascript,以便可以将其导入到我的 React 应用程序中。这个改造的细节已经解决了,不重要了。
为了实现这一点,我编写了一个执行转换的自定义加载程序(实际上,将执行转换的可执行文件打包)。这部分看起来效果不错!
var child_process = require('child_process');
module.exports = function(source) {
const callback = this.async();
const exepath = "..\xml-converter\xml-converter\bin\debug\xml-converter.exe"
const child = child_process.exec(exepath, { shell: false }, function(error, stdout, stderr) {
return callback(error, stdout);
});
child.stdin.write(source);
child.stdin.end();
}
我已经将它添加到 webpack 中,我知道它正在被使用。
//...
module: {
rules: [
//...other rules...
{
test: /\.xml$/,
use: [
{ //more on this later
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
},
{
loader: path.resolve(__dirname, 'room_loader.js')
}
]
}
]
}
然后,我尝试在代码中使用这个加载器:
import myAwesomeData from './myData.xml'
console.log(myAwesomeData.aPropertyThatIsDefinitelyThere)
console.log(myAwesomeData)
这输出:
undefined
/static/media/myData.05d816d8.xml
它不是给我我的 javascript,而是将其视为图像或其他东西,然后返回 javascript 来构建 URL。如果我手动加载提供的 URL,我会得到预期的源代码:
export let myAwesomeData = {
aPropertyThatIsDefinitelyThere: "whatever..."
}
然而,这显然不是我想要的
我尝试将 babel 加载器链接到等式中(见上文),虽然它起作用了(正确转译代码),但它没有解决核心问题。
我想做的事情可行吗?如果可以,怎么做?
所以,我过度简化了我的问题陈述,结果我的问题不是我想的那样。
我正在使用 create-react-app
,但这并不能按照我需要的方式自定义 Webpack(加载自定义加载器),所以我添加了 react-app-rewired
。然后我将其添加到我的自定义文件中:
module.exports = function override(config, env) {
config.module.rules.push({
test: /\.xml$/,
use: [
{
loader: path.resolve(__dirname, 'room_loader.js')
}]
});
return config;
};
然而,仔细检查预定义的规则(最容易通过弹出来完成,但您可以在其他地方找到它们)表明这是不正确的。放置它们的正确位置是在第三条规则中,它有一个以通用 "we don't know how to handle this, so we'll treat it like an image" 加载器结尾的子规则列表。
因此你真正想做的是:
module.exports = function override(config, env) {
var rules = config.module.rules[2].oneOf;
var position = rules.length - 2;
rules.splice(position, 0, {
test: /\.xml$/,
use: [
{
loader: path.resolve(__dirname, 'room_loader.js')
}]
});
return config;
};
效果很好,比我想象的要容易得多。