- Single char alternation (e.g. a|b|c|d) in a RegExp can be simplified to use a character class ([abcd]) instead. This usually also provides slightly better matching performance. - Character escapes that are replaceable with the unescaped character without a change in meaning. Inside the square brackets of a character class, many escapes are unnecessary that would be necessary outside of a character class. For example the regex [\.] is identical to [.] - If several qualified expressions occur after the qualifier having been checked for nullable, they can be replaced with optional chaining
169 lines
4.6 KiB
TypeScript
169 lines
4.6 KiB
TypeScript
import * as webpack from 'webpack';
|
|
import { Configuration, ProgressPlugin, Stats } from 'webpack';
|
|
|
|
import * as ts from 'typescript';
|
|
|
|
import { LicenseWebpackPlugin } from 'license-webpack-plugin';
|
|
import CircularDependencyPlugin = require('circular-dependency-plugin');
|
|
import ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
|
import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
|
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
|
|
import { readTsConfig } from '@nrwl/workspace/src/utilities/typescript';
|
|
import { BuildBuilderOptions } from './types';
|
|
|
|
export const OUT_FILENAME = 'main.js';
|
|
|
|
export function getBaseWebpackPartial(
|
|
options: BuildBuilderOptions
|
|
): Configuration {
|
|
const { options: compilerOptions } = readTsConfig(options.tsConfig);
|
|
const supportsEs2015 =
|
|
compilerOptions.target !== ts.ScriptTarget.ES3 &&
|
|
compilerOptions.target !== ts.ScriptTarget.ES5;
|
|
const mainFields = [...(supportsEs2015 ? ['es2015'] : []), 'module', 'main'];
|
|
const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx'];
|
|
const webpackConfig: Configuration = {
|
|
entry: {
|
|
main: [options.main],
|
|
},
|
|
devtool: options.sourceMap ? 'source-map' : false,
|
|
mode: options.optimization ? 'production' : 'development',
|
|
output: {
|
|
path: options.outputPath,
|
|
filename: OUT_FILENAME,
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.([jt])sx?$/,
|
|
loader: require.resolve(`ts-loader`),
|
|
exclude: /node_modules/,
|
|
options: {
|
|
configFile: options.tsConfig,
|
|
transpileOnly: true,
|
|
// https://github.com/TypeStrong/ts-loader/pull/685
|
|
experimentalWatchApi: true,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
resolve: {
|
|
extensions,
|
|
alias: getAliases(options),
|
|
plugins: [
|
|
new TsConfigPathsPlugin({
|
|
configFile: options.tsConfig,
|
|
extensions,
|
|
mainFields,
|
|
}),
|
|
],
|
|
mainFields,
|
|
},
|
|
performance: {
|
|
hints: false,
|
|
},
|
|
plugins: [
|
|
new ForkTsCheckerWebpackPlugin({
|
|
tsconfig: options.tsConfig,
|
|
memoryLimit:
|
|
options.memoryLimit ||
|
|
ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT,
|
|
workers: options.maxWorkers || ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE,
|
|
useTypescriptIncrementalApi: false,
|
|
}),
|
|
],
|
|
watch: options.watch,
|
|
watchOptions: {
|
|
poll: options.poll,
|
|
},
|
|
stats: getStatsConfig(options),
|
|
};
|
|
|
|
const extraPlugins: webpack.Plugin[] = [];
|
|
|
|
if (options.progress) {
|
|
extraPlugins.push(new ProgressPlugin());
|
|
}
|
|
|
|
if (options.extractLicenses) {
|
|
extraPlugins.push(
|
|
(new LicenseWebpackPlugin({
|
|
stats: {
|
|
errors: false,
|
|
},
|
|
perChunkOutput: false,
|
|
outputFilename: `3rdpartylicenses.txt`,
|
|
}) as unknown) as webpack.Plugin
|
|
);
|
|
}
|
|
|
|
// process asset entries
|
|
if (Array.isArray(options.assets) && options.assets.length > 0) {
|
|
const copyWebpackPluginInstance = new CopyWebpackPlugin({
|
|
patterns: options.assets.map((asset: any) => {
|
|
return {
|
|
context: asset.input,
|
|
// Now we remove starting slash to make Webpack place it from the output root.
|
|
to: asset.output,
|
|
from: asset.glob,
|
|
globOptions: {
|
|
ignore: [
|
|
'.gitkeep',
|
|
'**/.DS_Store',
|
|
'**/Thumbs.db',
|
|
...(asset.ignore ?? []),
|
|
],
|
|
dot: true,
|
|
},
|
|
};
|
|
}),
|
|
});
|
|
extraPlugins.push(copyWebpackPluginInstance);
|
|
}
|
|
|
|
if (options.showCircularDependencies) {
|
|
extraPlugins.push(
|
|
new CircularDependencyPlugin({
|
|
exclude: /[\\\/]node_modules[\\\/]/,
|
|
})
|
|
);
|
|
}
|
|
|
|
webpackConfig.plugins = [...webpackConfig.plugins, ...extraPlugins];
|
|
|
|
return webpackConfig;
|
|
}
|
|
|
|
function getAliases(options: BuildBuilderOptions): { [key: string]: string } {
|
|
return options.fileReplacements.reduce(
|
|
(aliases, replacement) => ({
|
|
...aliases,
|
|
[replacement.replace]: replacement.with,
|
|
}),
|
|
{}
|
|
);
|
|
}
|
|
|
|
function getStatsConfig(options: BuildBuilderOptions): Stats.ToStringOptions {
|
|
return {
|
|
hash: true,
|
|
timings: false,
|
|
cached: false,
|
|
cachedAssets: false,
|
|
modules: false,
|
|
warnings: true,
|
|
errors: true,
|
|
colors: !options.verbose && !options.statsJson,
|
|
chunks: !options.verbose,
|
|
assets: !!options.verbose,
|
|
chunkOrigins: !!options.verbose,
|
|
chunkModules: !!options.verbose,
|
|
children: !!options.verbose,
|
|
reasons: !!options.verbose,
|
|
version: !!options.verbose,
|
|
errorDetails: !!options.verbose,
|
|
moduleTrace: !!options.verbose,
|
|
usedExports: !!options.verbose,
|
|
};
|
|
}
|