【发布时间】:2021-03-31 17:23:00
【问题描述】:
Webpack 新手,第一次使用 Express 启动 Web 服务器。
我有一个使用 webpack-dev-server 在本地运行的 Vue 应用程序,我希望该应用程序也可以在 Heroku 上运行。我知道我不能使用webpack-dev-server 作为产品,所以我寻求建议。给我的建议是使用 Express 服务器,这就是我开始挣扎的地方。
我的应用附带一个样板文件 webpack.config.js,如下所示:
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');
function resolvePath(dir) {
return path.join(__dirname, '..', dir);
}
const env = process.env.NODE_ENV || 'development';
const target = process.env.TARGET || 'web';
const isCordova = target === 'cordova';
module.exports = {
mode: env,
entry: {
app: './src/js/app.js',
},
output: {
path: resolvePath(isCordova ? 'cordova/www' : 'www'),
filename: 'js/[name].js',
chunkFilename: 'js/[name].js',
publicPath: '',
hotUpdateChunkFilename: 'hot/hot-update.js',
hotUpdateMainFilename: 'hot/hot-update.json',
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
vue$: 'vue/dist/vue.esm.js',
'@': resolvePath('src'),
},
},
devtool: env === 'production' ? 'source-map' : 'eval',
devServer: {
hot: true,
open: true,
compress: true,
contentBase: '/www/',
disableHostCheck: true,
historyApiFallback: true,
watchOptions: {
poll: 1000,
},
},
optimization: {
minimizer: [
new TerserPlugin({
sourceMap: true,
}),
],
},
module: {
rules: [
{
test: /\.(mjs|js|jsx)$/,
use: 'babel-loader',
include: [
resolvePath('src'),
resolvePath('node_modules/framework7'),
resolvePath('node_modules/framework7-vue'),
resolvePath('node_modules/template7'),
resolvePath('node_modules/dom7'),
resolvePath('node_modules/ssr-window'),
],
},
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /\.css$/,
use: [
env === 'development'
? 'style-loader'
: {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
],
},
{
test: /\.styl(us)?$/,
use: [
env === 'development'
? 'style-loader'
: {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'stylus-loader',
],
},
{
test: /\.less$/,
use: [
env === 'development'
? 'style-loader'
: {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'less-loader',
],
},
{
test: /\.(sa|sc)ss$/,
use: [
env === 'development'
? 'style-loader'
: {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'sass-loader',
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'images/[name].[ext]',
},
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac|m4a)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name].[ext]',
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[ext]',
},
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env),
'process.env.TARGET': JSON.stringify(target),
}),
new VueLoaderPlugin(),
...(env === 'production'
? [
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true,
map: { inline: false },
},
}),
new webpack.optimize.ModuleConcatenationPlugin(),
]
: [
// Development only plugins
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
]),
new HtmlWebpackPlugin({
filename: './index.html',
template: './src/index.html',
inject: true,
minify:
env === 'production'
? {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
}
: false,
}),
new MiniCssExtractPlugin({
filename: 'css/[name].css',
}),
new CopyWebpackPlugin([
{
from: resolvePath('src/static'),
to: resolvePath(isCordova ? 'cordova/www/static' : 'www/static'),
},
]),
],
};
我的server.js 文件目前看起来像:
var express = require('express');
var app = express();
var webpack = require('webpack');
var path = require('path');
const port = process.env.PORT || 8080;
var compiler = webpack(require('./build/webpack.config.js'));
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: '/'
}));
app.use('*', function (req, res, next) {
var filename = path.join(compiler.outputPath,'index.html');
compiler.outputFileSystem.readFile(filename, function(err, result){
if (err) {
return next(err);
}
res.set('content-type','text/html');
res.send(result);
res.end();
});
});
app.listen(port);
当我在本地运行node ./server.js 时,服务器启动没有问题,我可以继续进行。我偷偷怀疑这可能是配置默认为development 的结果。
但是,当我将分支部署到 Heroku 时,node ./server.js 运行,服务器在挂起一段时间后崩溃并出现 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory。
在花费大量时间进行调试后,我感到很困惑。我想要的只是让我的网络应用程序在 Heroku 上运行。顺便说一句,我正在使用 Cordova 在移动平台上构建和运行这段代码,我不想丢失这些代码。我希望能有第二双眼睛告诉我应该如何修改这些文件。
感谢您的宝贵时间。
【问题讨论】:
-
你应该使用 Vue CLI,它带有预配置的
devServer、加载器等。然后通过 Github 将你的应用程序的 repo 连接到 Heroku 并让它构建/部署。如果您不需要后端,则无需快递。
标签: express vue.js heroku webpack webpack-dev-server