Webpack: bagaimana cara menggabungkan sisi klien dan server menjadi satu bundel akhir?

Saya sudah menderita vertigo karena berbagai webpack konfigurasi dan kasus penggunaan dan menemui jalan buntu. Akhirnya saya membangun aplikasi saya: react.js + express.js.

Sisi server sekarang hanya memproses data formulir yang dikirimkan dan menggunakan nodemailer untuk mengirim email. Dalam waktu dekat akan menyuntikkan data ke html template tergantung rute.

Jadi secara lokal semuanya berfungsi dengan baik, tetapi saya belum menemukan cara menggabungkan sisi klien dan server untuk bundel produksi akhir dengan webpack.

Ini bagian dari packages.json: saya

  "main": "src/index.js",
  "scripts": {
    "start": "start npm run start:client && start npm run start:server",
    "start:client": "webpack-dev-server",
    "start:server": "node server.js"
  },
  "proxy": "http://localhost:3000",

Bagian webpack:

module.exports = {

    devtool: 'source-map',
    devServer: {
        historyApiFallback: true,
        contentBase: './src',
        proxy : {
            '/contact': 'http://localhost:3000'
          }     
    },

    entry: {
        vendor:  ['./src/js/plugins.js', 
            './src/js/classList.min.js'].map(function(link){ 
                return path.resolve(__dirname, link); 
            }),



        base: ['./src/css/animate.css', './src/css/outdatedbrowser.css'].map(function(link){ 
                return path.resolve(__dirname, link); 
            }),
        entry: ["babel-polyfill", './src/index.js']
    },
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].[chunkhash].js',
        publicPath: '/'
    },
    resolve: {
        extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
        modules: [
             path.join(__dirname, 'node_modules')
        ]
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
        }),
        new webpack.optimize.ModuleConcatenationPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: 'vendor.[chunkhash].js',
            minChunks: Infinity
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
                screw_ie8: true,
                conditionals: true,
                unused: true,
                comparisons: true,
                sequences: true,
                dead_code: true,
                evaluate: true,
                if_return: true,
                join_vars: true
            },
            output: {
                comments: false
            }
        }),
        new webpack.LoaderOptionsPlugin({
            options: {
                postcss: [
                    autoprefixer({
                        browsers: [
                            'last 3 version',
                            'ie >= 10'
                        ]
                    })
                ],
                context: staticSourcePath
            }
        }),
        new webpack.HashedModuleIdsPlugin(),
        new HtmlWebpackPlugin({
            template: path.join(__dirname, './public/index.html'),
            path: buildPath,
            excludeChunks: ['base'],
            filename: 'index.html',
            minify: {
                collapseWhitespace: true,
                collapseInlineTagWhitespace: true,
                removeComments: true,
                removeRedundantAttributes: true
            }
        }),
        new PreloadWebpackPlugin({
            rel: 'preload',
            as: 'script',
            include: 'all',
            fileBlacklist: [/\.(css|map)$/, /base?.+/]
        }),
        new ExtractTextPlugin({
            filename: '[name].[contenthash].css',
            allChunks: true
        }), 
        new StyleExtHtmlWebpackPlugin({
            minify: true
        }),
        new webpack.NoEmitOnErrorsPlugin(),
        new CompressionPlugin({
            asset: '[path].gz[query]',
            algorithm: 'gzip',
            test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
            threshold: 10240,
            minRatio: 0.8
        })
    ],
    module: {

        rules: [{
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'react', 'stage-1'],
                    }
                },
                include: sourcePath
            }

        ]
    }

};

Dan struktur file:

    dist <folder>
    node_modules <folder> ----   
    public <folder> ---- 
        index.html
    src <folder> ----   
        components <folder>
        ---css < folder > 
        ---fonts < folder >
        ---icons < folder >
        ---img < folder >
        ---js < folder > - third party JS
        ---.env    
        ---i18n.js    
        ---index.js
        ---myDetector.js
        ---sitemap.xml    
    server.js   
    package.json     
    package-lock.json 
    webpack.config.js

Adakah yang bisa membantu dengan konfigurasi agar dapat berfungsi?


person Kuzma    schedule 07.02.2018    source sumber


Jawaban (2)


Ya, saya tidak tahu kenapa tidak ada yang menjawab, tapi jawabannya sederhana: keduanya tidak bisa digabungkan. Sisi server harus dijalankan pada VPS

person Kuzma    schedule 08.02.2018

Saya membagikan struktur proyek reactjs saya dengan konfigurasi..

Instal nodemon untuk mengawasi server kapan pun untuk mengubah apa pun di kode sisi server dan babel untuk memindahkan es6 atau es7 Anda ke es5

Paket.json

"scripts": {
"server": "nodemon --watch server --exec babel-node -- server/index.js",
"start": "nodemon --watch server --exec babel-node -- server/index.js",
"test": "echo \"Error: no test specified\" && exit 1"

},

webpack.config.dev.js

let outputPath = path.join(__dirname);


export default {
// devtools: 'eval-source-map',
devtool: 'source-map',
entry: [
    'webpack-hot-middleware/client',
    path.join(__dirname, 'client/index.js'),
],
output: {
    path: outputPath,
    publicPath: "/",
    filename: 'bundle.js'
},
module:{        
    loaders:[
        {
            test: /\.js$/,                
            include: path.join(__dirname, 'client'),
            exclude: /(node_modules|bower_components)/,
            loaders: ['react-hot-loader','babel-loader'],                
        }
    ]
},
node: {
    fs: 'empty'
},
plugins: [
    new webpack.ProvidePlugin({
        "React": "react",
    }),
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
],
resolve: ['','.js']

}

Struktur proyek

node_modules <folder> ----   
public <folder> ----   
    components <folder>
    ---css < folder > 
    ---fonts < folder >
    ---icons < folder >
    ---img < folder >
    ---js < folder > - third party JS
    ---.env    
    ---i18n.js    
    ---index.js
    ---myDetector.js
    ---sitemap.xml    
server
    ---index.html
    ---index.js
package.json     
package-lock.json 
webpack.config.dev.js
person radhey shyam    schedule 07.02.2018
comment
Tampaknya itu tidak terkait dengan pertanyaan saya: Saya perlu menggabungkan menjadi satu bundel aplikasi reaksi frontend yang berfungsi + sisi server - express.js - person Kuzma; 08.02.2018
comment
bundle.js adalah file yang semua kode ujung depannya akan diikat: output: { path: outputPath, publicPath: /, nama file: 'bundle.js' }, - person radhey shyam; 08.02.2018
comment
Saya rasa itu tidak mungkin untuk file sisi server. - person radhey shyam; 08.02.2018