admin管理员组文章数量:1289582
This issue occurs in Chrome 59.0.3071.115 and Firefox 54.0.1
I have been doing a lot of research on trying to get correct line numbers for my Typescript source code using Webpack 2.2.1 and the open-browser-webpack-plugin
. I have tried setting devtool to the following different options:
///
//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
option above provides the correct line number of my source code.
Here is an example in Chrome F12 Tools, this is with the Webpack devtool
option "eval-source-map" which is the same for "cheap-module-eval-source-map" as well:
That is the right source code file, wrong line number:
And here is Firefox with wrong line number:
And here is the loginponent.ts, the console.log("hello world");
is line 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/modalponent';
//Animations
import { pageTransition } from '../animation';
import { Animate } from '../core/const/animation.const';
@Component({
templateUrl: './loginponent.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
And here is my 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'
},
]
},
///
//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 pilation processes.
//currently not used (no dist file).
new webpackDelPlugin({match: path.join(DIST_DIR, '*.*')}),
//opens browser after pilation.
new OpenBrowserPlugin({ url: 'http://localhost:8080' })
]
}
}
And here is my tsconfig.json
:
{
"pilerOptions": {
"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 ponents
"sourceMap": true,
"types": [
"node",
"jasmine"
]
}
}
And here is my 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/mon": "^4.1.3",
"@angular/piler": "^4.1.3",
"@angular/piler-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"
}
}
I understand that I am seeing the line number of the plied version of my Typescript file, loginponent.ts
in Chrome Developer Tools so I am wondering if there is a way to change my Webpack sourcemap settings to see the actual line number of loginponent.ts
before Typescript pilation?
This issue occurs in Chrome 59.0.3071.115 and Firefox 54.0.1
I have been doing a lot of research on trying to get correct line numbers for my Typescript source code using Webpack 2.2.1 and the open-browser-webpack-plugin
. I have tried setting devtool to the following different options:
//https://webpack.js/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
option above provides the correct line number of my source code.
Here is an example in Chrome F12 Tools, this is with the Webpack devtool
option "eval-source-map" which is the same for "cheap-module-eval-source-map" as well:
That is the right source code file, wrong line number:
And here is Firefox with wrong line number:
And here is the login.ponent.ts, the console.log("hello world");
is line 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.ponent';
//Animations
import { pageTransition } from '../animation';
import { Animate } from '../core/const/animation.const';
@Component({
templateUrl: './login.ponent.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
And here is my 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/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 pilation processes.
//currently not used (no dist file).
new webpackDelPlugin({match: path.join(DIST_DIR, '*.*')}),
//opens browser after pilation.
new OpenBrowserPlugin({ url: 'http://localhost:8080' })
]
}
}
And here is my tsconfig.json
:
{
"pilerOptions": {
"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 ponents
"sourceMap": true,
"types": [
"node",
"jasmine"
]
}
}
And here is my 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/mon": "^4.1.3",
"@angular/piler": "^4.1.3",
"@angular/piler-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"
}
}
I understand that I am seeing the line number of the plied version of my Typescript file, login.ponent.ts
in Chrome Developer Tools so I am wondering if there is a way to change my Webpack sourcemap settings to see the actual line number of login.ponent.ts
before Typescript pilation?
- 1 I was filtering on similar issues. Does this correlate to your issue? github./webpack/webpack/issues/5186 - infers uses a webpack internal line number not the source one... – JGFMK Commented Jul 31, 2017 at 18:38
- 2 To get correct line numbers in your Chrome Developer Tools, you should use a source map option that points to your original TypeScript files. The source-map option should work for this purpose. In your webpack.config.js, update the devtool option as follows: devtool: 'source-map' – Ale_Bianco Commented Oct 6, 2023 at 14:22
- 1 Surly this is just a bug on that version of the broswers? – Jamie Hutber Commented Oct 7, 2023 at 21:26
- 1 Does this help you? stackoverflow./questions/47346252/… – Jonathan Rys Commented Jan 7, 2024 at 20:32
1 Answer
Reset to default 1I had this issue in the past, my workaround was setting into webpack.config.js
devtool: 'inline-source-map'
and inside tsconfig.json
sourceMap: true
But I didn't like to release my source map so, after some research, I used awesome-typescript-loader instead of ts-loader
and it worked just fine.
Hope that helps, here are some other useful links I have found:
- https://github./webpack/webpack/issues/12025
- https://github./TypeStrong/ts-loader/issues/882
本文标签: javascriptIncorrect line numberssourcemapsWebpack 2 TypescriptStack Overflow
版权声明:本文标题:javascript - Incorrect line numbers - sourcemaps, Webpack 2 Typescript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741433860a2378520.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论