wake-up-neo.com

Wie kann ich Webpack mit Express verwenden?

Wenn ich versuche, Webpack mit einem einfachen Express-Server zu verwenden, erhalte ich immer TONNEN von Fehlern: express.js

'use strict';
var express = require('express');
var path = require('path');
var url = require('url');


// -------- my proxy----------------------
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.set('port', process.env.PORT || 8080);
app.use(function logErrors(err, req, res, next) {
        console.error(err.stack);
        next(err);
    }
);

app.listen(app.get('port'), function() {
    console.info('Express server started at http://localhost:' + app.get('port'));
});

Ich bekomme all diese Fehler:

Version: webpack 1.10.0
Time: 1200ms
  Asset    Size  Chunks             Chunk Names
outfile  559 kB       0  [emitted]  main
chunk    {0} outfile (main) 498 kB [rendered]
    [0] ../app/server/express2.js 553 bytes {0} [built]
     + 125 hidden modules

WARNING in ../~/express/lib/view.js
Critical dependencies:
78:29-56 the request of a dependency is an expression
 @ ../~/express/lib/view.js 78:29-56

ERROR in ../~/express/lib/request.js
Module not found: Error: Cannot resolve module 'net' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/lib
 @ ../~/express/lib/request.js 18:11-25

ERROR in ../~/express/lib/view.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/lib
 @ ../~/express/lib/view.js 18:9-22

ERROR in ../~/express/~/send/index.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/send
 @ ../~/express/~/send/index.js 25:9-22

ERROR in ../~/express/~/etag/index.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/etag
 @ ../~/express/~/etag/index.js 22:12-25

ERROR in ../~/express/~/send/~/destroy/index.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/send/node_modules/destroy
 @ ../~/express/~/send/~/destroy/index.js 1:17-30

ERROR in ../~/express/~/send/~/mime/mime.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/send/node_modules/mime
 @ ../~/express/~/send/~/mime/mime.js 2:9-22

ERROR in ../~/express/~/send/~/statuses/codes.json
Module parse failed: /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/send/node_modules/statuses/codes.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
|   "100": "Continue",
|   "101": "Switching Protocols",
|   "102": "Processing",
 @ ../~/express/~/send/~/statuses/index.js 2:12-35

ERROR in ../~/express/~/send/~/mime/types.json
Module parse failed: /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/send/node_modules/mime/types.json Line 1: Unexpected token :
You may need an appropriate loader to handle this file type.

|
 @ ../~/express/~/send/~/mime/mime.js 87:12-35

ERROR in ../~/express/~/accepts/~/mime-types/~/mime-db/db.json
Module parse failed: /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/db.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
|   "application/1d-interleaved-parityfec": {
|     "source": "iana"
|   },
 @ ../~/express/~/accepts/~/mime-types/~/mime-db/index.js 11:17-37

ERROR in ../~/express/~/type-is/~/mime-types/~/mime-db/db.json
Module parse failed: /Users/Dynopia/Development/DS_Stalker_Frontend/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/db.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
|   "application/1d-interleaved-parityfec": {
|     "source": "iana"
|   },
 @ ../~/express/~/type-is/~/mime-types/~/mime-db/index.js 11:17-37

und das ist meine Konfigurationsdatei:

var webpack = require('webpack');


module.exports = {
    // Makes sure errors in console map to the correct file
    // and line number
    devtool: 'eval',
    entry: [
        './bin/www.js'
    ],
    output: {
        path: './bin/out',
        filename: 'server.js'
    },

    extensions: [
        '',
        '.jsx', '.js'
    ],

    module: {

        loaders: [
            // Compile es6 to js.
            {
                test: /app\/.*\.js?$/,
                loaders: [
                    'react-hot',
                    'babel-loader'
                ]
            }
        ]
    },

    devtool: 'source-map'
};

Was kann ich tun, ich muss das Webpack auch auf meiner Serverseite verwenden.

Ich führe die express.js-Datei wie folgt aus: ./node_modules/webpack/bin/webpack.js ../app/server/express.js outfile --display-chunks -c --progress -d

49
SudoPlz

Am Ende habe ich zwei verschiedene Konfigurationen verwendet, eine zum Packen des Serverzeugs mit Webpack und eine zum Packen des gesamten Browserzeugs sowie zum Ausführen des Webpack Dev-Servers für das Hot-Reloading.

Server webpack config aka webpack.node.config.js sieht jetzt so aus:

var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var nodeModules = {};

// note the path.resolve(__dirname, ...) part
// without it, eslint-import-resolver-webpack fails
// since eslint might be invoked with different cwd
fs.readdirSync(path.resolve(__dirname, 'node_modules'))
    .filter(x => ['.bin'].indexOf(x) === -1)
    .forEach(mod => { nodeModules[mod] = `commonjs ${mod}`; });

// es5 style alternative
// fs.readdirSync(path.resolve(__dirname, 'node_modules'))
//     .filter(function(x) {
//         return ['.bin'].indexOf(x) === -1;
//     })
//     .forEach(function(mod) {
//         nodeModules[mod] = 'commonjs ' + mod;    
//     });

