2017-10-16 62 views
1

我已經構建了一個使用以下結構的反應應用程序;如何構建多個反應應用程序並仍共享代碼+資產

node_modules 
src/ 
    app/ 
    index.ts 
    index.html 
    ... 
    server/ 
    index.ts 
    ... 
    node_modules/ // using the Alle pattern here 
    @<custom_packages> 
     api 
     components 

現在我需要添加一個新的應用程序。它運行在不同的域上,但應該能夠儘可能多地使用共享代碼,並加入我們的定製軟件包。我的第一次嘗試是做以下事情;

node_modules 
src/ 
    app1/ 
    index.ts 
    index.html 
    ... 
    app2/ 
    index.ts 
    index.html 
    ... 
    server/ 
    index.ts // Uses ENV_VAR to serve a different bundle 
    ... 
    node_modules/ 
    @<custom_packages> 
     api 
     components 

我現在運行到的問題是,這兩個應用程序生成自己的資產等,但我想在應用程序之間共享,以便客戶可以緩存。我可以決定不使用webpack構建資產,只是將它們放在一個靜態文件夾中,但是後來我失去了webpack中脫機插件的支持。

此外,我們決定在這種情況下使用單聲道回購。這使CI變得更加困難,但是更容易管理共享代碼。我有點想知道是否有經驗豐富的開發人員經常遇到這種情況。

基本上,你會如何構建2反應應該儘可能多地分享代碼的應用程序?

回答

0

我需要一個類似的設置,但爲Angular。下面是我(我只保留了相關的部分)的WebPack配置:

const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin'); 
const HtmlWebpackPlugin = require('html-webpack-plugin'); 

const apps = [ 
    { 
    name: 'app1', 
    baseUrl: '/app1' 
    }, 
    { 
    name: 'app2', 
    baseUrl: '/app2' 
    } 
]; 

module.exports = function (args = {}) { 
    const isDev = !args.PROD; 
    const distPath = 'dist'; 

    var config = {}; 

    config.entry = {}; 

    apps.forEach(function (app) { 
    config.entry[getAppBundleName(app)] = './src/apps/' + app.name + '/main.ts'; 
    }); 

    config.output = { 
    path: root(distPath), 
    filename: '[name].js', 
    chunkFilename: '[name].[chunkhash].js', 
    publicPath: '/dist/' 
    }; 

    config.resolve = { 
    extensions: ['.ts', '.js', '.json'], 

    modules: [root('src'), root('node_modules')] 
    }; 

    config.module = { 
    rules: [ 
     // Add your loaders here 
    ] 
    }; 

    config.plugins = [ 
    // Add your plugins here 

    // This enables tree shaking of the vendor modules 
    new CommonsChunkPlugin({ 
     name: 'vendor', 
     chunks: ['admin'].concat(apps.map(getAppBundleName)), 
     minChunks: module => /node_modules/.test(module.resource) 
    }), 
    new CommonsChunkPlugin({ 
     name: 'shared', 
     chunks: ['admin'].concat(apps.map(getAppBundleName)), 
     minChunks: module => /src(\\|\/)shared/.test(module.resource) 
    }) 
    ]; 

    apps.forEach(function (app) { 
    var otherApps = apps.slice(); 

    var appItemIndex = otherApps.indexOf(app); 

    if (appItemIndex > -1) { 
     otherApps.splice(appItemIndex, 1); 
    } 

    config.plugins.push(new HtmlWebpackPlugin({ 
     template: 'index_template.html', 
     title: app.name, 
     filename: getAppDevServerHtmlFileName(app), 
     excludeChunks: otherApps.map(getAppBundleName), 
     chunksSortMode: 'manual', 
     chunks: ['vendor', 'shared', getAppBundleName(app)], 
     inject: 'head', 
     metadata: { 
     baseUrl: app.baseUrl 
     } 
    })); 
    }); 

    config.devServer = { 
    port: 4200, 
    stats: stats, 
    historyApiFallback: { 
     rewrites: apps.map(function (app) { 
     return { 
      from: new RegExp('^' + app.baseUrl), 
      to: '/dist/' + getAppDevServerHtmlFileName(app) 
     } 
     }), 
    }, 
    }; 

    return config; 
} 

function getAppBundleName(app) { 
    return app.name; 
} 

function getAppDevServerHtmlFileName(app) { 
    return app.name + '_index.html'; 
} 

function root(args) { 
    args = Array.prototype.slice.call(arguments, 0); 
    return path.join.apply(path, [__dirname].concat(args)); 
}` 

在我的情況,我有以下的文件夾結構,這與你相似:

node_modules 
src/ 
    apps/ 
    app1/ 
     ... 
     main.ts 
    app2/ 
     ... 
     main.ts 
    shared/ 
    shared-module1/ 
     ... 
    shared-module2/ 
     ... 
    index.ts 
    ... 
webpack.config.js 

,這裏是編譯後的輸出在dist文件夾:

dist/ 
    app1.js 
    app1_index.html 
    app2.js 
    app2_index.html 
    vender.js 
    shared.js 

正如你所看到的,vendor.jsshared.js包含應用程序之間共享代碼。

相關問題