2017-10-16 73 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包含应用程序之间共享代码。

相关问题