背景介绍:
我这有一个node.js项目, 区分开发环境和线上环境. 开发环境下通过wepack-hot-middleware
实现热更新机制. 同时配合html-webpack-plugin
插件, 将模板文件生成为发布目录的最终入口文件:index.html
整个工程使用ES6语法, 由于目前node不支持es6, 所以开发环境中, 使用babel-node
作为"解释器".
现状:
目前这个东西, 如果使用纯命令行的方式. 可以正常执行开发环境和线上环境的各个功能. 但是如果相同的代码, 放到vscode
中去调试, 则在开发环境下无法正常启动调试(线上模式可以).
问题:
我打算用vscode
的动态调试功能, 调试本工程. 但是在开发模式下, wepack-hot-middleware
以及html-webpack-plugin
报错, 大部分错误都是找不到某个模块, 找不到模板文件. 以下是具体的报错信息:
ERROR in ./src/foreground/app.js
Module build failed: Error: Cannot find module '/home/dev/Code/react-blog/node_modules/babel-loader/lib/index.js'.
at /home/hacksign/Code/react-blog/dist/server.d263caa8612d7c914253.js:92039:9
at process._tickCallback (internal/process/next_tick.js:68:7)
@ multi webpack-hot-middleware/client?noInfo=true&reload=true ./src/foreground/app.js
ERROR in ./node_modules/webpack-hot-middleware/client.js?noInfo=true&reload=true
Module not found: Error: Can't resolve './../../../../../../buildin/module.js' in '/home/hacksign/Code/react-blog/node_modules/webpack-hot-middleware'
@ ./node_modules/webpack-hot-middleware/client.js?noInfo=true&reload=true 1:0-48
@ multi webpack-hot-middleware/client?noInfo=true&reload=true ./src/foreground/app.js
....省略一大堆同一类型的, 找不到其他模块的错误
Child html-webpack-plugin for "index.html":
ERROR in Entry module not found: Error: Can't resolve '/src/foreground/index.html' in '/home/dev/Code/react-blog'
ℹ 「wdm」: Failed to compile.
但是, 如果用vscode
调试线上环境的代码, 却没有问题. 但是这样的话, 我就失去了热更新的能力.
所以, 我该如何在区分开发环境和线上环境的情况下, 使用vscode和es6愉快的调试后端代码呢?
ps: 上面报的找不到的模块, 绝大部分文件都是存在的, 而且权限是没问题的.
相关代码:
首先是这个项目的package.json
(只列了关键部分), dev
是开发环境, start
是线上环境:
{
....
"scripts": {
"clean": "rm -rf dist",
"foreground": "webpack --config ./configs/webpack.foreground.js",
"background": "webpack --config ./configs/webpack.background.js",
"build": "npm run clean; npm run foreground; npm run background",
"start": "npm run clean; npm run build; NODE_ENV=production node dist/server.*.js",
"dev": "babel-node --presets env,stage-2,react src/background/app.js"
},
....
}
然后是开发环境的入口文件background/app.js
:
import express from 'express';
import path from 'path';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import config from '../../configs/webpack.foreground';
const isDevelopment = process.env.NODE_ENV !== "production";
const app = express();
app.set('port', '10010');
if(isDevelopment) {
console.log("develop environment.");
// load develop plugins
config.entry.app.unshift('webpack-hot-middleware/client?noInfo=true&reload=true');
config.plugins.push(new webpack.HotModuleReplacementPlugin());
let compiler = webpack(config);
//下面这个地方, 导致程序在vscode中报错
// 但是在命令行下正常
app.use(
webpackDevMiddleware(
compiler,
{
publicPath: config.output.publicPath
}
)
);
app.use(
webpackHotMiddleware(
compiler
)
);
}else{
console.log("production environment.");
app.use(
express.static(
path.resolve('./dist')
)
);
}
console.log('starting server...');
app.listen(
app.get('port')
);
导致报错的是上面初始化webpackDevMiddleware
的地方, 如果去掉这部分代码, 则报错消失, 当然, 程序功能不正常.
最后是webpack.foreground.js
:
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
module.exports = {
devtool: "source-map",
entry: {
app: [
'./src/foreground/app.js'
]
},
output: {
filename: 'assert/bundle.[hash].js',
path: path.resolve(__dirname, '../dist'),
publicPath: '/',
},
target: 'web',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
'env',
'stage-2',
'react'
]
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../src/foreground/index.html'),
inject: 'body',
}),
]
};
vscode
的launch.json
文件如下:
{
"version": "0.2.0",
"configurations": [
{//这个在vs里面可以正常启动调试, 但是没有hot-reload能力, 因为没有执行background/app.js的develop分支
"type": "node",
"request": "launch",
"name": "启动程序",
"program": "${workspaceRoot}/src/background/app.js",
"cwd": "${workspaceRoot}",
"outFiles": [
"${workspaceRoot}/dist/server.*.js"
],
"env": {
"NODE_ENV": "production"
},
"preLaunchTask": "build"
},
{//这个无法启动调试, vscode中报错, 报错信息上文以给出
"type": "node",
"request": "launch",
"name": "调试程序",
"program": "${workspaceRoot}/src/background/app.js",
"cwd": "${workspaceRoot}",
"outFiles": [
"${workspaceRoot}/dist/server.*.js"
],
"env": {
"NODE_ENV": "development"
},
"preLaunchTask": "build"
}
]
}⏎