mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 02:24:10 +08:00
feat(@angular-devkit/build-angular): fine grain settings for sourceMaps (#13062)
* feat(@angular/cli): update schema to match new `sourceMap` * feat(@angular-devkit/build-angular): fine grain settings for sourceMaps This PR add more control over which sourceMaps you want, Now you can enable sourceMaps for scripts only, styles only or both. Also we added another functionality which are hidden sourcemaps. These are normaly used for error reporting tools. Fixes #7527
This commit is contained in:
parent
ddbc7f201a
commit
8516d68213
@ -633,9 +633,39 @@
|
||||
"default": false
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps used for error reporting tools.",
|
||||
"default": false
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
@ -1045,8 +1075,34 @@
|
||||
"description": "Build using Ahead of Time compilation."
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps."
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
@ -1189,9 +1245,34 @@
|
||||
"description": "Defines the build environment."
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"progress": {
|
||||
"type": "boolean",
|
||||
@ -1455,9 +1536,39 @@
|
||||
"description": "The path where style resources will be placed, relative to outputPath."
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps used for error reporting tools.",
|
||||
"default": false
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
|
@ -24,6 +24,9 @@ export interface BuildOptions {
|
||||
resourcesOutputPath?: string;
|
||||
aot?: boolean;
|
||||
sourceMap?: boolean;
|
||||
scriptsSourceMap?: boolean;
|
||||
stylesSourceMap?: boolean;
|
||||
hiddenSourceMap?: boolean;
|
||||
vendorSourceMap?: boolean;
|
||||
evalSourceMap?: boolean;
|
||||
vendorChunk?: boolean;
|
||||
|
@ -10,7 +10,7 @@ import * as path from 'path';
|
||||
import { IndexHtmlWebpackPlugin } from '../../plugins/index-html-webpack-plugin';
|
||||
import { generateEntryPoints } from '../../utilities/package-chunk-sort';
|
||||
import { WebpackConfigOptions } from '../build-options';
|
||||
import { normalizeExtraEntryPoints } from './utils';
|
||||
import { getSourceMapDevTool, normalizeExtraEntryPoints } from './utils';
|
||||
|
||||
const SubresourceIntegrityPlugin = require('webpack-subresource-integrity');
|
||||
|
||||
@ -19,16 +19,11 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
|
||||
const { root, buildOptions } = wco;
|
||||
const extraPlugins = [];
|
||||
|
||||
let sourcemaps: string | false = false;
|
||||
if (buildOptions.sourceMap) {
|
||||
// See https://webpack.js.org/configuration/devtool/ for sourcemap types.
|
||||
if (buildOptions.evalSourceMap && !buildOptions.optimization) {
|
||||
// Produce eval sourcemaps for development with serve, which are faster.
|
||||
sourcemaps = 'eval';
|
||||
} else {
|
||||
// Produce full separate sourcemaps for production.
|
||||
sourcemaps = 'source-map';
|
||||
}
|
||||
let isEval = false;
|
||||
// See https://webpack.js.org/configuration/devtool/ for sourcemap types.
|
||||
if (buildOptions.sourceMap && buildOptions.evalSourceMap && !buildOptions.optimization) {
|
||||
// Produce eval sourcemaps for development with serve, which are faster.
|
||||
isEval = true;
|
||||
}
|
||||
|
||||
if (buildOptions.index) {
|
||||
@ -59,11 +54,25 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
|
||||
}));
|
||||
}
|
||||
|
||||
if (!isEval && buildOptions.sourceMap) {
|
||||
const {
|
||||
scriptsSourceMap = false,
|
||||
stylesSourceMap = false,
|
||||
hiddenSourceMap = false,
|
||||
} = buildOptions;
|
||||
|
||||
extraPlugins.push(getSourceMapDevTool(
|
||||
scriptsSourceMap,
|
||||
stylesSourceMap,
|
||||
hiddenSourceMap,
|
||||
));
|
||||
}
|
||||
|
||||
const globalStylesBundleNames = normalizeExtraEntryPoints(buildOptions.styles, 'styles')
|
||||
.map(style => style.bundleName);
|
||||
|
||||
return {
|
||||
devtool: sourcemaps,
|
||||
devtool: isEval ? 'eval' : false,
|
||||
resolve: {
|
||||
mainFields: [
|
||||
...(wco.supportES2015 ? ['es2015'] : []),
|
||||
|
@ -15,7 +15,7 @@ import { ScriptsWebpackPlugin } from '../../plugins/scripts-webpack-plugin';
|
||||
import { findUp } from '../../utilities/find-up';
|
||||
import { isDirectory } from '../../utilities/is-directory';
|
||||
import { requireProjectModule } from '../../utilities/require-project-module';
|
||||
import { WebpackConfigOptions } from '../build-options';
|
||||
import { BuildOptions, WebpackConfigOptions } from '../build-options';
|
||||
import { getOutputHashFormat, normalizeExtraEntryPoints } from './utils';
|
||||
|
||||
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
|
||||
@ -102,7 +102,7 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
|
||||
|
||||
extraPlugins.push(new ScriptsWebpackPlugin({
|
||||
name: bundleName,
|
||||
sourceMap: buildOptions.sourceMap,
|
||||
sourceMap: buildOptions.scriptsSourceMap,
|
||||
filename: `${path.basename(bundleName)}${hash}.js`,
|
||||
scripts: script.paths,
|
||||
basePath: projectRoot,
|
||||
@ -174,7 +174,7 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
|
||||
use: [
|
||||
{
|
||||
loader: buildOptimizerLoader,
|
||||
options: { sourceMap: buildOptions.sourceMap },
|
||||
options: { sourceMap: buildOptions.scriptsSourceMap },
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -297,12 +297,12 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
|
||||
// TODO: check with Mike what this feature needs.
|
||||
new BundleBudgetPlugin({ budgets: buildOptions.budgets }),
|
||||
new CleanCssWebpackPlugin({
|
||||
sourceMap: buildOptions.sourceMap,
|
||||
sourceMap: buildOptions.stylesSourceMap,
|
||||
// component styles retain their original file name
|
||||
test: (file) => /\.(?:css|scss|sass|less|styl)$/.test(file),
|
||||
}),
|
||||
new TerserPlugin({
|
||||
sourceMap: buildOptions.sourceMap,
|
||||
sourceMap: buildOptions.scriptsSourceMap,
|
||||
parallel: true,
|
||||
cache: true,
|
||||
terserOptions,
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
import { Configuration } from 'webpack';
|
||||
import { WebpackConfigOptions } from '../build-options';
|
||||
import { getSourceMapDevTool } from './utils';
|
||||
|
||||
|
||||
/**
|
||||
@ -15,8 +16,22 @@ import { WebpackConfigOptions } from '../build-options';
|
||||
*/
|
||||
export function getServerConfig(wco: WebpackConfigOptions) {
|
||||
|
||||
const extraPlugins = [];
|
||||
if (wco.buildOptions.sourceMap) {
|
||||
const {
|
||||
scriptsSourceMap = false,
|
||||
stylesSourceMap = false,
|
||||
hiddenSourceMap = false,
|
||||
} = wco.buildOptions;
|
||||
|
||||
extraPlugins.push(getSourceMapDevTool(
|
||||
scriptsSourceMap,
|
||||
stylesSourceMap,
|
||||
hiddenSourceMap,
|
||||
));
|
||||
}
|
||||
|
||||
const config: Configuration = {
|
||||
devtool: wco.buildOptions.sourceMap ? 'source-map' : false,
|
||||
resolve: {
|
||||
mainFields: [
|
||||
...(wco.supportES2015 ? ['es2015'] : []),
|
||||
@ -27,6 +42,7 @@ export function getServerConfig(wco: WebpackConfigOptions) {
|
||||
output: {
|
||||
libraryTarget: 'commonjs',
|
||||
},
|
||||
plugins: extraPlugins,
|
||||
node: false,
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,8 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
||||
const entryPoints: { [key: string]: string[] } = {};
|
||||
const globalStylePaths: string[] = [];
|
||||
const extraPlugins = [];
|
||||
const cssSourceMap = buildOptions.sourceMap;
|
||||
|
||||
const cssSourceMap = buildOptions.stylesSourceMap;
|
||||
|
||||
// Determine hashing format.
|
||||
const hashFormat = getOutputHashFormat(buildOptions.outputHashing as string);
|
||||
@ -187,7 +188,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
||||
options: {
|
||||
ident: 'embedded',
|
||||
plugins: postcssPluginCreator,
|
||||
sourceMap: cssSourceMap ? 'inline' : false,
|
||||
sourceMap: cssSourceMap && !buildOptions.hiddenSourceMap ? 'inline' : false,
|
||||
},
|
||||
},
|
||||
...(use as webpack.Loader[]),
|
||||
@ -208,7 +209,10 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
||||
options: {
|
||||
ident: buildOptions.extractCss ? 'extracted' : 'embedded',
|
||||
plugins: postcssPluginCreator,
|
||||
sourceMap: cssSourceMap && !buildOptions.extractCss ? 'inline' : cssSourceMap,
|
||||
sourceMap: cssSourceMap
|
||||
&& !buildOptions.extractCss
|
||||
&& !buildOptions.hiddenSourceMap
|
||||
? 'inline' : cssSourceMap,
|
||||
},
|
||||
},
|
||||
...(use as webpack.Loader[]),
|
||||
|
@ -10,6 +10,7 @@ import * as glob from 'glob';
|
||||
import * as path from 'path';
|
||||
import * as webpack from 'webpack';
|
||||
import { WebpackConfigOptions, WebpackTestOptions } from '../build-options';
|
||||
import { getSourceMapDevTool } from './utils';
|
||||
|
||||
|
||||
/**
|
||||
@ -55,6 +56,20 @@ export function getTestConfig(
|
||||
});
|
||||
}
|
||||
|
||||
if (wco.buildOptions.sourceMap) {
|
||||
const {
|
||||
scriptsSourceMap = false,
|
||||
stylesSourceMap = false,
|
||||
} = wco.buildOptions;
|
||||
|
||||
extraPlugins.push(getSourceMapDevTool(
|
||||
scriptsSourceMap,
|
||||
stylesSourceMap,
|
||||
false,
|
||||
true,
|
||||
));
|
||||
}
|
||||
|
||||
return {
|
||||
mode: 'development',
|
||||
resolve: {
|
||||
@ -63,7 +78,7 @@ export function getTestConfig(
|
||||
'browser', 'module', 'main',
|
||||
],
|
||||
},
|
||||
devtool: buildOptions.sourceMap ? 'inline-source-map' : 'eval',
|
||||
devtool: buildOptions.sourceMap ? false : 'eval',
|
||||
entry: {
|
||||
main: path.resolve(root, buildOptions.main),
|
||||
},
|
||||
|
@ -75,7 +75,7 @@ function _createAotPlugin(
|
||||
locale: buildOptions.i18nLocale,
|
||||
platform: buildOptions.platform === 'server' ? PLATFORM.Server : PLATFORM.Browser,
|
||||
missingTranslation: buildOptions.i18nMissingTranslation,
|
||||
sourceMap: buildOptions.sourceMap,
|
||||
sourceMap: buildOptions.scriptsSourceMap,
|
||||
additionalLazyModules,
|
||||
hostReplacementPaths,
|
||||
nameLazyFiles: buildOptions.namedChunks,
|
||||
@ -108,7 +108,7 @@ export function getAotConfig(
|
||||
if (buildOptions.buildOptimizer) {
|
||||
loaders.unshift({
|
||||
loader: buildOptimizerLoader,
|
||||
options: { sourceMap: buildOptions.sourceMap }
|
||||
options: { sourceMap: buildOptions.scriptsSourceMap }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
import * as path from 'path';
|
||||
import { basename, normalize } from '@angular-devkit/core';
|
||||
import { ExtraEntryPoint, ExtraEntryPointObject } from '../../../browser/schema';
|
||||
import { SourceMapDevToolPlugin } from 'webpack';
|
||||
|
||||
export const ngAppResolve = (resolvePath: string): string => {
|
||||
return path.resolve(process.cwd(), resolvePath);
|
||||
@ -66,3 +67,25 @@ export function normalizeExtraEntryPoints(
|
||||
return normalizedEntry;
|
||||
})
|
||||
}
|
||||
|
||||
export function getSourceMapDevTool(
|
||||
scriptsSourceMap: boolean,
|
||||
stylesSourceMap: boolean,
|
||||
hiddenSourceMap = false,
|
||||
inlineSourceMap = false,
|
||||
): SourceMapDevToolPlugin {
|
||||
const include = [];
|
||||
if (scriptsSourceMap) {
|
||||
include.push(/js$/);
|
||||
}
|
||||
|
||||
if (stylesSourceMap) {
|
||||
include.push(/css$/);
|
||||
}
|
||||
|
||||
return new SourceMapDevToolPlugin({
|
||||
filename: inlineSourceMap ? undefined : '[file].map',
|
||||
include,
|
||||
append: hiddenSourceMap ? false : undefined,
|
||||
});
|
||||
}
|
||||
|
@ -34,8 +34,18 @@ import {
|
||||
statsToString,
|
||||
statsWarningsToString,
|
||||
} from '../angular-cli-files/utilities/stats';
|
||||
import { defaultProgress, normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
|
||||
import { AssetPatternObject, BrowserBuilderSchema, CurrentFileReplacement } from './schema';
|
||||
import {
|
||||
NormalizedSourceMaps,
|
||||
defaultProgress,
|
||||
normalizeAssetPatterns,
|
||||
normalizeFileReplacements,
|
||||
normalizeSourceMaps,
|
||||
} from '../utils';
|
||||
import {
|
||||
AssetPatternObject,
|
||||
BrowserBuilderSchema,
|
||||
CurrentFileReplacement,
|
||||
} from './schema';
|
||||
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
|
||||
const webpackMerge = require('webpack-merge');
|
||||
|
||||
@ -45,7 +55,9 @@ const webpackMerge = require('webpack-merge');
|
||||
// Right now this normalization has to be done in all other builders that make use of the
|
||||
// BrowserBuildSchema and BrowserBuilder.buildWebpackConfig.
|
||||
// It would really help if it happens during architect.validateBuilderOptions, or similar.
|
||||
export interface NormalizedBrowserBuilderSchema extends BrowserBuilderSchema {
|
||||
export interface NormalizedBrowserBuilderSchema extends
|
||||
Pick<BrowserBuilderSchema, Exclude<keyof BrowserBuilderSchema, 'sourceMap' | 'vendorSourceMap'>>,
|
||||
NormalizedSourceMaps {
|
||||
assets: AssetPatternObject[];
|
||||
fileReplacements: CurrentFileReplacement[];
|
||||
}
|
||||
@ -55,7 +67,7 @@ export class BrowserBuilder implements Builder<BrowserBuilderSchema> {
|
||||
constructor(public context: BuilderContext) { }
|
||||
|
||||
run(builderConfig: BuilderConfiguration<BrowserBuilderSchema>): Observable<BuildEvent> {
|
||||
const options = builderConfig.options;
|
||||
let options = builderConfig.options;
|
||||
const root = this.context.workspace.root;
|
||||
const projectRoot = resolve(root, builderConfig.root);
|
||||
const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<fs.Stats>);
|
||||
@ -71,6 +83,17 @@ export class BrowserBuilder implements Builder<BrowserBuilderSchema> {
|
||||
options.assets, host, root, projectRoot, builderConfig.sourceRoot)),
|
||||
// Replace the assets in options with the normalized version.
|
||||
tap((assetPatternObjects => options.assets = assetPatternObjects)),
|
||||
tap(() => {
|
||||
const normalizedOptions = normalizeSourceMaps(options.sourceMap);
|
||||
// todo: remove when removing the deprecations
|
||||
normalizedOptions.vendorSourceMap
|
||||
= normalizedOptions.vendorSourceMap || !!options.vendorSourceMap;
|
||||
|
||||
options = {
|
||||
...options,
|
||||
...normalizedOptions,
|
||||
};
|
||||
}),
|
||||
concatMap(() => {
|
||||
let webpackConfig;
|
||||
try {
|
||||
|
@ -69,10 +69,11 @@ export interface BrowserBuilderSchema {
|
||||
/**
|
||||
* Output sourcemaps.
|
||||
*/
|
||||
sourceMap: boolean;
|
||||
sourceMap: SourceMapOptions;
|
||||
|
||||
/**
|
||||
* Resolve vendor packages sourcemaps.
|
||||
* @deprecated - use `sourceMap.vendor` instead
|
||||
*/
|
||||
vendorSourceMap?: boolean;
|
||||
|
||||
@ -236,6 +237,19 @@ export interface BrowserBuilderSchema {
|
||||
profile: boolean;
|
||||
}
|
||||
|
||||
export type SourceMapOptions = boolean | SourceMapObject;
|
||||
|
||||
export interface SourceMapObject {
|
||||
/** Output sourcemaps used for error reports. */
|
||||
hidden?: boolean;
|
||||
/** Resolve vendor packages sourcemaps */
|
||||
vendor?: boolean;
|
||||
/** Output sourcemaps for all scripts */
|
||||
scripts?: boolean;
|
||||
/** Output sourcemaps for all styles. */
|
||||
styles?: boolean;
|
||||
}
|
||||
|
||||
export type AssetPattern = string | AssetPatternObject;
|
||||
|
||||
export interface AssetPatternObject {
|
||||
|
@ -82,13 +82,44 @@
|
||||
"default": false
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps used for error reporting tools.",
|
||||
"default": false
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"x-deprecated": true,
|
||||
"default": false
|
||||
},
|
||||
"evalSourceMap": {
|
||||
@ -415,4 +446,4 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -24,11 +24,15 @@ import * as WebpackDevServer from 'webpack-dev-server';
|
||||
import { checkPort } from '../angular-cli-files/utilities/check-port';
|
||||
import { BrowserBuilder, NormalizedBrowserBuilderSchema, getBrowserLoggingCb } from '../browser/';
|
||||
import { BrowserBuilderSchema } from '../browser/schema';
|
||||
import { normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
|
||||
import { normalizeAssetPatterns, normalizeFileReplacements, normalizeSourceMaps } from '../utils';
|
||||
const opn = require('opn');
|
||||
|
||||
|
||||
export interface DevServerBuilderOptions {
|
||||
export interface DevServerBuilderOptions extends Pick<BrowserBuilderSchema,
|
||||
'optimization' | 'aot' | 'sourceMap' | 'vendorSourceMap'
|
||||
| 'evalSourceMap' | 'vendorChunk' | 'commonChunk' | 'poll'
|
||||
| 'baseHref' | 'deployUrl' | 'progress' | 'verbose'
|
||||
> {
|
||||
browserTarget: string;
|
||||
port: number;
|
||||
host: string;
|
||||
@ -45,21 +49,6 @@ export interface DevServerBuilderOptions {
|
||||
watch: boolean;
|
||||
hmrWarning: boolean;
|
||||
servePathDefaultWarning: boolean;
|
||||
|
||||
// These options come from the browser builder and are provided here for convenience.
|
||||
optimization?: boolean;
|
||||
aot?: boolean;
|
||||
sourceMap?: boolean;
|
||||
vendorSourceMap?: boolean;
|
||||
/**@deprecated */
|
||||
evalSourceMap?: boolean;
|
||||
vendorChunk?: boolean;
|
||||
commonChunk?: boolean;
|
||||
baseHref?: string;
|
||||
deployUrl?: string;
|
||||
progress?: boolean;
|
||||
poll?: number;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
type DevServerBuilderOptionsKeys = Extract<keyof DevServerBuilderOptions, string>;
|
||||
@ -88,14 +77,24 @@ export class DevServerBuilder implements Builder<DevServerBuilderOptions> {
|
||||
browserOptions.assets, host, root, projectRoot, builderConfig.sourceRoot)),
|
||||
// Replace the assets in options with the normalized version.
|
||||
tap((assetPatternObjects => browserOptions.assets = assetPatternObjects)),
|
||||
tap(() => {
|
||||
const normalizedOptions = normalizeSourceMaps(browserOptions.sourceMap);
|
||||
// todo: remove when removing the deprecations
|
||||
normalizedOptions.vendorSourceMap
|
||||
= normalizedOptions.vendorSourceMap || !!browserOptions.vendorSourceMap;
|
||||
|
||||
browserOptions = {
|
||||
...browserOptions,
|
||||
...normalizedOptions,
|
||||
};
|
||||
}),
|
||||
concatMap(() => {
|
||||
const webpackConfig = this.buildWebpackConfig(
|
||||
root, projectRoot, host, browserOptions as NormalizedBrowserBuilderSchema);
|
||||
|
||||
let webpackDevServerConfig: WebpackDevServer.Configuration;
|
||||
try {
|
||||
webpackDevServerConfig = this._buildServerConfig(
|
||||
root, projectRoot, options, browserOptions);
|
||||
webpackDevServerConfig = this._buildServerConfig(root, options, browserOptions);
|
||||
} catch (err) {
|
||||
return throwError(err);
|
||||
}
|
||||
@ -172,7 +171,8 @@ export class DevServerBuilder implements Builder<DevServerBuilderOptions> {
|
||||
|
||||
return buildEvent;
|
||||
}),
|
||||
);
|
||||
// using more than 10 operators will cause rxjs to loose the types
|
||||
) as Observable<BuildEvent>;
|
||||
}
|
||||
|
||||
buildWebpackConfig(
|
||||
@ -190,7 +190,6 @@ export class DevServerBuilder implements Builder<DevServerBuilderOptions> {
|
||||
|
||||
private _buildServerConfig(
|
||||
root: Path,
|
||||
projectRoot: Path,
|
||||
options: DevServerBuilderOptions,
|
||||
browserOptions: BrowserBuilderSchema,
|
||||
) {
|
||||
|
@ -92,12 +92,44 @@
|
||||
"description": "Build using Ahead of Time compilation."
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps."
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps used for error reporting tools.",
|
||||
"default": false
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"x-deprecated": true,
|
||||
"default": false
|
||||
},
|
||||
"evalSourceMap": {
|
||||
@ -134,4 +166,4 @@
|
||||
"required": [
|
||||
"browserTarget"
|
||||
]
|
||||
}
|
||||
}
|
@ -27,7 +27,12 @@ import {
|
||||
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
|
||||
import { requireProjectModule } from '../angular-cli-files/utilities/require-project-module';
|
||||
import { AssetPatternObject, CurrentFileReplacement } from '../browser/schema';
|
||||
import { defaultProgress, normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
|
||||
import {
|
||||
defaultProgress,
|
||||
normalizeAssetPatterns,
|
||||
normalizeFileReplacements,
|
||||
normalizeSourceMaps,
|
||||
} from '../utils';
|
||||
import { KarmaBuilderSchema } from './schema';
|
||||
const webpackMerge = require('webpack-merge');
|
||||
|
||||
@ -41,7 +46,7 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
|
||||
constructor(public context: BuilderContext) { }
|
||||
|
||||
run(builderConfig: BuilderConfiguration<KarmaBuilderSchema>): Observable<BuildEvent> {
|
||||
const options = builderConfig.options;
|
||||
let options = builderConfig.options;
|
||||
const root = this.context.workspace.root;
|
||||
const projectRoot = resolve(root, builderConfig.root);
|
||||
const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<fs.Stats>);
|
||||
@ -53,6 +58,17 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
|
||||
options.assets, host, root, projectRoot, builderConfig.sourceRoot)),
|
||||
// Replace the assets in options with the normalized version.
|
||||
tap((assetPatternObjects => options.assets = assetPatternObjects)),
|
||||
tap(() => {
|
||||
const normalizedOptions = normalizeSourceMaps(options.sourceMap);
|
||||
// todo: remove when removing the deprecations
|
||||
normalizedOptions.vendorSourceMap
|
||||
= normalizedOptions.vendorSourceMap || !!options.vendorSourceMap;
|
||||
|
||||
options = {
|
||||
...options,
|
||||
...normalizedOptions,
|
||||
};
|
||||
}),
|
||||
concatMap(() => new Observable(obs => {
|
||||
const karma = requireProjectModule(getSystemPath(projectRoot), 'karma');
|
||||
const karmaConfig = getSystemPath(resolve(root, normalize(options.karmaConfig)));
|
||||
|
@ -7,17 +7,20 @@
|
||||
*/
|
||||
import { BrowserBuilderSchema } from '../browser/schema';
|
||||
|
||||
|
||||
// TODO: in TS 2.8 use Extract instead of Pick to make a subset of another type.
|
||||
export interface KarmaBuilderSchema extends Pick<BrowserBuilderSchema,
|
||||
'assets' | 'main' | 'polyfills' | 'tsConfig' | 'scripts' | 'styles' | 'stylePreprocessorOptions'
|
||||
| 'fileReplacements' | 'sourceMap' | 'poll' | 'preserveSymlinks' | 'watch'
|
||||
| 'fileReplacements' | 'poll' | 'preserveSymlinks' | 'watch' | 'vendorSourceMap'
|
||||
> {
|
||||
/**
|
||||
* The name of the Karma configuration file..
|
||||
*/
|
||||
karmaConfig: string;
|
||||
|
||||
/**
|
||||
* Output sourcemaps.
|
||||
*/
|
||||
sourceMap: KarmaSourceMapOptions;
|
||||
|
||||
/**
|
||||
* Override which browsers tests are run against.
|
||||
*/
|
||||
@ -38,3 +41,14 @@ export interface KarmaBuilderSchema extends Pick<BrowserBuilderSchema,
|
||||
*/
|
||||
reporters?: string[];
|
||||
}
|
||||
|
||||
export type KarmaSourceMapOptions = boolean | KarmaSourceMapObject;
|
||||
|
||||
export interface KarmaSourceMapObject {
|
||||
/** Resolve vendor packages sourcemaps */
|
||||
vendor?: boolean;
|
||||
/** Output sourcemaps for all scripts */
|
||||
scripts?: boolean;
|
||||
/** Output sourcemaps for all styles. */
|
||||
styles?: boolean;
|
||||
}
|
||||
|
@ -63,13 +63,39 @@
|
||||
"description": "Defines the build environment."
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"x-deprecated": true,
|
||||
"default": false
|
||||
},
|
||||
"evalSourceMap": {
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
|
||||
import { requireProjectModule } from '../angular-cli-files/utilities/require-project-module';
|
||||
import { getBrowserLoggingCb } from '../browser';
|
||||
import { defaultProgress, normalizeFileReplacements } from '../utils';
|
||||
import { defaultProgress, normalizeFileReplacements, normalizeSourceMaps } from '../utils';
|
||||
import { BuildWebpackServerSchema } from './schema';
|
||||
const webpackMerge = require('webpack-merge');
|
||||
|
||||
@ -40,7 +40,7 @@ export class ServerBuilder implements Builder<BuildWebpackServerSchema> {
|
||||
constructor(public context: BuilderContext) { }
|
||||
|
||||
run(builderConfig: BuilderConfiguration<BuildWebpackServerSchema>): Observable<BuildEvent> {
|
||||
const options = builderConfig.options;
|
||||
let options = builderConfig.options;
|
||||
const root = this.context.workspace.root;
|
||||
const projectRoot = resolve(root, builderConfig.root);
|
||||
const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<Stats>);
|
||||
@ -51,8 +51,19 @@ export class ServerBuilder implements Builder<BuildWebpackServerSchema> {
|
||||
concatMap(() => options.deleteOutputPath
|
||||
? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
|
||||
: of(null)),
|
||||
concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
|
||||
tap(fileReplacements => options.fileReplacements = fileReplacements),
|
||||
concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
|
||||
tap(fileReplacements => options.fileReplacements = fileReplacements),
|
||||
tap(() => {
|
||||
const normalizedOptions = normalizeSourceMaps(options.sourceMap);
|
||||
// todo: remove when removing the deprecations
|
||||
normalizedOptions.vendorSourceMap
|
||||
= normalizedOptions.vendorSourceMap || !!options.vendorSourceMap;
|
||||
|
||||
options = {
|
||||
...options,
|
||||
...normalizedOptions,
|
||||
};
|
||||
}),
|
||||
concatMap(() => {
|
||||
const webpackConfig = this.buildWebpackConfig(root, projectRoot, host, options);
|
||||
|
||||
|
@ -6,17 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import { FileReplacement } from '../browser/schema';
|
||||
import { BrowserBuilderSchema, FileReplacement, SourceMapOptions } from '../browser/schema';
|
||||
|
||||
export interface BuildWebpackServerSchema {
|
||||
/**
|
||||
* The name of the TypeScript configuration file.
|
||||
*/
|
||||
tsConfig: string;
|
||||
/**
|
||||
* Output sourcemaps.
|
||||
*/
|
||||
sourceMap?: boolean;
|
||||
/**
|
||||
* Adds more details to output logging.
|
||||
*/
|
||||
@ -37,8 +33,13 @@ export interface BuildWebpackServerSchema {
|
||||
* Use a separate bundle containing only vendor libraries.
|
||||
*/
|
||||
vendorChunk?: boolean;
|
||||
/**
|
||||
* Output sourcemaps.
|
||||
*/
|
||||
sourceMap: SourceMapOptions;
|
||||
/**
|
||||
* Resolve vendor packages sourcemaps.
|
||||
* @deprecated use sourceMap.vendor
|
||||
*/
|
||||
vendorSourceMap?: boolean;
|
||||
/**
|
||||
|
@ -50,13 +50,44 @@
|
||||
"default": ""
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps.",
|
||||
"default": true
|
||||
"default": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"scripts": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all scripts.",
|
||||
"default": true
|
||||
},
|
||||
"styles": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps for all styles.",
|
||||
"default": true
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"description": "Output sourcemaps used for error reporting tools.",
|
||||
"default": false
|
||||
},
|
||||
"vendor": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"vendorSourceMap": {
|
||||
"type": "boolean",
|
||||
"description": "Resolve vendor packages sourcemaps.",
|
||||
"x-deprecated": true,
|
||||
"default": false
|
||||
},
|
||||
"evalSourceMap": {
|
||||
@ -220,6 +251,5 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -10,3 +10,4 @@ export * from './default-progress';
|
||||
export * from './run-module-as-observable-fork';
|
||||
export * from './normalize-file-replacements';
|
||||
export * from './normalize-asset-patterns';
|
||||
export * from './normalize-source-maps';
|
||||
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import { SourceMapOptions } from '../browser/schema';
|
||||
|
||||
export interface NormalizedSourceMaps {
|
||||
sourceMap: boolean;
|
||||
scriptsSourceMap: boolean;
|
||||
stylesSourceMap: boolean;
|
||||
hiddenSourceMap: boolean;
|
||||
vendorSourceMap: boolean;
|
||||
}
|
||||
|
||||
export function normalizeSourceMaps(sourceMap: SourceMapOptions): NormalizedSourceMaps {
|
||||
const scriptsSourceMap = !!(typeof sourceMap === 'object' ? sourceMap.scripts : sourceMap);
|
||||
const stylesSourceMap = !!(typeof sourceMap === 'object' ? sourceMap.styles : sourceMap);
|
||||
const hiddenSourceMap = typeof sourceMap === 'object' && !!sourceMap.hidden;
|
||||
const vendorSourceMap = typeof sourceMap === 'object' && !!sourceMap.vendor;
|
||||
|
||||
return {
|
||||
sourceMap: stylesSourceMap || scriptsSourceMap,
|
||||
vendorSourceMap,
|
||||
hiddenSourceMap,
|
||||
scriptsSourceMap,
|
||||
stylesSourceMap,
|
||||
};
|
||||
}
|
@ -9,9 +9,10 @@
|
||||
import { runTargetSpec } from '@angular-devkit/architect/testing';
|
||||
import { join, normalize, virtualFs } from '@angular-devkit/core';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { BrowserBuilderSchema, OutputHashing } from '../../src';
|
||||
import { browserTargetSpec, host } from '../utils';
|
||||
|
||||
|
||||
// tslint:disable-next-line:no-big-function
|
||||
describe('Browser Builder source map', () => {
|
||||
const outputPath = normalize('dist');
|
||||
|
||||
@ -19,13 +20,38 @@ describe('Browser Builder source map', () => {
|
||||
afterEach(done => host.restore().toPromise().then(done, done.fail));
|
||||
|
||||
it('works', (done) => {
|
||||
const overrides = { sourceMap: true };
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: true,
|
||||
extractCss: true,
|
||||
styles: ['src/styles.css'],
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/styles.css': `div { flex: 1 }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
const fileName = join(outputPath, 'main.js.map');
|
||||
expect(host.scopedSync().exists(fileName)).toBe(true);
|
||||
const scriptsFileName = join(outputPath, 'main.js.map');
|
||||
expect(host.scopedSync().exists(scriptsFileName)).toBe(true);
|
||||
|
||||
const stylesFileName = join(outputPath, 'styles.css.map');
|
||||
expect(host.scopedSync().exists(stylesFileName)).toBe(true);
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('works with outputHashing', (done) => {
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: true,
|
||||
outputHashing: OutputHashing.All,
|
||||
};
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.fileMatchExists(outputPath, /main\.[0-9a-f]{20}\.js.map/)).toBeTruthy();
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
@ -55,4 +81,143 @@ describe('Browser Builder source map', () => {
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('supports hidden sourcemaps', (done) => {
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
hidden: true,
|
||||
styles: true,
|
||||
scripts: true,
|
||||
},
|
||||
extractCss: true,
|
||||
styles: ['src/styles.scss'],
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/styles.scss': `div { flex: 1 }`,
|
||||
});
|
||||
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(true);
|
||||
expect(host.scopedSync().exists(join(outputPath, 'styles.css.map'))).toBe(true);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
expect(scriptContent).not.toContain('sourceMappingURL=main.js.map');
|
||||
|
||||
const styleContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'styles.css')),
|
||||
);
|
||||
expect(styleContent).not.toContain('sourceMappingURL=styles.css.map');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('supports styles only sourcemaps', (done) => {
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
styles: true,
|
||||
scripts: false,
|
||||
},
|
||||
extractCss: true,
|
||||
styles: ['src/styles.scss'],
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/styles.scss': `div { flex: 1 }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(false);
|
||||
expect(host.scopedSync().exists(join(outputPath, 'styles.css.map'))).toBe(true);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
expect(scriptContent).not.toContain('sourceMappingURL=main.js.map');
|
||||
|
||||
const styleContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'styles.css')),
|
||||
);
|
||||
|
||||
expect(styleContent).toContain('sourceMappingURL=styles.css.map');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('supports scripts only sourcemaps', (done) => {
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
styles: false,
|
||||
scripts: true,
|
||||
},
|
||||
extractCss: true,
|
||||
styles: ['src/styles.scss'],
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/styles.scss': `div { flex: 1 }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(true);
|
||||
expect(host.scopedSync().exists(join(outputPath, 'styles.css.map'))).toBe(false);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
expect(scriptContent).toContain('sourceMappingURL=main.js.map');
|
||||
|
||||
const styleContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'styles.css')),
|
||||
);
|
||||
expect(styleContent).not.toContain('sourceMappingURL=styles.css.map');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('should not inline component styles sourcemaps when hidden', (done) => {
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
hidden: true,
|
||||
styles: true,
|
||||
scripts: true,
|
||||
},
|
||||
extractCss: true,
|
||||
styles: ['src/styles.scss'],
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/styles.scss': `div { flex: 1 }`,
|
||||
'src/app/app.component.css': `p { color: red; }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(true);
|
||||
expect(host.scopedSync().exists(join(outputPath, 'styles.css.map'))).toBe(true);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
|
||||
expect(scriptContent).not.toContain('sourceMappingURL=main.js.map');
|
||||
expect(scriptContent).not.toContain('sourceMappingURL=data:application/json');
|
||||
|
||||
const styleContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'styles.css')),
|
||||
);
|
||||
expect(styleContent).not.toContain('sourceMappingURL=styles.css.map');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ import { runTargetSpec } from '@angular-devkit/architect/testing';
|
||||
import { join, normalize, virtualFs } from '@angular-devkit/core';
|
||||
import * as path from 'path';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { BrowserBuilderSchema } from '../../src/browser/schema';
|
||||
import { browserTargetSpec, host } from '../utils';
|
||||
|
||||
describe('Browser Builder external source map', () => {
|
||||
@ -19,7 +20,13 @@ describe('Browser Builder external source map', () => {
|
||||
afterEach(done => host.restore().toPromise().then(done, done.fail));
|
||||
|
||||
it('works', (done) => {
|
||||
const overrides = { sourceMap: true, vendorSourceMap: true };
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
scripts: true,
|
||||
styles: true,
|
||||
vendor: true,
|
||||
},
|
||||
};
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
@ -35,7 +42,13 @@ describe('Browser Builder external source map', () => {
|
||||
});
|
||||
|
||||
it('does not map sourcemaps from external library when disabled', (done) => {
|
||||
const overrides = { sourceMap: true, vendorSourceMap: false };
|
||||
const overrides: Partial<BrowserBuilderSchema> = {
|
||||
sourceMap: {
|
||||
scripts: true,
|
||||
styles: true,
|
||||
vendor: false,
|
||||
},
|
||||
};
|
||||
|
||||
runTargetSpec(host, browserTargetSpec, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
|
@ -9,6 +9,7 @@
|
||||
import { runTargetSpec } from '@angular-devkit/architect/testing';
|
||||
import { join, normalize, virtualFs } from '@angular-devkit/core';
|
||||
import { take, tap } from 'rxjs/operators';
|
||||
import { BuildWebpackServerSchema } from '../../src/server/schema';
|
||||
import { host } from '../utils';
|
||||
|
||||
|
||||
@ -47,6 +48,58 @@ describe('Server Builder', () => {
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('supports scripts only sourcemaps', (done) => {
|
||||
const overrides: Partial<BuildWebpackServerSchema> = {
|
||||
sourceMap: {
|
||||
styles: false,
|
||||
scripts: true,
|
||||
},
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/app/app.component.css': `p { color: red; }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, { project: 'app', target: 'server' }, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(true);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
expect(scriptContent).toContain('sourceMappingURL=main.js.map');
|
||||
expect(scriptContent).not.toContain('sourceMappingURL=data:application/json');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('supports component styles sourcemaps', (done) => {
|
||||
const overrides: Partial<BuildWebpackServerSchema> = {
|
||||
sourceMap: {
|
||||
styles: true,
|
||||
scripts: true,
|
||||
},
|
||||
};
|
||||
|
||||
host.writeMultipleFiles({
|
||||
'src/app/app.component.css': `p { color: red; }`,
|
||||
});
|
||||
|
||||
runTargetSpec(host, { project: 'app', target: 'server' }, overrides).pipe(
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
expect(host.scopedSync().exists(join(outputPath, 'main.js.map'))).toBe(true);
|
||||
|
||||
const scriptContent = virtualFs.fileBufferToString(
|
||||
host.scopedSync().read(join(outputPath, 'main.js')),
|
||||
);
|
||||
expect(scriptContent).toContain('sourceMappingURL=main.js.map');
|
||||
expect(scriptContent).toContain('sourceMappingURL=data:application/json');
|
||||
}),
|
||||
).toPromise().then(done, done.fail);
|
||||
});
|
||||
|
||||
it('runs watch mode', (done) => {
|
||||
const overrides = { watch: true };
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user