module.exports =

{
    // The configuration for the server-side rendering
    name: 'server',
    target: 'node',
    entry: './app/server/serverEntryPrototype.js',
    output: {
        path: './bin/',
        publicPath: 'bin/',
        filename: 'serverEntryPoint.js'
    },
    externals: nodeModules,
    module: {
        loaders: [
            { test: /\.js$/,

                loaders: [
                    // 'imports?document=this',

                    // 'react-hot',
                    'babel-loader'
                    //,'jsx-loader'
                ]
            },
            { test:  /\.json$/, loader: 'json-loader' },
        ]
    },
    plugins: [
    // new webpack.NormalModuleReplacementPlugin("^(react-bootstrap-modal)$", "^(react)$")
    // new webpack.IgnorePlugin(new RegExp("^(react-bootstrap-modal)$"))
    // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};

Browser webpack config aka webpack.browser.config.js sieht jetzt so aus:

var webpack = require('webpack');
var path = require('path');
var buildPath = path.resolve(__dirname, 'assets');
var fs = require('fs');


var commonLoaders = [
    { test: /\.js$/,

        loaders: [
            'react-hot',
            'babel-loader'
            //,'jsx-loader'
        ]
    }
];


module.exports =
{
    // Makes sure errors in console map to the correct file
    // and line number
    name: 'browser',
    devtool: 'eval',
    entry: [
        //'./bin/www.js',
        './app/index.js',
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:8081'  // WebpackDevServer Host and port
    ],
    output: {
        path: buildPath,
        filename: '[name].js',
        // Everything related to Webpack should go through a build path,
        // localhost:3000/build. That makes proxying easier to handle
        publicPath: 'http://localhost:8081/assets/'
    },

    extensions: [
        '',
        '.jsx', '.js',
        '.json',
        '.html',
        '.css', '.styl', '.scss', '.sass'
    ],

    module: {

        loaders: [
            // Compile es6 to js.
            {
                test: /app\/.*\.jsx?$/,
                loaders: [
                    'react-hot',
                    'babel-loader'
                ]
            },

            ///app\/.*\.json$/
            { test:  /\.json$/, loader: 'json-loader' },

            // Styles
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.s(a|c)ss$/, loader: 'style!css?localIdentName=[path][name]---[local]---[hash:base64:5]!postcss!sass' },

            // Fonts
            { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff' },
            { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' }

            //{ test: /\.png$/, loader: 'url-loader?limit=100000' },
            //{ test: /\.jpg$/, loader: 'file-loader' }
        ],

        plugins: [
            new webpack.HotModuleReplacementPlugin(),
            new webpack.NoErrorsPlugin()
        ]
    },

    postcss: [
        require('autoprefixer-core')
    ],

    devtool: 'source-map'
}
;
38
SudoPlz

Dies kann durch Angabe von "node" an "target" - Option seit v1.10.2 realisiert werden.

Für Referenz: http://jlongster.com/Backend-Apps-with-Webpack--Part-I

Wenn Sie den Server und den Clientcode gleichzeitig bündeln möchten, können Sie mehrere Konfigurationen auf folgende Weise verwenden.

// webpack.config.js

module.exports = [
    {
        name: 'server',
        entry: './src/server/index.js',
        target: 'node',
        output: {
            path: __dirname + '/dist/server',
            filename: 'bundle.js',
        },
    },
    {
        name: 'client',
        entry: './src/client/index.js',
        // target: 'web', // by default
        output: {
            path: __dirname + '/dist/client',
            filename: 'bundle.js',
        },
    }
];
25
meta2

Wenn Sie mit TypeScript arbeiten, müssen Sie außerdem die Erweiterung ".js" in Ihre Konfiguration aufnehmen:

module.exports = {
   entry: './src/server/index.ts',
   target: 'node',
   output: {
      path: __dirname + '/dist/server',
      filename: 'bundle.js',
   },        
   resolve: {
      modules: [
         "node_modules"
      ],
      extensions: [".ts", ".js"]
   }
};
0
Finickyflame

Ich erkläre nur die Antwort von @meta2, weil ich glaube, dass es verständlicher geschrieben werden kann - obwohl es volle Punkte auf ihn gibt!

tl; dr - Setzen Sie target: 'node' in Ihrem webpack.config.js, um die Fehler zu beheben, die bei der Verwendung von Webpack mit Express generiert werden.

Sie erhalten immer noch Warnungen wie:

WARNING in ./node_modules/express/lib/view.js 
81:13-25 Critical dependency: the request of a dependency is an expression

Um dies zu beheben, verwenden Sie https://github.com/liady/webpack-node-externals . Zu Ihrer Information - dies reduziert die Bündelgröße erheblich (vor und nach der Größe prüfen) und beschleunigt die Bündelungszeit enorm.

Vollständiges Beispiel:

const path = require('path')
const nodeExternals = require('webpack-node-externals')

module.exports = {
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  target: 'node',   // THIS IS THE IMPORTANT PART
  externals: [nodeExternals()],
  mode: 'development'
}
0
Ben