无法使用 webpack2 生成外部源映射
Cannot produce external source map with webpack2
将 Angular 项目从 webpack1 迁移到 webpack2 后出现问题。
除了 sourcemaps 之外,一切都很好。
它在我的 JS 文件中嵌入了一个 sourcemap 作为 base64 编码的字符串。
它当然会创建非常大的文件。
我想在产品中有单独的地图文件。
然而,我所有控制源地图生成的尝试都没有成功。
我尝试使用 uglifyjs 禁用它们,我尝试在 tsconfig.json 中禁用它们,当然我使用了设置为 'source-map' 的 devtool 参数。
我已经尝试了我能想到的一切。
我也尝试更改我的打字稿加载器,但没有结果。
我的印象是我的行为与我选择 'inline-source-map' 而不是 'source-map' 时的行为相同。
这是我的 webpack 配置以及我的 tsconfig 和 package.json
提前感谢您的帮助!
Webpack 配置:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var WebpackMd5Hash = require('webpack-md5-hash');
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');
var UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
var loginUrl = 'https://renaissance-authent.xxx.xx';//'http://localhost:52445';
var apiUrl = 'http://localhost:50519';
var clientSiteUrl = 'http://localhost:10123';
var isProd = (process.env.NODE_ENV == 'prod' || process.env.NODE_ENV == 'production');
if (isProd) {
apiUrl = '/api';
clientSiteUrl = 'https://renaissance-client.xxx.xx';
loginUrl = 'https://renaissance-authent.xxx.xx';
}
const METADATA = {
title: 'xxx',
baseUrl: '/',
};
function isExternal(module) {
var userRequest = module.userRequest;
if (typeof userRequest !== 'string') {
return false;
}
return userRequest.indexOf('node_modules') >= 0;
}
var plugins = new Array();
plugins.push(new webpack.DefinePlugin({
'process.env.API_URL': JSON.stringify(apiUrl),
'process.env.CLIENTSITE_URL': JSON.stringify(clientSiteUrl),
'process.env.LOGIN_URL': JSON.stringify(loginUrl)
}));
// Ignore moment locals other than English
plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\]locale$/, /en/));
// Fixes errors with Angular
plugins.push(new webpack.ContextReplacementPlugin(
/angular(\|\/)core(\|\/)@angular/,
path.join(__dirname, 'app/')
));
if (isProd) {
console.log('Production Configuration');
// Split vendor code and app code
plugins.push(new CommonsChunkPlugin({
name: 'vendor',
chunks: ['app'],
minChunks: function (module) {
return isExternal(module);
}
}));
// MD5 hash on generated chunks
plugins.push(new WebpackMd5Hash());
// Minimize JS code
plugins.push(new UglifyJsPlugin({
beautify: false,
sourceMap: true,
output: {
comments: false
},
mangle: {
screw_ie8: true
},
compress: {
screw_ie8: true,
warnings: false,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: false
},
}));
}
// Provide jQuery as a global plugin
plugins.push(new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery'
}));
// Move CSS to a separate file
plugins.push(new ExtractTextPlugin("[name].[chunkhash].css"));
// Generate the index.html
plugins.push(new HtmlWebpackPlugin({
template: './app/index.html',
chunksSortMode: 'dependency'
}));
plugins.push(new CopyWebpackPlugin([
{ from: 'Web.config' },
{ from: 'Content/favicon.png', to: 'images/favicon.png' },
{ from: 'Content/AppleIcon_180_180.png', to: 'images/AppleIcon_180_180.png' }
]));
plugins.push(new WebpackNotifierPlugin());
module.exports = {
entry: {
app: './app/main.ts'
},
output: {
path: path.join(__dirname, 'wwwroot/'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].map',
publicPath: '/'
},
resolve: {
extensions: ['.ts', '.js', '.css', '.scss'],
alias: {
highcharts$: "highcharts/highstock.src"
}
},
devServer: {
historyApiFallback: true
},
devtool: 'source-map',
module: {
rules: [
/*
{
test: /\.ts$/,
use: [{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'tsconfig.json'
}
}, {
loader: 'angular2-template-loader'
}]
},
*/
{
test: /\.ts$/,
loader: 'ts-loader'
},
{
test: /\.html$/,
loader: 'html-loader?minimize=false'
},
{
test: /\.(gif|png|jpe?g|svg|ico)$/i,
loader: 'file-loader?name=images/[name].[ext]'
},
{
test: /\.(woff|woff2|ttf|eot)$/i,
loader: 'file-loader?name=fonts/[name].[ext]'
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
},
{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader' })
}
]
},
plugins: plugins
}
tsconfig
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"inlineSourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"exclude": [
"node_modules"
]
}
Package.json
{
"name": "xxxx",
"version": "0.0.0",
"scripts": {
"clean": "rimraf wwwroot/*",
"build": "set NODE_ENV=production&& npm run clean && webpack -d --color --display-error-details",
"start": "webpack-dev-server --inline --progress --port 10124"
},
"keywords": [ ],
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"dependencies": { },
"devDependencies": {
"typescript": "2.1.4",
"typings": "2.1.0",
"canonical-path": "0.0.2",
"@angular/compiler": "4.0.2",
"@angular/common": "4.0.2",
"@angular/core": "4.0.2",
"@angular/forms": "4.0.2",
"@angular/http": "4.0.2",
"@angular/platform-browser": "4.0.2",
"@angular/platform-browser-dynamic": "4.0.2",
"@angular/router": "4.0.2",
"@angular/upgrade": "4.0.2",
"angular-in-memory-web-api": "0.3.1",
"bootstrap": "3.3.7",
"bootstrap-sass": "3.3.7",
"font-awesome": "4.7.0",
"jquery": "3.2.1",
"lato-font": "2.0.0",
"systemjs": "0.20.12",
"core-js": "2.4.1",
"reflect-metadata": "0.1.10",
"rxjs": "5.3.0",
"zone.js": "0.8.5",
"angular2-highcharts": "0.5.5",
"mydatepicker": "1.9.7",
"moment": "2.18.1",
"file-saver": "1.3.3",
"@types/filesaver": "0.0.30",
"webpack": "2.4.1",
"webpack-merge": "4.1.0",
"webpack-dev-server": "2.4.2",
"html-webpack-plugin": "2.28.0",
"ts-loader": "2.0.3",
"copy-webpack-plugin": "4.0.1",
"webpack-md5-hash": "0.0.5",
"awesome-typescript-loader": "3.1.2",
"angular2-template-loader": "0.6.2",
"html-loader": "0.4.5",
"file-loader": "0.11.1",
"style-loader": "0.16.1",
"sass-loader": "4.1.1",
"css-loader": "0.28.0",
"raw-loader": "0.5.1",
"node-sass": "4.5.2",
"extract-text-webpack-plugin": "2.1.0",
"rimraf": "2.6.1",
"webpack-notifier": "1.5.0"
},
"repository": { }
}
终于找到问题了。
我正在将参数 -d 传递给 webpack。
这恰好强制了源映射行为。
改用-p,好多了。当然可以。
我保留它以防它对某人有帮助。
我过于关注配置,以至于忘记了控制台参数。
将 Angular 项目从 webpack1 迁移到 webpack2 后出现问题。 除了 sourcemaps 之外,一切都很好。 它在我的 JS 文件中嵌入了一个 sourcemap 作为 base64 编码的字符串。 它当然会创建非常大的文件。
我想在产品中有单独的地图文件。 然而,我所有控制源地图生成的尝试都没有成功。 我尝试使用 uglifyjs 禁用它们,我尝试在 tsconfig.json 中禁用它们,当然我使用了设置为 'source-map' 的 devtool 参数。 我已经尝试了我能想到的一切。 我也尝试更改我的打字稿加载器,但没有结果。
我的印象是我的行为与我选择 'inline-source-map' 而不是 'source-map' 时的行为相同。
这是我的 webpack 配置以及我的 tsconfig 和 package.json
提前感谢您的帮助!
Webpack 配置:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var WebpackMd5Hash = require('webpack-md5-hash');
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');
var UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
var loginUrl = 'https://renaissance-authent.xxx.xx';//'http://localhost:52445';
var apiUrl = 'http://localhost:50519';
var clientSiteUrl = 'http://localhost:10123';
var isProd = (process.env.NODE_ENV == 'prod' || process.env.NODE_ENV == 'production');
if (isProd) {
apiUrl = '/api';
clientSiteUrl = 'https://renaissance-client.xxx.xx';
loginUrl = 'https://renaissance-authent.xxx.xx';
}
const METADATA = {
title: 'xxx',
baseUrl: '/',
};
function isExternal(module) {
var userRequest = module.userRequest;
if (typeof userRequest !== 'string') {
return false;
}
return userRequest.indexOf('node_modules') >= 0;
}
var plugins = new Array();
plugins.push(new webpack.DefinePlugin({
'process.env.API_URL': JSON.stringify(apiUrl),
'process.env.CLIENTSITE_URL': JSON.stringify(clientSiteUrl),
'process.env.LOGIN_URL': JSON.stringify(loginUrl)
}));
// Ignore moment locals other than English
plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\]locale$/, /en/));
// Fixes errors with Angular
plugins.push(new webpack.ContextReplacementPlugin(
/angular(\|\/)core(\|\/)@angular/,
path.join(__dirname, 'app/')
));
if (isProd) {
console.log('Production Configuration');
// Split vendor code and app code
plugins.push(new CommonsChunkPlugin({
name: 'vendor',
chunks: ['app'],
minChunks: function (module) {
return isExternal(module);
}
}));
// MD5 hash on generated chunks
plugins.push(new WebpackMd5Hash());
// Minimize JS code
plugins.push(new UglifyJsPlugin({
beautify: false,
sourceMap: true,
output: {
comments: false
},
mangle: {
screw_ie8: true
},
compress: {
screw_ie8: true,
warnings: false,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: false
},
}));
}
// Provide jQuery as a global plugin
plugins.push(new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery'
}));
// Move CSS to a separate file
plugins.push(new ExtractTextPlugin("[name].[chunkhash].css"));
// Generate the index.html
plugins.push(new HtmlWebpackPlugin({
template: './app/index.html',
chunksSortMode: 'dependency'
}));
plugins.push(new CopyWebpackPlugin([
{ from: 'Web.config' },
{ from: 'Content/favicon.png', to: 'images/favicon.png' },
{ from: 'Content/AppleIcon_180_180.png', to: 'images/AppleIcon_180_180.png' }
]));
plugins.push(new WebpackNotifierPlugin());
module.exports = {
entry: {
app: './app/main.ts'
},
output: {
path: path.join(__dirname, 'wwwroot/'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].map',
publicPath: '/'
},
resolve: {
extensions: ['.ts', '.js', '.css', '.scss'],
alias: {
highcharts$: "highcharts/highstock.src"
}
},
devServer: {
historyApiFallback: true
},
devtool: 'source-map',
module: {
rules: [
/*
{
test: /\.ts$/,
use: [{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'tsconfig.json'
}
}, {
loader: 'angular2-template-loader'
}]
},
*/
{
test: /\.ts$/,
loader: 'ts-loader'
},
{
test: /\.html$/,
loader: 'html-loader?minimize=false'
},
{
test: /\.(gif|png|jpe?g|svg|ico)$/i,
loader: 'file-loader?name=images/[name].[ext]'
},
{
test: /\.(woff|woff2|ttf|eot)$/i,
loader: 'file-loader?name=fonts/[name].[ext]'
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
},
{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader' })
}
]
},
plugins: plugins
}
tsconfig
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"inlineSourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"exclude": [
"node_modules"
]
}
Package.json
{
"name": "xxxx",
"version": "0.0.0",
"scripts": {
"clean": "rimraf wwwroot/*",
"build": "set NODE_ENV=production&& npm run clean && webpack -d --color --display-error-details",
"start": "webpack-dev-server --inline --progress --port 10124"
},
"keywords": [ ],
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
],
"dependencies": { },
"devDependencies": {
"typescript": "2.1.4",
"typings": "2.1.0",
"canonical-path": "0.0.2",
"@angular/compiler": "4.0.2",
"@angular/common": "4.0.2",
"@angular/core": "4.0.2",
"@angular/forms": "4.0.2",
"@angular/http": "4.0.2",
"@angular/platform-browser": "4.0.2",
"@angular/platform-browser-dynamic": "4.0.2",
"@angular/router": "4.0.2",
"@angular/upgrade": "4.0.2",
"angular-in-memory-web-api": "0.3.1",
"bootstrap": "3.3.7",
"bootstrap-sass": "3.3.7",
"font-awesome": "4.7.0",
"jquery": "3.2.1",
"lato-font": "2.0.0",
"systemjs": "0.20.12",
"core-js": "2.4.1",
"reflect-metadata": "0.1.10",
"rxjs": "5.3.0",
"zone.js": "0.8.5",
"angular2-highcharts": "0.5.5",
"mydatepicker": "1.9.7",
"moment": "2.18.1",
"file-saver": "1.3.3",
"@types/filesaver": "0.0.30",
"webpack": "2.4.1",
"webpack-merge": "4.1.0",
"webpack-dev-server": "2.4.2",
"html-webpack-plugin": "2.28.0",
"ts-loader": "2.0.3",
"copy-webpack-plugin": "4.0.1",
"webpack-md5-hash": "0.0.5",
"awesome-typescript-loader": "3.1.2",
"angular2-template-loader": "0.6.2",
"html-loader": "0.4.5",
"file-loader": "0.11.1",
"style-loader": "0.16.1",
"sass-loader": "4.1.1",
"css-loader": "0.28.0",
"raw-loader": "0.5.1",
"node-sass": "4.5.2",
"extract-text-webpack-plugin": "2.1.0",
"rimraf": "2.6.1",
"webpack-notifier": "1.5.0"
},
"repository": { }
}
终于找到问题了。 我正在将参数 -d 传递给 webpack。 这恰好强制了源映射行为。
改用-p,好多了。当然可以。
我保留它以防它对某人有帮助。 我过于关注配置,以至于忘记了控制台参数。