Javascript 行号不正确-sourcemaps,网页包2 Typescript

Javascript 行号不正确-sourcemaps,网页包2 Typescript,javascript,angular,google-chrome,typescript,webpack,Javascript,Angular,Google Chrome,Typescript,Webpack,这个问题出现在Chrome 59.0.3071.115和Firefox 54.0.1中 我一直在做大量研究,试图使用Webpack2.2.1和开放浏览器Webpack插件为我的Typescript源代码获取正确的行号。我已尝试设置为以下不同选项: //https://webpack.js.org/configuration/devtool/ //devtool: 'eval', //eval vert fast but line numbers will be wrong

这个问题出现在Chrome 59.0.3071.115和Firefox 54.0.1中

我一直在做大量研究,试图使用Webpack2.2.1和
开放浏览器Webpack插件
为我的Typescript源代码获取正确的行号。我已尝试设置为以下不同选项:

    //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',
上面的No
devtool
选项提供了源代码的正确行号

以下是Chrome F12工具中的一个示例,它与Webpack
devtool
选项“eval source map”一起使用,该选项与“廉价模块eval source map”相同:

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

以下是错误行号的Firefox:

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

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"
        ]
    }
}
这是我的npm
package.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 Developer Tools中的
login.component.ts
,因此我想知道是否有办法在Typescript编译之前更改我的网页sourcemap设置,以查看
login.component.ts
的实际行号?

这是以前很多人在没有解决方案的情况下面临的已知问题。chrome调试器似乎有一些关于类似行为的开放bug:


在这种情况下,我建议使用firefox。

github页面用于webpack,这甚至很难确定它是v1还是v2。我确实看到了很多问题。但这可能与v1有关。我确实在这里看到它引用了-quote:删除和添加行是受支持的-那么是v1还是v2?想知道您是否尝试过吗?您确定
tsconfig.json
中的
sourceMap
设置为
true
?@shotor或者,我在我的问题中添加了我的tsconfig.json供您参考verfiy@JGFMK我正在使用Webpack2.2.1,我为您将我的package.json添加到verify@JGFMK你建议我试试源代码列表地图插件吗?我添加了Firefox屏幕截图