mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-19 04:26:01 +08:00
141 lines
5.1 KiB
TypeScript
141 lines
5.1 KiB
TypeScript
import * as path from 'path';
|
|
import * as fs from 'fs';
|
|
|
|
import { CliConfig } from '../models/config';
|
|
import { Pattern } from './glob-copy-webpack-plugin';
|
|
import { extraEntryParser } from '../models/webpack-configs/utils';
|
|
import { WebpackTestConfig, WebpackTestOptions } from '../models/webpack-test-config';
|
|
|
|
const getAppFromConfig = require('../utilities/app-utils').getAppFromConfig;
|
|
|
|
function isDirectory(path: string) {
|
|
try {
|
|
return fs.statSync(path).isDirectory();
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const init: any = (config: any) => {
|
|
const apps = CliConfig.fromProject().config.apps;
|
|
const appConfig = getAppFromConfig(apps, config.angularCli.app);
|
|
const appRoot = path.join(config.basePath, appConfig.root);
|
|
const testConfig: WebpackTestOptions = Object.assign({
|
|
environment: 'dev',
|
|
codeCoverage: false,
|
|
sourcemap: true,
|
|
progress: true,
|
|
}, config.angularCli);
|
|
|
|
// Add assets. This logic is mimics the one present in GlobCopyWebpackPlugin.
|
|
if (appConfig.assets) {
|
|
config.proxies = config.proxies || {};
|
|
appConfig.assets.forEach((pattern: Pattern) => {
|
|
// Convert all string patterns to Pattern type.
|
|
pattern = typeof pattern === 'string' ? { glob: pattern } : pattern;
|
|
// Add defaults.
|
|
// Input is always resolved relative to the appRoot.
|
|
pattern.input = path.resolve(appRoot, pattern.input || '');
|
|
pattern.output = pattern.output || '';
|
|
pattern.glob = pattern.glob || '';
|
|
|
|
// Build karma file pattern.
|
|
const assetPath = path.join(pattern.input, pattern.glob);
|
|
const filePattern = isDirectory(assetPath) ? assetPath + '/**' : assetPath;
|
|
config.files.push({
|
|
pattern: filePattern,
|
|
included: false,
|
|
served: true,
|
|
watched: true
|
|
});
|
|
|
|
// The `files` entry serves the file from `/base/{asset.input}/{asset.glob}`.
|
|
// We need to add a URL rewrite that exposes the asset as `/{asset.output}/{asset.glob}`.
|
|
let relativePath: string, proxyPath: string;
|
|
if (fs.existsSync(assetPath)) {
|
|
relativePath = path.relative(config.basePath, assetPath);
|
|
proxyPath = path.join(pattern.output, pattern.glob);
|
|
} else {
|
|
// For globs (paths that don't exist), proxy pattern.output to pattern.input.
|
|
relativePath = path.relative(config.basePath, pattern.input);
|
|
proxyPath = path.join(pattern.output);
|
|
|
|
}
|
|
// Proxy paths must have only forward slashes.
|
|
proxyPath = proxyPath.replace(/\\/g, '/');
|
|
config.proxies['/' + proxyPath] = '/base/' + relativePath;
|
|
});
|
|
}
|
|
|
|
// Add webpack config.
|
|
const webpackConfig = new WebpackTestConfig(testConfig, appConfig).buildConfig();
|
|
const webpackMiddlewareConfig = {
|
|
noInfo: true, // Hide webpack output because its noisy.
|
|
stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors.
|
|
assets: false,
|
|
colors: true,
|
|
version: false,
|
|
hash: false,
|
|
timings: false,
|
|
chunks: false,
|
|
chunkModules: false
|
|
},
|
|
watchOptions: {
|
|
poll: testConfig.poll
|
|
}
|
|
};
|
|
|
|
config.webpack = Object.assign(webpackConfig, config.webpack);
|
|
config.webpackMiddleware = Object.assign(webpackMiddlewareConfig, config.webpackMiddleware);
|
|
|
|
// Replace the @angular/cli preprocessor with webpack+sourcemap.
|
|
Object.keys(config.preprocessors)
|
|
.filter((file) => config.preprocessors[file].indexOf('@angular/cli') !== -1)
|
|
.map((file) => config.preprocessors[file])
|
|
.map((arr) => arr.splice(arr.indexOf('@angular/cli'), 1, 'webpack', 'sourcemap'));
|
|
|
|
// Add global scripts. This logic mimics the one in webpack-configs/common.
|
|
if (appConfig.scripts && appConfig.scripts.length > 0) {
|
|
const globalScriptPatterns = extraEntryParser(appConfig.scripts, appRoot, 'scripts')
|
|
// Neither renamed nor lazy scripts are currently supported
|
|
.filter(script => !(script.output || script.lazy))
|
|
.map(script => ({
|
|
pattern: path.resolve(appRoot, script.input),
|
|
included: true,
|
|
served: true,
|
|
watched: true
|
|
}));
|
|
|
|
// Unshift elements onto the beginning of the files array.
|
|
// It's important to not replace the array, because
|
|
// karma already has a reference to the existing array.
|
|
config.files.unshift(...globalScriptPatterns);
|
|
}
|
|
|
|
// Add polyfills file before everything else
|
|
if (appConfig.polyfills) {
|
|
const polyfillsFile = path.resolve(appRoot, appConfig.polyfills);
|
|
const polyfillsPattern = {
|
|
pattern: polyfillsFile,
|
|
included: true,
|
|
served: true,
|
|
watched: true
|
|
};
|
|
config.preprocessors[polyfillsFile] = ['webpack', 'sourcemap'];
|
|
// Same as above.
|
|
config.files.unshift(polyfillsPattern);
|
|
}
|
|
};
|
|
|
|
init.$inject = ['config'];
|
|
|
|
// Dummy preprocessor, just to keep karma from showing a warning.
|
|
const preprocessor: any = () => (content: any, _file: string, done: any) => done(null, content);
|
|
preprocessor.$inject = [];
|
|
|
|
// Also export karma-webpack and karma-sourcemap-loader.
|
|
module.exports = Object.assign({
|
|
'framework:@angular/cli': ['factory', init],
|
|
'preprocessor:@angular/cli': ['factory', preprocessor]
|
|
}, require('karma-webpack'), require('karma-sourcemap-loader'));
|