不正确的行号 - sourcemaps, Webpack 2 Typescript

Incorrect line numbers - sourcemaps, Webpack 2 Typescript

提问人:Brian Ogden 提问时间:7/21/2017 最后编辑:Brian Ogden 更新时间:5/18/2023 访问量:4071

问:

此问题发生在 Chrome 59.0.3071.115 和 Firefox 54.0.1 中

我一直在做很多研究,试图使用 Webpack 2.2.1 和 .我尝试将devtool设置为以下不同的选项:open-browser-webpack-plugin

    //https://webpack.js.org/configuration/devtool/
    //devtool: 'eval', //eval vert fast but line numbers will be wrong
    //devtool: 'eval-source-map', //starts off slow but fast rebuild speed and correct line numbers, supposedly, not correct line numbers for typescript
    //devtool: 'source-map', //very slow, for production, most accurate source maps
    //devtool: 'cheap-module-eval-source-map',
    //devtool: 'inline-source-map',

上面没有选项提供我的源代码的正确行号。devtool

这是 Chrome F12 工具中的一个示例,这是使用 Webpack 选项“eval-source-map”的,该选项也与“cheap-module-eval-source-map”相同:devtool

enter image description here

这是正确的源代码文件,错误的行号:enter image description here

这是Firefox的行号错误:

enter image description here

这里是 login.component.ts,是第 32 行:console.log("hello world");

