vscode编译Node.js项目由于开发环境和线上环境差异导致某些模块找不到

背景介绍:

我这有一个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',
        }),
    ]
};

vscodelaunch.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"
        }
    ]
}⏎ 
阅读 2.7k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题