angular cli

This commit is contained in:
lotte
2020-03-18 16:03:40 +01:00
parent 41969ec3b1
commit 8bf241c182
503 changed files with 5303 additions and 9574 deletions

View File

@@ -1,109 +0,0 @@
const path = require('path');
const fs = require('fs');
const projectRoot = (relativePath) => {
return path.resolve(__dirname, '..', relativePath);
};
const srcPath = projectRoot('src');
const buildRoot = (relativePath, env) => {
if (env.aot) {
return path.resolve(projectRoot('./build'), relativePath);
} else {
return path.resolve(projectRoot('src'), relativePath);
}
};
//TODO refactor to share between this and config.ts.
const getThemeName = () => {
let defaultCfg = require(projectRoot('config/environment.default.js'));
let envConfigFile;
let envConfigOverride = {};
switch (process.env.NODE_ENV) {
case 'prod':
case 'production':
// webpack.prod.dspace-angular-config.ts defines process.env.NODE_ENV = 'production'
envConfigFile = projectRoot('config/environment.prod.js');
break;
case 'test':
// webpack.test.dspace-angular-config.ts defines process.env.NODE_ENV = 'test'
envConfigFile = projectRoot('config/environment.test.js');
break;
default:
// if not using webpack.prod.dspace-angular-config.ts or webpack.test.dspace-angular-config.ts, it must be development
envConfigFile = projectRoot('config/environment.dev.js');
}
if (envConfigFile) {
try {
envConfigOverride = require(envConfigFile);
} catch (e) {
}
}
return Object.assign({}, defaultCfg.theme, envConfigOverride.theme).name;
}
const theme = getThemeName();
let themePath;
if (theme !== null && theme !== undefined) {
themePath = path.normalize(path.join(__dirname, '..', 'themes', theme));
}
else {
themePath = srcPath;
}
const globalCSSImports = (env) => { return [
buildRoot('styles/_variables.scss', env),
buildRoot('styles/_mixins.scss', env),
]};
const getThemedPath = (componentPath, ext) => {
const parsedPath = path.parse(componentPath);
const relativePath = path.relative(srcPath, parsedPath.dir);
return path.join(themePath, relativePath, `${parsedPath.name}.${ext}`);
};
const themedTest = (origPath, extension) => {
if (/\.component.ts$/.test(origPath)) { // only match components
const themedPath = getThemedPath(origPath, extension);
return fs.existsSync(themedPath);
} else {
return false;
}
};
const themedUse = (resource, extension) => {
const origPath = path.parse(resource);
let themedPath = getThemedPath(resource, extension);
/* Make sure backslashes are escaped twice, because the replace unescapes those again */
themedPath = themedPath.replace(/\\/g, '\\\\');
return [
{
loader: 'string-replace-loader',
options: {
search: `\.\/${origPath.name}\.${extension}`,
replace: themedPath,
flags: 'g'
}
}
]
};
module.exports = {
projectRoot,
buildRoot,
theme: theme,
themePath,
getThemedPath,
themedTest,
themedUse,
globalCSSImports
};

79
webpack/helpers.ts Normal file
View File

@@ -0,0 +1,79 @@
const path = require('path');
const fs = require('fs');
const environment = require('../src/environments/environment.ts').environment;
export const projectRoot = (relativePath) => {
return path.resolve(__dirname, '..', relativePath);
};
export const srcPath = projectRoot('src');
export const buildRoot = (relativePath) => {
if (environment.aot) {
return path.resolve(projectRoot('./build'), relativePath);
} else {
return path.resolve(projectRoot('src'), relativePath);
}
};
export const theme = environment.theme.name;
export let themePath;
if (theme !== null && theme !== undefined) {
themePath = path.normalize(path.join(__dirname, '..', 'themes', theme));
} else {
themePath = srcPath;
}
export const globalCSSImports = () => {
return [
buildRoot('styles/_variables.scss'),
buildRoot('styles/_mixins.scss'),
];
};
const getThemedPath = (componentPath, ext) => {
const parsedPath = path.parse(componentPath);
const relativePath = path.relative(srcPath, parsedPath.dir);
return path.join(themePath, relativePath, `${parsedPath.name}.${ext}`);
};
export const themedTest = (origPath, extension) => {
if (/\.component.ts$/.test(origPath)) { // only match components
const themedPath = getThemedPath(origPath, extension);
return fs.existsSync(themedPath);
} else {
return false;
}
};
export const themedUse = (resource, extension) => {
const origPath = path.parse(resource);
let themedPath = getThemedPath(resource, extension);
/* Make sure backslashes are escaped twice, because the replace unescapes those again */
themedPath = themedPath.replace(/\\/g, '\\\\');
return [
{
loader: 'string-replace-loader',
options: {
search: `\.\/${origPath.name}\.${extension}`,
replace: themedPath,
flags: 'g'
}
}
];
};
module.exports = {
projectRoot,
buildRoot,
theme: theme,
themePath,
getThemedPath,
themedTest,
themedUse,
globalCSSImports
};

