如何将 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.html
和 bundle.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 一起工作?
无法使 react-hot-loader 和 webpack-dev-server 与 react-router 一起工作
如何使用 webpack 捆绑 puppeteer 进行生产部署?