import { Component, OnDestroy, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { Http } from '@angular/http';
import { ActivatedRoute, Router } from '@angular/router';
import { FormBuilder, FormGroup, FormControl, Validators, AbstractControl, ValidatorFn, FormArray } from '@angular/forms';
import { User } from './login.interface';
import 'rxjs/add/operator/debounceTime';
//Services 
import { LoginService } from './login.service';
import { SpinnerService } from '../core/spinner/spinner.service';
import { DialogService } from "ng2-bootstrap-modal";
import { LoginModal } from './modal/modal.component';
//Animations
import { pageTransition } from '../animation';
import { Animate } from '../core/const/animation.const';


@Component({
  templateUrl: './login.component.html',
  animations: [pageTransition]
})
export class LoginComponent implements OnInit {

  /////////////////
  // CONSTRUCTOR //
  /////////////////
  constructor(
    private spinnerService: SpinnerService,
    private router: Router,
    public http: Http,
    private _fb: FormBuilder,
    private loginService: LoginService,
    private dialogService: DialogService) { console.log("hello world"); }


  //////////////
  // BINDINGS //
  //////////////



  ////////////
  // FIELDS //
  ////////////
  private state: string = Animate.in;
  private background = require('../assets/images/construction-background.jpg');
  private loginForm: FormGroup;
  //Username
  private userNameMessage: any[];
  private userNameError: boolean = false;
  //password
  private passwordMessage: any[];
  private passwordError: boolean;
  private NgbModalOptions = { closeByClickingOutside: true, size: "lg" };
  //ANY VALIDATION OBJECT
  private validationMessages = {
    // Note: these validation messages could easily be populated with a backend server. 
    required: 'This field is required',
    pattern: 'please enter a valid email address',
    minlength: 'I need more letters please'
  }

  ngOnInit() {

    //view animations.
    this.state = (this.state === Animate.in ? Animate.out : Animate.in);


    // Creating the Form Group and Form Controls 
    this.loginForm = this._fb.group({
      userName: ['', [Validators.minLength(2)]],
      password: ['', [Validators.required]],
    });

    const userNameControl = this.loginForm.get('userName');
    const passwordControl = this.loginForm.get('password');

    //Watch User Name Control
    userNameControl.valueChanges
      .debounceTime(1000)
      .subscribe(value => this.userNameMessage = this.setMessage(userNameControl, this.validationMessages, 'userNameError'));

    //Watch Password Control      
    passwordControl.valueChanges
      .debounceTime(1000)
      .subscribe(value => this.passwordMessage = this.setMessage(passwordControl, this.validationMessages, 'passwordError'));

    // Mock Spinner wait time  - http call starts
    this.spinnerService.display(true);
    //http call ends
    setTimeout(() => {
      this.spinnerService.display(false);
    }, 2000);


  }//end ngOnInit



  // LOGIN
  login(resp: boolean): void {
    if (resp) {
      this.router.navigate(['dashboard']);
    } else {
      this.dialogService.addDialog(LoginModal, { message: 'Username or password are not correct' }, this.NgbModalOptions);
    }
  }

  //CLEAR FORM AFTER SUMBIT CLICK
  clearData() {
    const loginForm = this.loginForm;
    loginForm.setValue({
      userName: '',
      password: ''
    })
  }

  //LOGIN CLICK
  loginClick() {
    // GET USER NAME AND PASSWORD TO SEND TO SERVER.
    let body = {
      'username': this.loginForm.get('userName').value,
      'password': this.loginForm.get('password').value
    };
    this.loginService.validateUser(body).subscribe(
      // do something with response , just logging in and routing for now.
      response => this.login(true),
      error => this.login(error)
    );
    //Clear Form
    this.clearData();
  }

  // SET FIELD CONTROLL ERROR MESSAGES 
  setMessage(control: AbstractControl, messages: any, errorId: string): any[] {
    //clear left over messages. If is has one
    this[errorId] = false;

    if ((control.touched || control.dirty) && control.errors) {
      this[errorId] = true;
      // Maps error type to string and returns array of appropriate error messages. 
      return Object.keys(control.errors).map(key => messages[key])
    }
  }


}// End Class

这是我的:webpack.config.js

var webpack = require('webpack'),
    htmlPlugin = require('html-webpack-plugin'),
    revPlugin = require('webpack-rev-replace-plugin'),
    config = require('./build.config.json'),
    path = require('path'),
    extendedDefinePlugin = require('extended-define-webpack-plugin'),
    webpackDelPlugin = require('webpack-del-plugin');
    OpenBrowserPlugin = require('open-browser-webpack-plugin');
    output = require('to-string-loader');

//Note : in package.json the last variable (dev) is the param delivered to this function { env: 'dev' }. 
module.exports = function (env) {

    // Note : '__dirname' is the root file path.
    const ROOT_DIR = path.resolve(__dirname);
    const DIST_DIR = path.join(ROOT_DIR, config.dist);

    console.log(__dirname);
    // If no env make it the dev
    if (!env) {
        env = {};
        env.env = config.envDev;
    }

    console.log('env configuration', env.env);

    // this takes path variables from build.config.json and builds it with given env
    var appConfigPath = config.envs + config.appConfig.replace('{env}', env.env);

    return {
        entry: config.src + config.entry,//main.ts
        output: {
            path: path.join(__dirname, config.dist),
            filename: config.buildjs,
            sourceMapFilename: config.buildjsmap
        },
        module: {
            loaders: [
                { test: /\.html$/, use: 'raw-loader' },
                { test: /\.css$/, use: 'raw-loader' },
                { test: /\.ts$/, 
                    loaders: [ 
                        'ts-loader',
                        'angular2-template-loader', 
                        'angular-router-loader'] 
                },
                { test: /\.scss$/,
                  exclude: /node_modules/,
                  loaders: ['style-loader', 'css-loader', 'sass-loader'],
                },
                //For images. 
                {   test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=app/assets/images/[name].[ext]"},
                {   test: /\.(ttf|eot|woff|woff2)$/,
                    loader: 'file-loader'
                },
            ]
        },
        //https://webpack.js.org/configuration/devtool/
        //devtool: 'eval', //eval vert fast but line numbers will be wrong
        devtool: 'eval-source-map', //starts off slow but fast rebuild speed and correct line numbers, supposedly, not correct line numbers for typescript
        //devtool: 'source-map', //very slow, for production, most accurate source maps
        //devtool: 'cheap-module-eval-source-map',
        //devtool: 'inline-source-map',
        //
        resolve: {
            extensions: ['.js', '.ts','.scss','.css']
        },
        plugins: [
            new htmlPlugin({
                template: config.src + config.index
            }),
            // Not in use from what I can see - Nick July 9th 2017
            new revPlugin({
                cwd: config.src,
                files: '**/*.html',
                outputPageName: function (filename) {
                    return filename;
                },
                modifyReved: function (filename) {
                    return filename.replace(/(\/style\/|\/script\/)/, '')
                }
            }),
            //Makes AppConfig variable available in the application code. 
            new extendedDefinePlugin({
                AppConfig: require(appConfigPath)
            }),
            //Usefull if you need remove some files or folders before compilation processes. 
            //currently not used (no dist file).
            new webpackDelPlugin({match: path.join(DIST_DIR, '*.*')}),
            //opens browser after compilation.
            new OpenBrowserPlugin({ url: 'http://localhost:8080' })
        ]
    }
}

这是我的:tsconfig.json

{
    "compilerOptions": {
        "target": "es5", //most browsers currently understand this version of Javascript
        "experimentalDecorators": true, //Angular2 uses Component,Injectable etc
        "emitDecoratorMetadata": true, //Required for Angular2 to use the metadata in our components
        "sourceMap": true,
        "types": [
            "node",
            "jasmine"
        ]
    }
}

这是我的 npmpackage.json

{
  "name": "angular2-starter",
  "version": "0.1.0",
  "scripts": {
    "test": "karma start",
    "build-dev": "webpack --progress --colors --env.env dev",
    "build-qa": "webpack --progress --colors --env.env qa",
    "build-prd": "webpack -p --progress --colors --env.env prd",
    "postinstall": "typings install",
    "serve": "webpack-dev-server --inline --progress --colors --env.env dev"
  },
  "dependencies": {
    "@angular/animations": "^4.1.3",
    "@angular/common": "^4.1.3",
    "@angular/compiler": "^4.1.3",
    "@angular/compiler-cli": "^4.1.3",
    "@angular/core": "^4.1.3",
    "@angular/forms": "^4.1.3",
    "@angular/http": "^4.1.3",
    "@angular/material": "^2.0.0-beta.5",
    "@angular/platform-browser": "^4.1.3",
    "@angular/platform-browser-dynamic": "^4.1.3",
    "@angular/platform-server": "^4.1.3",
    "@angular/router": "^4.1.3",
    "@angular/cdk": "^2.0.0-beta.8",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.26",
    "angular2-jwt": "^0.2.3",
    "angular2-wizard": "^0.3.0",
    "bootstrap": "^4.0.0-alpha.6",
    "core-js": "2.4.1",
    "font-awesome": "^4.7.0",
    "hammerjs": "^2.0.8",
    "ng2-bootstrap-modal": "1.0.1",
    "ng2-drag-drop": "^2.0.1",
    "reflect-metadata": "0.1.8",
    "rxjs": "^5.0.0-beta.12",
    "systemjs": "0.19.40",
    "typescript": "^2.4.1",
    "zone.js": "^0.7.8"
  },
  "devDependencies": {
    "@types/jasmine": "^2.5.53",
    "angular-router-loader": "^0.6.0",
    "angular2-router-loader": "^0.3.5",
    "angular2-template-loader": "^0.6.2",
    "css-loader": "^0.27.3",
    "extended-define-webpack-plugin": "^0.1.3",
    "file-loader": "^0.10.1",
    "html-webpack-plugin": "^2.28.0",
    "install": "^0.8.7",
    "jasmine": "^2.6.0",
    "karma": "^1.7.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^2.0.4",
    "node-sass": "^4.5.0",
    "npm": "^4.4.1",
    "open-browser-webpack-plugin": "0.0.5",
    "path": "^0.12.7",
    "prepack-webpack-plugin": "^1.1.0",
    "raw-loader": "^0.5.1",
    "sass-loader": "^6.0.3",
    "style-loader": "^0.13.2",
    "to-string-loader": "^1.1.5",
    "ts-loader": "^2.0.1",
    "typings": "^2.1.0",
    "webpack": "^2.2.1",
    "webpack-del-plugin": "0.0.1",
    "webpack-dev-server": "^2.4.1",
    "webpack-merge": "^4.1.0",
    "webpack-rev-replace-plugin": "^0.1.1"
  }
}

我知道我在 Chrome 开发者工具中看到我的 Typescript 文件的编译版本的行号,所以我想知道是否有办法更改我的 Webpack sourcemap 设置以查看 Typescript 编译前的实际行号?login.component.tslogin.component.ts

javascript angular google-chrome 打字稿 webpack

评论

0赞 JGFMK 8/1/2017
我正在过滤类似的问题。这是否与您的问题有关?github.com/webpack/webpack/issues/5186 - 推断使用 webpack 内部行号而不是源行号......
0赞 Ale_Bianco 10/6/2023
要在 Chrome 开发者工具中获取正确的行号,您应该使用指向原始 TypeScript 文件的源映射选项。source-map 选项应该适用于此目的。在 webpack.config.js 中,更新 devtool 选项,如下所示:devtool: 'source-map'
0赞 Jamie Hutber 10/8/2023
奇怪的是,这只是那个版本的兄弟的一个错误?

答: 暂无答案