View File

@@ -1,37 +0,0 @@
const {
buildRoot
} = require('./helpers');
const {
AngularCompilerPlugin
} = require('@ngtools/webpack');
module.exports = (env) => {
const tsconfigs = {
client: buildRoot('./tsconfig.browser.json', env),
server: buildRoot('./tsconfig.server.json', env)
};
const aotTsconfigs = {
client: buildRoot('./tsconfig.browser.json', env),
server: buildRoot('./tsconfig.server.aot.json', env)
};
/**
* Generates a AotPlugin for @ngtools/webpack
*
* @param {string} platform Should either be client or server
* @param {boolean} aot Enables/Disables AoT Compilation
* @returns {AotPlugin} Configuration of AotPlugin
*/
function getAotPlugin(platform, aot) {
return new AngularCompilerPlugin({
tsConfigPath: aot ? aotTsconfigs[platform] : tsconfigs[platform],
skipCodeGeneration: !aot
});
}
return {
getAotPlugin: getAotPlugin
}
};

View File

@@ -1,27 +0,0 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtPlugin = require('script-ext-html-webpack-plugin');
const {
projectRoot,
buildRoot
} = require('./helpers');
module.exports = (env) => {
return {
entry: buildRoot('./main.browser.ts', env),
output: {
filename: 'client.js'
},
target: 'web',
plugins: [
new HtmlWebpackPlugin({
template: buildRoot('./index.html', env),
output: projectRoot('dist'),
inject: 'head'
}),
new ScriptExtPlugin({
defaultAttribute: 'defer'
})
]
};
}

View File

@@ -1,173 +0,0 @@
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const fs = require('fs');
const {
projectRoot,
buildRoot,
globalCSSImports,
theme,
themePath,
themedTest,
themedUse
} = require('./helpers');
module.exports = (env) => {
let copyWebpackOptions = [{
from: path.join(__dirname, '..', 'node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('assets', 'fonts')
}, {
from: path.join(__dirname, '..', 'resources', 'fonts'),
to: path.join('assets', 'fonts')
}, {
from: path.join(__dirname, '..', 'resources', 'images'),
to: path.join('assets', 'images')
}, {
from: path.join(__dirname, '..', 'resources', 'i18n'),
to: path.join('assets', 'i18n')
}
];
const themeFonts = path.join(themePath, 'resources', 'fonts');
if(theme && fs.existsSync(themeFonts)) {
copyWebpackOptions.push({
from: themeFonts,
to: path.join('assets', 'fonts') ,
force: true,
});
}
const themeImages = path.join(themePath, 'resources', 'images');
if(theme && fs.existsSync(themeImages)) {
copyWebpackOptions.push({
from: themeImages,
to: path.join('assets', 'images') ,
force: true,
});
}
return {
mode: 'development',
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.json']
},
output: {
path: projectRoot('dist')
},
watchOptions: {
aggregateTimeout: 50,
},
node: {
fs: "empty",
module: "empty"
},
module: {
rules: [
{
test: (filePath) => themedTest(filePath, 'scss'),
use: (info) => themedUse(info.resource, 'scss')
},
{
test: (filePath) => themedTest(filePath, 'html'),
use: (info) => themedUse(info.resource, 'html')
},
{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
{
test: /\.css$/,
use: [
{
loader: 'to-string-loader',
options: {
sourceMap: true
}
},
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.scss$/,
exclude: [
/node_modules/,
buildRoot('styles/_exposed_variables.scss', env),
buildRoot('styles/_variables.scss', env)
],
use: [
{
loader: 'raw-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
},
{
loader: 'sass-resources-loader',
options: {
resources: globalCSSImports(env)
},
}
]
},
{
test: /(_exposed)?_variables.scss$/,
exclude: [/node_modules/],
use: [
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
}
]
},
{
test: /\.(html|eot|ttf|otf|svg|woff|woff2)$/,
loader: 'raw-loader'
}
]
},
plugins: [
new CopyWebpackPlugin(copyWebpackOptions)
]
}
};

103
webpack/webpack.common.ts Normal file
View File

@@ -0,0 +1,103 @@
import { buildRoot, globalCSSImports, projectRoot, theme, themedTest, themedUse, themePath } from './helpers';
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtPlugin = require('script-ext-html-webpack-plugin');
export const copyWebpackOptions = [
{
from: path.join(__dirname, '..', 'node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('assets', 'fonts'),
force: undefined
},
{
from: path.join(__dirname, '..', 'src', 'assets', 'fonts'),
to: path.join('assets', 'fonts')
}, {
from: path.join(__dirname, '..', 'src', 'assets', 'images'),
to: path.join('assets', 'images')
}, {
from: path.join(__dirname, '..', 'src', 'assets', 'i18n'),
to: path.join('assets', 'i18n')
}
];
export const commonExports = {
target: 'web',
plugins: [
new CopyWebpackPlugin(copyWebpackOptions),
new HtmlWebpackPlugin({
template: buildRoot('./index.html', ),
output: projectRoot('dist'),
inject: 'head'
}),
new ScriptExtPlugin({
defaultAttribute: 'defer'
})
],
node: {
module: 'empty'
},
module: {
rules: [
{
test: (filePath) => themedTest(filePath, 'scss'),
use: (info) => themedUse(info.resource, 'scss')
},
{
test: (filePath) => themedTest(filePath, 'html'),
use: (info) => themedUse(info.resource, 'html')
},
{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
{
test: /\.scss$/,
exclude: [
/node_modules/,
buildRoot('styles/_exposed_variables.scss'),
buildRoot('styles/_variables.scss')
],
use: [
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
},
{
loader: 'sass-resources-loader',
options: {
resources: globalCSSImports()
},
}
]
},
{
test: /(_exposed)?_variables.scss$/,
exclude: [/node_modules/],
use: [
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
}
]
},
],
}
};
module.exports = commonExports;

View File

@@ -1,75 +0,0 @@
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CompressionPlugin = require("compression-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const cssnano = require("cssnano");
const {
projectRoot
} = require('./helpers');
module.exports = {
mode: 'production',
recordsOutputPath: projectRoot('webpack.records.json'),
plugins: [
new webpack.EnvironmentPlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production'),
'AOT': true
}
}),
new BundleAnalyzerPlugin({
analyzerMode: 'disabled', // change it to `server` to view bundle stats
reportFilename: 'report.html',
generateStatsFile: true,
statsFilename: 'stats.json',
}),
new CompressionPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
],
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
beautify: false,
mangle: false,
output: {
comments: false
},
compress: {
conditionals: false,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: true
},
sourceMap: true,
warnings: false
}
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: cssnano,
cssProcessorOptions: {
discardComments: {
removeAll: true,
}
},
safe: true
})
]
},
};

