2016-01-26 18 views
5

Tôi muốn đạt được cơ cấu như sau:Webpack chủ đề nạp

  • button.core.jsx
  • button.theme-a.jsx
  • button.theme-b.jsx

Chịu Phản ứng làm ví dụ, tôi muốn làm như sau trong 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>; 
    } 
} 

Nói cách khác, tôi muốn xác định chủ đề trong số webpack.config.js và tải tệp đó nếu nó tồn tại. Nếu nó không, hãy trả về hành vi mặc định. Tôi nghĩ rằng đây sẽ là một thiết lập rất mạnh mẽ!

Tôi đã tìm kiếm xung quanh để tạo trình tải tùy chỉnh nhưng chưa thành công. ai đó có thể chỉ cho tôi phương hướng đúng không?

Trả lời

4

Tôi đã có làm việc này với viết một tùy chỉnh "giải quyết":

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]), 
    ] 
    // ... 
}; 

Nó cố gắng để giải quyết một tập tin với [theme] trong đường đi của nó vào một con đường với chủ đề định nghĩa là một biến môi trường. Nếu nó không thành công, nó sẽ dự phòng một tệp mặc định thay thế. Bằng cách này tôi có thể yêu cầu một tập tin theo chủ đề như vậy:

import Presentation from './button-[theme]'

Thành phần chính hóa ra là một chút khác nhau hơn trong câu hỏi của tôi, nhưng tôi nội dung thực sự khá với nó:

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 } />; 
    } 
} 

Logic của này nút thành phần có thể sống bên trong của button.core.jsx, trong khi trình bày sẽ được xử lý theo một trong các thành phần này:

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 

Tuyên bố từ chối trách nhiệm: Tôi chưa sử dụng điều này ở quy mô lớn hoặc môi trường sản xuất, nhưng có vẻ như nó hoạt động trong một POC nhỏ. Xin vui lòng cho tôi biết nếu tôi đang làm một cái gì đó không khôn ngoan!

+0

Tôi đã gặp phải một sự cố với vấn đề này. Các plugin khác dường như không nhìn thấy nó. Vì vậy, trong trường hợp của tôi, sử dụng 'html-webpack-plugin' cho favicon, nó không bao giờ giải quyết thẻ theme. – Ben

+0

Điều đó thực sự có ý nghĩa, bởi vì bạn không yêu cầu/nhập bất cứ thứ gì vào thời điểm đó. Bạn chỉ đang thực hiện một tham chiếu và trình duyệt của bạn sẽ tải favicon. Bạn không thể thêm một số logic bên trong mẫu của bạn? – Jpunt

+0

Đó có lẽ là những gì tôi sẽ làm. Modularize "hiện tập tin thương hiệu của tôi tồn tại" mã ở trên để tôi có thể sử dụng nó bên ngoài trình phân giải. – Ben

Các vấn đề liên quan