简体   繁体   中英

Node Webpack eval() sourcemaps

I am struggling setting up a Node project with TypeScript. My workflow is: I run a Node script using nodemon. The node script creates a webpack compiler instance and sets the filesystem to MemoryFS. The webpack config includes loaders for TypeScript and Babel. After webpack has finished compiling, if there are errors, I throw then, if not I fetch the result with MemoryFS and eval() it to run the code.

All of that works fine. But I tried to add sourcemaps support. I added a banner plugin in webpack which adds 'source-map-support'. In webpack, I set the devtool to 'source-map'. In tsconfig.json, I have the sourcemaps option enabled. In the src/index.ts I just throw an error, and at runtime Node doesn't tell me where did the error occur. (the sourcemap)

But if I run webpack normally, and then I run it using node dist/bundle.js . It is working.

I think there is a problem because of me using eval() to run the compiled output.

src/index.ts:

console.log('Hello world');

throw new Error('not');

build.js:

const path = require('path');
const webpack = require('webpack');
const MemoryFS = require('memory-fs');

const fs = new MemoryFS();

const config = require('./webpack.config');

const compiler = webpack(config);

compiler.outputFileSystem = fs;

compiler.run((err, stats) => {
    console.clear();

    const jsonStats = stats.toJson();

    if(jsonStats.errors.length > 0 || jsonStats.warnings.length > 0)
        return console.log(jsonStats.warning, jsonStats.errors);

    const result = fs.readFileSync(path.resolve(__dirname, 'dist', 'bundle.js')).toString();

    eval(result);
});

webpack.config.js:

const path = require('path');
const webpack = require('webpack');

const SRC_DIR = path.resolve(__dirname, 'src');
const DIST_DIR = path.resolve(__dirname, 'dist');

module.exports = {
    entry: SRC_DIR + '/index.ts',
    output: {
        path: DIST_DIR,
        filename: 'bundle.js'
    },
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.ts$/,
                use: [
                    { loader: 'babel-loader' },
                    { loader: 'ts-loader' },
                    { loader: 'tslint-loader' }
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.ts', '.js', '.json']
    },
    target: 'node',
    plugins: [
        new webpack.BannerPlugin({
            raw: true,
            entryOnly: false,
            banner: 'require("source-map-support").install();'
        }),
        new webpack.NoEmitOnErrorsPlugin()
    ]
};

After running webpack normally and executing the code ( webpack && node dist\\bundle.js , as expected):

C:\Users\shachar\Desktop\graph\dist\webpack:\src\index.ts:3
throw new Error('not');
    ^
Error: not
    at Object.<anonymous> (C:\Users\shachar\Desktop\graph\dist\webpack:\src\index.ts:3:7)
    at __webpack_require__ (C:\Users\shachar\Desktop\graph\dist\webpack:\webpack\bootstrap a6ba0885ca7e8b14ee63:19:1)
    at C:\Users\shachar\Desktop\graph\dist\webpack:\webpack\bootstrap a6ba0885ca7e8b14ee63:62:1
    at Object.<anonymous> (C:\Users\shachar\Desktop\graph\dist\bundle.js:67:10)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)

Running it using build.js :

Hello world
Error: not
    at Object.eval (eval at compiler.run (C:\Users\shachar\Desktop\graph\build.js:23:5), <anonymous>:75:7)
    at __webpack_require__ (eval at compiler.run (C:\Users\shachar\Desktop\graph\build.js:23:5), <anonymous>:21:30)
    at eval (eval at compiler.run (C:\Users\shachar\Desktop\graph\build.js:23:5), <anonymous>:64:18)
    at eval (eval at compiler.run (C:\Users\shachar\Desktop\graph\build.js:23:5), <anonymous>:67:10)
    at compiler.run (C:\Users\shachar\Desktop\graph\build.js:23:5)
    at emitRecords.err (C:\Users\shachar\Desktop\graph\node_modules\webpack\lib\Compiler.js:269:13)
    at Compiler.emitRecords (C:\Users\shachar\Desktop\graph\node_modules\webpack\lib\Compiler.js:375:38)
    at emitAssets.err (C:\Users\shachar\Desktop\graph\node_modules\webpack\lib\Compiler.js:262:10)
    at applyPluginsAsyncSeries1.err (C:\Users\shachar\Desktop\graph\node_modules\webpack\lib\Compiler.js:368:12)
    at next (C:\Users\shachar\Desktop\graph\node_modules\tapable\lib\Tapable.js:218:11)

Thanks for any help!

When you use eval to run the code, Node will have no idea about the source map. Perhaps you can try to run a child node process instead of using eval to run the result, or is there any reason you're using eval ? See https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM