mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
495 lines
18 KiB
495 lines
18 KiB
/* eslint-disable no-useless-escape */
|
|
/* eslint-disable global-require */
|
|
|
|
const webpack = require('webpack');
|
|
const path = require('path');
|
|
|
|
const appRoot = path.resolve(__dirname, '..');
|
|
|
|
function root() {
|
|
// eslint-disable-next-line prefer-rest-params
|
|
const newArgs = Array.prototype.slice.call(arguments, 0);
|
|
|
|
// eslint-disable-next-line prefer-spread
|
|
return path.join.apply(path, [appRoot].concat(newArgs));
|
|
}
|
|
|
|
const plugins = {
|
|
// https://github.com/webpack-contrib/mini-css-extract-plugin
|
|
MiniCssExtractPlugin: require('mini-css-extract-plugin'),
|
|
// https://github.com/dividab/tsconfig-paths-webpack-plugin
|
|
TsconfigPathsPlugin: require('tsconfig-paths-webpack-plugin'),
|
|
// https://github.com/aackerman/circular-dependency-plugin
|
|
CircularDependencyPlugin: require('circular-dependency-plugin'),
|
|
// https://github.com/jantimon/html-webpack-plugin
|
|
HtmlWebpackPlugin: require('html-webpack-plugin'),
|
|
// https://webpack.js.org/plugins/terser-webpack-plugin/
|
|
TerserPlugin: require('terser-webpack-plugin'),
|
|
// https://www.npmjs.com/package/@ngtools/webpack
|
|
NgToolsWebpack: require('@ngtools/webpack'),
|
|
// https://github.com/NMFR/optimize-css-assets-webpack-plugin
|
|
OptimizeCSSAssetsPlugin: require('optimize-css-assets-webpack-plugin'),
|
|
// https://webpack.js.org/plugins/eslint-webpack-plugin/
|
|
ESLintPlugin: require('eslint-webpack-plugin'),
|
|
// https://github.com/webpack-contrib/stylelint-webpack-plugin
|
|
StylelintPlugin: require('stylelint-webpack-plugin'),
|
|
// https://www.npmjs.com/package/webpack-bundle-analyzer
|
|
BundleAnalyzerPlugin: require('webpack-bundle-analyzer').BundleAnalyzerPlugin,
|
|
// https://www.npmjs.com/package/@angular-devkit/build-optimizer
|
|
BuildOptimizerWebpackPlugin: require('@angular-devkit/build-optimizer').BuildOptimizerWebpackPlugin,
|
|
// https://webpack.js.org/plugins/copy-webpack-plugin/
|
|
CopyPlugin: require('copy-webpack-plugin'),
|
|
// https://www.npmjs.com/package/webpack-filter-warnings-plugin
|
|
FilterWarningsPlugin: require('webpack-filter-warnings-plugin'),
|
|
};
|
|
|
|
module.exports = function calculateConfig(env) {
|
|
const isProduction = env && env.production;
|
|
const isAnalyzing = isProduction && env.analyze;
|
|
const isDevServer = env.WEBPACK_SERVE;
|
|
const isTestCoverage = env && env.coverage;
|
|
const isTests = env && env.target === 'tests';
|
|
|
|
const configFile = isTests ? 'tsconfig.spec.json' : 'tsconfig.app.json';
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.log(`Use ${configFile}, Production: ${!!isProduction}`);
|
|
|
|
const config = {
|
|
mode: isProduction ? 'production' : 'development',
|
|
|
|
/*
|
|
* Source map for Karma from the help of karma-sourcemap-loader & karma-webpack.
|
|
*
|
|
* See: https://webpack.js.org/configuration/devtool/
|
|
*/
|
|
devtool: isProduction ? false : 'inline-source-map',
|
|
|
|
/*
|
|
* Options affecting the resolving of modules.
|
|
*
|
|
* See: https://webpack.js.org/configuration/resolve/
|
|
*/
|
|
resolve: {
|
|
/*
|
|
* An array of extensions that should be used to resolve modules.
|
|
*
|
|
* See: https://webpack.js.org/configuration/resolve/#resolve-extensions
|
|
*/
|
|
extensions: ['.ts', '.js', '.mjs', '.css', '.scss'],
|
|
modules: [
|
|
root('app'),
|
|
root('app', 'theme'),
|
|
root('node_modules'),
|
|
],
|
|
|
|
plugins: [
|
|
new plugins.TsconfigPathsPlugin({
|
|
configFile,
|
|
}),
|
|
],
|
|
},
|
|
|
|
/*
|
|
* Options affecting the normal modules.
|
|
*
|
|
* See: https://webpack.js.org/configuration/module/
|
|
*/
|
|
module: {
|
|
/*
|
|
* An array of Rules which are matched to requests when modules are created.
|
|
*
|
|
* See: https://webpack.js.org/configuration/module/#module-rules
|
|
*/
|
|
rules: [{
|
|
test: /\.mjs$/,
|
|
type: 'javascript/auto',
|
|
include: [/node_modules/],
|
|
}, {
|
|
// Mark files inside `@angular/core` as using SystemJS style dynamic imports.
|
|
test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
|
|
parser: { system: true },
|
|
include: [/node_modules/],
|
|
}, {
|
|
test: /\.js\.flow$/,
|
|
use: [{
|
|
loader: 'ignore-loader',
|
|
}],
|
|
include: [/node_modules/],
|
|
}, {
|
|
test: /\.map$/,
|
|
use: [{
|
|
loader: 'ignore-loader',
|
|
}],
|
|
include: [/node_modules/],
|
|
}, {
|
|
test: /\.d\.ts$/,
|
|
use: [{
|
|
loader: 'ignore-loader',
|
|
}],
|
|
include: [/node_modules/],
|
|
}, {
|
|
test: /\.(woff|woff2|ttf|eot)(\?.*$|$)/,
|
|
use: [{
|
|
loader: 'file-loader',
|
|
options: {
|
|
name: '[name].[hash].[ext]',
|
|
// Store the assets in custom path because of fonts need relative urls.
|
|
outputPath: 'assets',
|
|
|
|
// Use custom public path as ./ is not supported by fonts.
|
|
publicPath: isDevServer ? undefined : 'assets',
|
|
},
|
|
}],
|
|
}, {
|
|
test: /\.(png|jpe?g|gif|svg|ico)(\?.*$|$)/,
|
|
use: [{
|
|
loader: 'file-loader',
|
|
options: {
|
|
name: '[name].[hash].[ext]',
|
|
// Store the assets in custom path because of fonts need relative urls.
|
|
outputPath: 'assets',
|
|
},
|
|
}],
|
|
}, {
|
|
test: /\.css$/,
|
|
use: [
|
|
plugins.MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader',
|
|
}, {
|
|
loader: 'postcss-loader',
|
|
}],
|
|
}, {
|
|
test: /\.scss$/,
|
|
use: [{
|
|
loader: 'raw-loader',
|
|
}, {
|
|
loader: 'postcss-loader',
|
|
}, {
|
|
loader: 'sass-loader',
|
|
options: {
|
|
additionalData: `
|
|
@import '_vars';
|
|
@import '_mixins';
|
|
`,
|
|
sassOptions: {
|
|
includePaths: [root('app', 'theme')],
|
|
},
|
|
},
|
|
}],
|
|
exclude: root('app', 'theme'),
|
|
}],
|
|
},
|
|
|
|
performance: {
|
|
hints: false,
|
|
},
|
|
|
|
plugins: [
|
|
new plugins.FilterWarningsPlugin({
|
|
exclude: /System.import/,
|
|
}),
|
|
|
|
/*
|
|
* Always replace the context for the System.import in angular/core to prevent warnings.
|
|
*/
|
|
new webpack.ContextReplacementPlugin(
|
|
/\@angular(\\|\/)core(\\|\/)/,
|
|
root('./app', '$_lazy_route_resources'),
|
|
{},
|
|
),
|
|
|
|
new plugins.NgToolsWebpack.AngularWebpackPlugin({
|
|
tsconfig: configFile,
|
|
// Load directly from file system and skip webpack.
|
|
directTemplateLoading: true,
|
|
|
|
// Only run in aot compiler in production.
|
|
jitMode: !isProduction,
|
|
}),
|
|
|
|
/*
|
|
* Puts each bundle into a file and appends the hash of the file to the path.
|
|
*
|
|
* See: https://github.com/webpack-contrib/mini-css-extract-plugin
|
|
*/
|
|
new plugins.MiniCssExtractPlugin({
|
|
filename: '[name].css',
|
|
}),
|
|
|
|
new webpack.LoaderOptionsPlugin({
|
|
options: {
|
|
htmlLoader: {
|
|
/*
|
|
* Define the root for images, so that we can use absolute urls.
|
|
*
|
|
* See: https://github.com/webpack/html-loader#Advanced_Options
|
|
*/
|
|
root: root('app', 'images'),
|
|
},
|
|
context: '/',
|
|
},
|
|
}),
|
|
|
|
new plugins.StylelintPlugin({
|
|
files: '**/*.scss',
|
|
}),
|
|
|
|
/*
|
|
* Detect circular dependencies in app.
|
|
*
|
|
* See: https://github.com/aackerman/circular-dependency-plugin
|
|
*/
|
|
new plugins.CircularDependencyPlugin({
|
|
exclude: /([\\\/]node_modules[\\\/])|(ngfactory\.js$)/,
|
|
// Add errors to webpack instead of warnings
|
|
failOnError: true,
|
|
}),
|
|
|
|
/*
|
|
* Copy lazy loaded libraries to output.
|
|
*/
|
|
new plugins.CopyPlugin({
|
|
patterns: [
|
|
{ from: './node_modules/simplemde/dist', to: 'dependencies/simplemde' },
|
|
|
|
{ from: './node_modules/tinymce/icons/default/icons.min.js', to: 'dependencies/tinymce/icons/default' },
|
|
{ from: './node_modules/tinymce/plugins/advlist', to: 'dependencies/tinymce/plugins/advlist' },
|
|
{ from: './node_modules/tinymce/plugins/code', to: 'dependencies/tinymce/plugins/code' },
|
|
{ from: './node_modules/tinymce/plugins/image', to: 'dependencies/tinymce/plugins/image' },
|
|
{ from: './node_modules/tinymce/plugins/link', to: 'dependencies/tinymce/plugins/link' },
|
|
{ from: './node_modules/tinymce/plugins/lists', to: 'dependencies/tinymce/plugins/lists' },
|
|
{ from: './node_modules/tinymce/plugins/media', to: 'dependencies/tinymce/plugins/media' },
|
|
{ from: './node_modules/tinymce/plugins/paste', to: 'dependencies/tinymce/plugins/paste' },
|
|
{ from: './node_modules/tinymce/skins', to: 'dependencies/tinymce/skins' },
|
|
{ from: './node_modules/tinymce/themes/silver', to: 'dependencies/tinymce/themes/silver' },
|
|
{ from: './node_modules/tinymce/tinymce.min.js', to: 'dependencies/tinymce' },
|
|
|
|
{ from: './node_modules/tui-code-snippet/dist', to: 'dependencies/tui-calendar' },
|
|
{ from: './node_modules/tui-calendar/dist', to: 'dependencies/tui-calendar' },
|
|
|
|
{ from: './node_modules/ace-builds/src-min/ace.js', to: 'dependencies/ace/ace.js' },
|
|
{ from: './node_modules/ace-builds/src-min/ext-language_tools.js', to: 'dependencies/ace/ext/language_tools.js' },
|
|
{ from: './node_modules/ace-builds/src-min/ext-modelist.js', to: 'dependencies/ace/ext/modelist.js' },
|
|
{ from: './node_modules/ace-builds/src-min/mode-*.js', to: 'dependencies/ace/[name][ext]' },
|
|
{ from: './node_modules/ace-builds/src-min/snippets', to: 'dependencies/ace/snippets' },
|
|
{ from: './node_modules/ace-builds/src-min/worker-*.js', to: 'dependencies/ace/[name][ext]' },
|
|
|
|
{ from: './node_modules/leaflet-control-geocoder/dist/Control.Geocoder.css', to: 'dependencies/leaflet' },
|
|
{ from: './node_modules/leaflet-control-geocoder/dist/Control.Geocoder.min.js', to: 'dependencies/leaflet' },
|
|
{ from: './node_modules/leaflet/dist/leaflet.js', to: 'dependencies/leaflet' },
|
|
{ from: './node_modules/leaflet/dist/leaflet.css', to: 'dependencies/leaflet' },
|
|
{ from: './node_modules/leaflet/dist/images', to: 'dependencies/leaflet/images' },
|
|
|
|
{ from: './node_modules/video.js/dist/video.min.js', to: 'dependencies/videojs' },
|
|
{ from: './node_modules/video.js/dist/video-js.min.css', to: 'dependencies/videojs' },
|
|
|
|
{ from: './node_modules/font-awesome/css/font-awesome.min.css', to: 'dependencies/font-awesome/css' },
|
|
{ from: './node_modules/font-awesome/fonts', to: 'dependencies/font-awesome/fonts' },
|
|
|
|
{ from: './node_modules/vis-network/standalone/umd/vis-network.min.js', to: 'dependencies' },
|
|
],
|
|
}),
|
|
],
|
|
|
|
devServer: {
|
|
headers: {
|
|
'Access-Control-Allow-Origin': '*',
|
|
},
|
|
historyApiFallback: true,
|
|
},
|
|
};
|
|
|
|
if (!isTests) {
|
|
/*
|
|
* The entry point for the bundle. Our Angular app.
|
|
*
|
|
* See: https://webpack.js.org/configuration/entry-context/
|
|
*/
|
|
config.entry = {
|
|
shims: './app/shims.ts',
|
|
style: './app/style.js',
|
|
app: './app/app.ts',
|
|
};
|
|
|
|
if (isProduction) {
|
|
config.output = {
|
|
/*
|
|
* The output directory as absolute path (required).
|
|
*
|
|
* See: https://webpack.js.org/configuration/output/#output-path
|
|
*/
|
|
path: root('/build/'),
|
|
|
|
publicPath: './build/',
|
|
|
|
/*
|
|
* Specifies the name of each output file on disk.
|
|
*
|
|
* See: https://webpack.js.org/configuration/output/#output-filename
|
|
*/
|
|
filename: '[name].js',
|
|
|
|
/*
|
|
* The filename of non-entry chunks as relative path inside the output.path directory.
|
|
*
|
|
* See: https://webpack.js.org/configuration/output/#output-chunkfilename
|
|
*/
|
|
chunkFilename: '[id].[fullhash].chunk.js',
|
|
};
|
|
} else {
|
|
config.output = {
|
|
filename: '[name].js',
|
|
|
|
/*
|
|
* Set the public path, because we are running the website from another port (5000).
|
|
*/
|
|
publicPath: 'https://localhost:3000/',
|
|
};
|
|
}
|
|
|
|
config.plugins.push(
|
|
new plugins.HtmlWebpackPlugin({
|
|
filename: 'index.html',
|
|
hash: true,
|
|
chunks: ['shims', 'app'],
|
|
chunksSortMode: 'manual',
|
|
template: root('app', 'index.html'),
|
|
}),
|
|
);
|
|
|
|
config.plugins.push(
|
|
new plugins.HtmlWebpackPlugin({
|
|
filename: 'theme.html',
|
|
hash: true,
|
|
chunks: ['style'],
|
|
chunksSortMode: 'none',
|
|
template: root('app', '_theme.html'),
|
|
}),
|
|
);
|
|
|
|
if (isProduction) {
|
|
config.plugins.push(
|
|
new plugins.ESLintPlugin({
|
|
files: [
|
|
'./app/**/*.ts',
|
|
],
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
|
|
if (isProduction) {
|
|
config.optimization = {
|
|
minimizer: [
|
|
new plugins.TerserPlugin({
|
|
terserOptions: {
|
|
compress: true,
|
|
ecma: 5,
|
|
mangle: true,
|
|
output: {
|
|
comments: false,
|
|
},
|
|
safari10: true,
|
|
},
|
|
extractComments: true,
|
|
}),
|
|
|
|
new plugins.OptimizeCSSAssetsPlugin({}),
|
|
],
|
|
};
|
|
|
|
config.plugins.push(new plugins.BuildOptimizerWebpackPlugin());
|
|
|
|
config.module.rules.push({
|
|
test: /\.js$/,
|
|
use: [{
|
|
loader: '@angular-devkit/build-optimizer/webpack-loader',
|
|
options: {
|
|
sourceMap: false,
|
|
},
|
|
}],
|
|
});
|
|
}
|
|
|
|
if (isTestCoverage) {
|
|
// Do not instrument tests.
|
|
config.module.rules.push({
|
|
test: /\.[jt]sx?$/,
|
|
use: [{
|
|
loader: '@ngtools/webpack',
|
|
}],
|
|
include: [/\.(e2e|spec)\.ts$/],
|
|
});
|
|
|
|
// Use instrument loader for all normal files.
|
|
config.module.rules.push({
|
|
test: /\.[jt]sx?$/,
|
|
use: [{
|
|
loader: 'istanbul-instrumenter-loader',
|
|
options: {
|
|
esModules: true,
|
|
},
|
|
}, {
|
|
loader: '@ngtools/webpack',
|
|
}],
|
|
exclude: [/\.(e2e|spec)\.ts$/],
|
|
});
|
|
} else {
|
|
config.module.rules.push({
|
|
test: /\.[jt]sx?$/,
|
|
use: [{
|
|
loader: '@ngtools/webpack',
|
|
}],
|
|
});
|
|
}
|
|
|
|
if (isProduction) {
|
|
config.module.rules.push({
|
|
test: /\.scss$/,
|
|
/*
|
|
* Extract the content from a bundle to a file.
|
|
*
|
|
* See: https://github.com/webpack-contrib/extract-text-webpack-plugin
|
|
*/
|
|
use: [
|
|
plugins.MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader',
|
|
}, {
|
|
loader: 'postcss-loader',
|
|
}, {
|
|
loader: 'sass-loader',
|
|
}],
|
|
/*
|
|
* Do not include component styles.
|
|
*/
|
|
include: root('app', 'theme'),
|
|
});
|
|
} else {
|
|
config.module.rules.push({
|
|
test: /\.scss$/,
|
|
use: [{
|
|
loader: 'style-loader',
|
|
}, {
|
|
loader: 'css-loader',
|
|
}, {
|
|
loader: 'postcss-loader',
|
|
}, {
|
|
loader: 'sass-loader',
|
|
options: {
|
|
sourceMap: true,
|
|
},
|
|
}],
|
|
// Do not include component styles.
|
|
include: root('app', 'theme'),
|
|
});
|
|
}
|
|
|
|
if (isAnalyzing) {
|
|
config.plugins.push(new plugins.BundleAnalyzerPlugin());
|
|
}
|
|
|
|
return config;
|
|
};
|
|
|