Webpack主题加载器

时间:2016-01-26 17:23:48

标签: reactjs webpack

我想完成以下结构:

  • 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中定义一个主题并加载该文件(如果存在)。如果没有,则渲染默认行为。我认为这将是一个非常强大的设置!

我一直在寻找制作定制装载机,但还没有成功。有人能指出我正确的方向吗?

1 个答案:

答案 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。如果我做不明智的事情,请告诉我!