127
webpack/webpack.prod.ts Normal file
View File

@@ -0,0 +1,127 @@
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CompressionPlugin = require('compression-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const cssnano = require('cssnano');
const nodeExternals = require('webpack-node-externals');
import { buildRoot, globalCSSImports, projectRoot, theme, themedTest, themedUse, themePath } from './helpers';
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtPlugin = require('script-ext-html-webpack-plugin');
export const copyWebpackOptions = [
{
from: path.join(__dirname, '..', 'node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'),
to: path.join('assets', 'fonts'),
force: undefined
},
{
from: path.join(__dirname, '..', 'src', 'assets', 'fonts'),
to: path.join('assets', 'fonts')
}, {
from: path.join(__dirname, '..', 'src', 'assets', 'images'),
to: path.join('assets', 'images')
}, {
from: path.join(__dirname, '..', 'src', 'assets', 'i18n'),
to: path.join('assets', 'i18n')
}
];
export const commonExports = {
plugins: [
new CopyWebpackPlugin(copyWebpackOptions),
new HtmlWebpackPlugin({
template: buildRoot('./index.html', ),
output: projectRoot('dist'),
inject: 'head'
}),
new ScriptExtPlugin({
defaultAttribute: 'defer'
}),
new webpack.EnvironmentPlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
AOT: true
}
}),
],
module: {
rules: [
{
test: (filePath) => themedTest(filePath, 'scss'),
use: (info) => themedUse(info.resource, 'scss')
},
{
test: (filePath) => themedTest(filePath, 'html'),
use: (info) => themedUse(info.resource, 'html')
},
{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
{
test: /\.scss$/,
exclude: [
/node_modules/,
buildRoot('styles/_exposed_variables.scss'),
buildRoot('styles/_variables.scss')
],
use: [
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
},
{
loader: 'sass-resources-loader',
options: {
resources: globalCSSImports()
},
}
]
},
{
test: /(_exposed)?_variables.scss$/,
exclude: [/node_modules/],
use: [
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
}
]
},
],
},
mode: 'production',
recordsOutputPath: projectRoot('webpack.records.json'),
entry: buildRoot('./main.server.ts'),
target: 'node',
externals: [nodeExternals({
whitelist: [
/@angular/,
/@ng/,
/angular2-text-mask/,
/ng2-file-upload/,
/ngx-sortablejs/,
/sortablejs/,
/ngx/]
})],
};
module.exports = commonExports;

