2017-10-12 62 views
1

動機怎麼辦陣營原住民風格的多個版本,建立與的WebPack

我保持一個應用程序,是白標爲衆多獨立的品牌,有時會發生變化主要體現在風格,而且在覈心UX陣營。當前的(骨幹)解決方案包括將共享代碼保存在單獨的回購站中,然後使用Grunt構建獨立的應用程序,併爲每個生活在其自己文件夾中的項目提供大部分樣式代碼和一些視圖覆蓋。我們只需使用shell腳本一個接一個地運行所有的grunt任務。我們將在React中繼續構建這個新版本,並希望儘量減少重複代碼,現在這已經成爲舊版本中的主要問題。

期望的結果

的陣營本地打包建立在同一時間的應用程序的兩個版本。它看起來像import ComponentA from './ComponentA.js'這樣的導入語句,並首先查找ComponentA.android.jsComponentA.ios.js,然後如果未找到特定於平臺的導入語句,則會回退到導入ComponentA.js。我想在Webpack中複製這種行爲。所以,我想有一個看起來像這樣的文件夾:

react_clients/src/components 
    |_ ComponentB.js // import ComponentA from './ComponentA.js'; 
    |_ ComponentA.js 
    |_ ComponentA.brand1.js 
    |_ ComponentA.brand2.js 

的WebPack應該建立ComponentB.js如下:

  • brand1.bundle.jsComponentA.brand1.js
  • brand2.bundle.js進口進口ComponentA.brand2.js
  • brand3.bundle.jsbrand4.bundle.jsComponentA.js進口

這也適用於樣式,理想情況下使用相同的命名約定。

如果需要,可以爲每個版本單獨運行Webpack,可以使用不同的webpack.config文件或接受命令行參數。關鍵是避免重複應用程序代碼。

當前代碼

爲的WebPack的出發點是新鮮生成並排出create-react-app項目。


PS:事先道歉,如果事實證明這是一個重複,但這是一個非常棘手的問題研究。我懷疑這個答案會與https://webpack.js.org/configuration/resolve/的高級配置有關,但是還不能確定。

回答

1

好吧,夥計這裏就是我最後做:

開發

.env.development我指定一個變量我想要做對開發項目的名稱:

REACT_APP_VERSION_NAME=brand1 

然後在webpack.config.dev.js我利用模塊分辨率來實現上述行爲:

const JS_PROJECT_EXTENSION = `.${process.env.REACT_APP_VERSION_NAME}.js`; 
const STYLE_PROJECT_EXTENSION = `.${process.env.REACT_APP_VERSION_NAME}.pcss`; 
const extensions = [JS_PROJECT_EXTENSION, '.js', '.json', '.jsx', STYLE_PROJECT_EXTENSION, '.pcss']; 

... 
module.exports = { 
... 
    extensions, 
... 
} 

然後在代碼中,我可以簡單地做到以下幾點:

import ComponentA from './componentA'; 
import Styles from './styles'; 

而且一切正常。


生產

我不指定.env.productionREACT_APP_VERSION_NAME。相反,相關的配置文件導出功能,我迭代我想要建立的版本。

首先,我創建的config/paths.js一個單獨的版本,出口的函數,而不是一個靜態的對象:

module.exports = function(projectName) { 
    return { 
    ... 
    appBuild: resolveApp('build/' + projectName), 
    ... 
    }; 
} 

而且我webpack.config.prod.js看起來是這樣的:

... 
const getPaths = require('./paths.prod'); 
... 

module.exports = function(projectName) { 
    const paths = getPaths(projectName); 

    const JS_PROJECT_EXTENSION = `.${projectName}.js`; 
    const STYLE_PROJECT_EXTENSION = `.${projectName}.pcss`; 
    const extensions = [JS_PROJECT_EXTENSION, '.js', '.json', '.jsx', STYLE_PROJECT_EXTENSION, '.pcss']; 

    ... 
    return { 
    ... 
    output: { 
     ... 
     filename: projectName + '-assets/js/[name].[chunkhash:8].js', 
     chunkFilename: projectName + '-assets/js/[name].[chunkhash:8].chunk.js', 
     ... 
    } 
    ... [etc, adding projectName to any output that needs to be built separately] 
    }; 
} 

最後,只是包裝大部分在scripts/build.js中的一個循環中的動作:

... 
[various imports] 
... 

process.argv[2].split(' ').forEach(projectName => { 
    const config = require('../config/webpack.config.prod')(projectName); 
    const paths = require('../config/paths.prod')(projectName); 
    ... 
    [rest of build.js as normal] 
} 

之後,只需將服務器指向每個版本的正確文件,然後在想要構建時運行yarn build "brand1 brand2"即可。

想要接受這個答案,因爲它現在對我來說很有用,但是很想聽聽將來任何人遇到的潛在改進。

相關問題