我想完成以下结构:
button.core.jsx
button.theme-a.jsx
button.theme-b.jsx
以React为例,我想在button.core.jsx
中执行以下操作:
import React from 'react';
import Themed from './button.[theme]';
export default class Button extends React.Component {
render() {
if (Themed) {
return <Themed />;
}
return <button>default button</button>;
}
}
换句话说,我想在webpack.config.js
中定义一个主题并加载该文件(如果存在)。如果没有,则渲染默认行为。我认为这将是一个非常强大的设置!
我一直在寻找制作定制装载机,但还没有成功。有人能指出我正确的方向吗?
答案 0 :(得分:4)
我已经开始编写自定义&#34;解析器&#34;:
const ThemeResolver = {
apply: function(resolver) {
resolver.plugin('file', function(req, cb) {
if (req.request.indexOf('[theme]') == -1) {
return cb();
}
const defaultFile = req.request.replace('[theme]', 'Default');
const themedFile = req.request.replace('[theme]', process.env.THEME);
req.request = themedFile;
this.doResolve(['file'], req, (err) => {
if (!err) {
return cb();
}
req.request = defaultFile;
this.doResolve(['file'], req, cb);
})
});
}
};
module.exports = {
// ...
plugins: [
new webpack.ResolverPlugin([ThemeResolver]),
]
// ...
};
尝试将路径中[theme]
的文件解析为主题定义为环境变量的路径。如果失败,它将回退到默认文件。这样我就可以像这样需要一个主题文件:
import Presentation from './button-[theme]'
主要组成部分与我的问题有点不同,但我实际上非常满意它:
import React from 'react';
import Presentation from './button-[theme]';
export default class Button extends React.Component {
onClick = (e) => console.log('some logic');
render() {
return <Presentation onClick={ this.onClick } />;
}
}
此按钮组件的逻辑可以在button.core.jsx
内部,而演示文稿将由以下组件之一处理:
THEME=theme-a npm start // button-[theme] resolves to button-theme-a.jsx
THEME=theme-c npm start // button-[theme] resolves to button-default.jsx
免责声明:我还没有在大规模或生产环境中使用它,但它似乎适用于小型POC。如果我做不明智的事情,请告诉我!