View File

@@ -1,30 +0,0 @@
var nodeExternals = require('webpack-node-externals');
const {
buildRoot
} = require('./helpers');
module.exports = (env) => {
return {
getServerWebpackPartial: function (aot) {
const entry = aot ? buildRoot('./main.server.aot.ts', env) : buildRoot('./main.server.ts', env);
return {
entry: entry,
output: {
filename: 'server.js'
},
target: 'node',
externals: [nodeExternals({
whitelist: [
/@angular/,
/@ng/,
/angular2-text-mask/,
/ng2-file-upload/,
/ngx-sortablejs/,
/sortablejs/,
/ngx/]
})],
}
}
}
};

View File

@@ -1,304 +0,0 @@
const {
projectRoot,
buildRoot,
themedTest,
themedUse,
themePath,
globalCSSImports
} = require('./helpers');
const path = require('path');
/**
* Webpack Plugins
*/
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
/**
* Webpack Constants
*/
const ENV = process.env.ENV = process.env.NODE_ENV = 'test';
/**
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = function (env) {
return {
mode: 'development',
/**
* Source map for Karma from the help of karma-sourcemap-loader & karma-webpack
*
* Do not change, leave as is or it wont work.
* See: https://github.com/webpack/karma-webpack#source-maps
*/
devtool: 'source-map',
/**
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/**
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['.ts', '.js', '.json'],
/**
* Make sure root is src
*/
modules: [projectRoot('src'), 'node_modules']
},
/**
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*
* 'use:' revered back to 'loader:' as a temp. workaround for #1188
* See: https://github.com/AngularClass/angular2-webpack-starter/issues/1188#issuecomment-262872034
*/
module: {
rules: [
/**
* Source map loader support for *.js files
* Extracts SourceMaps for source files that as added as sourceMappingURL comment.
*
* See: https://github.com/webpack/source-map-loader
*/
{
test: (filePath) => themedTest(filePath, 'scss'),
use: (info) => themedUse(info.resource, 'scss')
},
{
test: (filePath) => themedTest(filePath, 'html'),
use: (info) => themedUse(info.resource, 'html')
},
/**
* Typescript loader support for .ts and Angular 2 async routes via .async.ts
*
* See: https://github.com/TypeStrong/ts-loader
*/
{
test: /\.tsx?$/,
loaders: [{
loader: 'ts-loader',
options: {
configFile: projectRoot('src/tsconfig.test.json'),
transpileOnly: true
}
},
'angular2-template-loader'
],
exclude: [/\.e2e\.ts$/]
},
/**
* CSS loader support for *.css files
* Returns file content as string
*
* See: https://github.com/webpack/css-loader
*/
{
test: /\.css$/,
use: [{
loader: 'to-string-loader',
options: {
sourceMap: true
}
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
],
},
/**
* SASS loader support for *.css files
* Returns file content as string
*
*/
{
test: /\.scss$/,
exclude: [
/node_modules/,
buildRoot('styles/_exposed_variables.scss', env),
buildRoot('styles/_variables.scss', env)
],
use: [
{
loader: 'raw-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
},
{
loader: 'sass-resources-loader',
options: {
resources: globalCSSImports(env)
},
}
]
},
{
test: /(_exposed)?_variables.scss$/,
exclude: [/node_modules/],
use: [
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
includePaths: [projectRoot('./'), path.join(themePath, 'styles')]
}
}
]
},
/**
* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: /\.html$/,
loader: 'raw-loader',
exclude: [projectRoot('src/index.html')]
},
/**
* Instruments JS files with Istanbul for subsequent code coverage reporting.
* Instrument only testing sources.
*
* See: https://github.com/deepsweet/istanbul-instrumenter-loader
*/
{
enforce: 'post',
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
query: {
esModules: true
},
include: projectRoot('src'),
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/
]
}
]
},
/**
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
new ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
projectRoot('./src'), {}
),
// Workaround for https://github.com/angular/angular/issues/20357
new ContextReplacementPlugin(
/\@angular(\\|\/)core(\\|\/)esm5/,
projectRoot('./src'), {}
),
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(ENV),
'HMR': false,
'process.env': {
'ENV': JSON.stringify(ENV),
'NODE_ENV': JSON.stringify(ENV),
'HMR': false,
}
}),
new ForkTsCheckerWebpackPlugin()
],
/**
* Disable performance hints
*
* See: https://github.com/a-tarasyuk/rr-boilerplate/blob/master/webpack/dev.config.babel.js#L41
*/
performance: {
hints: false
},
/**
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
process: false,
crypto: 'empty',
module: false,
clearImmediate: false,
setImmediate: false
}
};
};