最近我遇到了以下问题:我在开发过程中使用 expressJS 框架来处理一些后端的东西,使用 webpack-dev-middleware 来编译资产,似乎 dev-middleware 正在做它的事情 - 编译 css 和 js,因为我看到了一些绿色消息在终端上,但是当我尝试访问我的 js 或 css 文件 - /css/app.css - 404、/js/app.js - 404 等时,我不断收到 404 错误。当我尝试使用 webpack 编译资产时,一切正常很好,我得到编译的 css 和 js 文件没有问题。这里有github repo
应用程序.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const argv = require('yargs').argv;
const app = express();
const devMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../../webpack.config');
const compiler = webpack(webpackConfig(null, { mode: 'development' }));
// view engine setup
app.set('views', path.join(__dirname, '../../views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.get('/', (req, res, next) => {
res.render('index', { title: "home" });
})
app.use(express.static(path.join(__dirname, '../../public')));
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
if (argv.mode !== 'production') {
app.use(devMiddleware(compiler, {
noInfo: true,
publicPath: webpackConfig(null, { mode: 'development' }).output.publicPath
}));
app.use(require("webpack-hot-middleware")(compiler));
}
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
webpack.config.js
const Path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
module.exports = (env, argv) => {
return {
entry: {
app: [
"./src/client/app.js",
"./src/scss/style.scss",
'webpack-hot-middleware/client?path=http://localhost/__webpack_hmr&timeout=20000'
]
},
output: {
filename: 'js/[name].js',
path: Path.resolve(__dirname, 'public'),
publicPath: '/'
},
mode: argv.mode || 'development',
devtool: argv.mode !== 'production' ? 'source-map' : false,
optimization: {
minimizer: [
new TerserJSPlugin({ sourceMap: true }),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
map: argv.mode !== 'production' ? {
inline: false // set to false if you want CSS source maps
} : null
}
})],
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'css/[name].css',
chunkFilename: '[id].css',
}),
new CopyPlugin([
{ from: 'images/*' }
]),
// OccurrenceOrderPlugin is needed for webpack 1.x only
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
// Use NoErrorsPlugin for webpack 1.x
new webpack.NoEmitOnErrorsPlugin()
],
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
}
]
},
{
test: /\.s?css$/,
exclude: [Path.resolve("/node_modules/")],
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
}, {
loader: "css-loader",
options: {
sourceMap: true,
url: false,
}
}, {
loader: 'postcss-loader',
options: {
sourceMap: true
}
}, {
loader: "sass-loader",
options: {
sourceMap: true,
includePaths: [Path.resolve('src/scss')],
}
}
]
},
]
}
}
};