如何将 webpack 与 express 一起使用?

Posted

技术标签:

【中文标题】如何将 webpack 与 express 一起使用?【英文标题】:How can I use webpack with express? 【发布时间】:2015-09-15 02:39:46 【问题描述】:

当我尝试将 webpack 与简单的 express 服务器一起使用时,我总是会遇到大量错误: 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'));
);

我得到了所有这些错误:

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

这是我的配置文件:

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'
;

我该怎么办,我的服务器端也需要使用 webpack。

我像这样运行 express.js 文件: ./node_modules/webpack/bin/webpack.js ../app/server/express.js outfile --display-chunks -c --progress -d

【问题讨论】:

webpack 用于浏览器,express 用于服务器端,我认为您不需要打包服务器定义 但是我也看到了一些人使用 webpack 作为服务器端的例子。你看我想为客户端和服务器使用相同的代码,并利用 webpacks 的特性。 是的。存在一种在双方重用代码的方法,但 express 存在用于处理请求、服务文件和其他可能的事情。通常在节点项目中,我们有两个不同的文件夹,一个用于服务器代码,另一个用于客户端/浏览器。我们将 webpack/browserify 应用到最后一个 【参考方案1】:

我最终做的是我使用了 2 种不同的配置,1 用于使用 webpack 将服务器内容打包在一起,1 用于将所有浏览器内容打包在一起并运行 webpack 开发服务器以进行热重载。

服务器 webpack 配置 aka webpack.node.config.js 现在看起来像这样:

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$/)
  ]
;

浏览器 webpack 配置 aka webpack.browser.config.js 现在看起来像这样:

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'

;

【讨论】:

您能分享一下您将 webpack 添加到节点文件的位置吗?那会很有帮助。 不确定我是否正确理解了您的问题,但如果我理解了,您不会将 webpack 添加到您的主节点文件中。 Webpack 会转换你的节点文件,但你不必将 webpack 代码放入其中。在使用 node.js 运行主文件之前,您只需使用 webpack 命令行转换文件。就我而言,我通过输入npm start debugMode 来运行整个过程。 deugMode 是我创建的用于为我做所有事情的脚本,这是我的一部分 package.json 代码:tinyurl.com/tldrsudo 伙计,这就是我喜欢的那种魔法。那个 nodeModules 小东西让我很开心。 我更新了答案以包含每个文件的文件名,希望对您有所帮助。 @SudoPlz 非常感谢您添加文件名,现在我正在让 webpack 和 express 一起工作。你摇滚,先生!【参考方案2】:

可以通过将“node”指定为"target" option来实现,从v1.10.2开始。

供参考:http://jlongster.com/Backend-Apps-with-Webpack--Part-I

如果你想同时捆绑服务端和客户端的代码,可以通过如下方式使用多个配置。

// 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',
        ,
    
];

【讨论】:

你有在一个文件中使用多个配置的来源吗?我在 Webpack 文档中找不到它,它对我不起作用。 虽然我找不到文档,但存储库中存在一个示例:github.com/webpack/webpack/tree/master/examples/multi-compiler 尝试加载 express/lib/view.js 依赖项时仍然失败(the request of a dependency is an expression @ ../~/express/lib/view.js 78:29-56 一切都对我有用,但是当我介绍 require express 时,webpack 现在给了我很多错误.. 这解决了它.. 现在赞成【参考方案3】:

我只是澄清@meta2 的答案,因为我相信它可以用更容易理解的方式来写——尽管对他来说是满分!

tl;dr - 在您的 webpack.config.js 中设置 target: 'node' 以修复将 Webpack 与 Express 一起使用时产生的错误。

您仍然会收到如下警告:

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

要解决这些问题,请使用 https://github.com/liady/webpack-node-externals。仅供参考 - 这会显着减少您的捆绑大小(检查前后的大小)并极大地加快捆绑时间。

完整示例:

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'

【讨论】:

【参考方案4】:

此外,如果您使用的是 Typescript,请确保在您的配置中也包含“.js”扩展名:

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

【讨论】:

【参考方案5】:

我采用了一种在中小型项目中可能有用的简单方法。我这样做是为了让 webpack 可以作为 ecma 脚本和 scss 的捆绑器,尽管在这种方法中我不使用热重载。

服务器配置是express generator给出的默认配置。

webpack.config.js

const path = require("path");

module.exports = 
  entry: "./resources/index.js",
  output: 
    path: path.join(__dirname, "/public/dist"),
    publicPath: "/public/dist",
    filename: "main.js"
  ,
  mode: "development",
  module: 
    rules: [
      
        test: /\.js$/,
        exclude: /node_modules/,
        use: 
          loader: "babel-loader"
        
      ,
      
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"]
      
    ]
  
;

package.json 是 devDependencies

"devDependencies": 
    "@babel/core": "^7.6.4",
    "@babel/preset-env": "^7.6.3",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.2.0",
    "mini-css-extract-plugin": "^0.8.0",
    "node-sass": "^4.13.0",
    "sass-loader": "^8.0.0",
    "style-loader": "^1.0.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.9"
  

package.json 是脚本

"scripts": 
    "start": "node ./bin/www",
    "dev": "nodemon",
    "build": "webpack",
    "watch": "webpack --watch"
  ,

【讨论】:

【参考方案6】:

这是构建 express+webpack 应用程序的简单设置。请注意package.json文件scripts部分同时启动express server和webpack进程。

另外请注意server.js文件"app.use(express.static('dist'));"部分。 Express static 应该指向包含 index.htmlbundle.js 的 webpack 文件夹

server.js 文件:

const express = require ("express");
const path = require ("path");

const app = express();

app.use(express.json());
app.use(express.urlencoded(extended: true));
app.use(express.static('dist'));

app.get("/", (req, res) => 
  res.sendFile(path.join(__dirname, 'dist/index.html'));
)

const server = app.listen (process.env.PORT || 4000);
const portNumber = server.address().port;
console.log("ГОСПОДИН ПОРТ СЕИЧАС ОТКРЫТ "+ portNumber);

现在 package.json 文件:


  "name": "firebase1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": 
    "build": "webpack",
    "server": "node server.js",
    "dev": "concurrently --kill-others-on-fail \"npm run build\" \"npm run server\""
  ,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": 
    "webpack": "^5.64.0",
    "webpack-cli": "^4.9.1"
  ,
  "dependencies": 
    "express": "^4.17.1"
  

现在,webpack.config.js 文件:

const path = require("path");

module.exports = 
  mode: "development",
  entry: "./src/index.js",
  output: 
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js"
  ,
  watch: true

最后是 index.html 文件:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FIREBASE PROJECT OF MY LORD TOM AND JERRY</title>
  </head>
  <body>
    <h1>Getting Started with Firebase</h1>
    <script type="text/javascript" src="bundle.js"></script>
  </body>
</html>

【讨论】:

完成代码后,在命令行输入:“npm run dev”

以上是关于如何将 webpack 与 express 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 react-hot-loader 与 webpack 2 和 webpackDevMiddleware 一起工作?

使 Angular 路由与 Express 路由一起工作

无法使 react-hot-loader 和 webpack-dev-server 与 react-router 一起工作

如何使用 webpack 捆绑 puppeteer 进行生产部署?

如何通过 Express JS 服务器使 React JS 和 Socket IO 连接在一起?

如何将 Webpack 与 Angular + templateCache 一起使用?