Created
November 28, 2018 16:27
-
-
Save danwellman/954c74df23f2eb5ab635a5c6d08720d9 to your computer and use it in GitHub Desktop.
Custom Webpack Config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const path = require('path'); | |
| const CopyWebpackPlugin = require('copy-webpack-plugin'); | |
| const autoprefixer = require('autoprefixer'); | |
| const postcssUrl = require('postcss-url'); | |
| const cssnano = require('cssnano'); | |
| const customProperties = require('postcss-custom-properties'); | |
| const webpack = require('webpack'); | |
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |
| const CleanWebpackPlugin = require('clean-webpack-plugin'); | |
| const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; | |
| const { NoEmitOnErrorsPlugin, SourceMapDevToolPlugin, NormalModuleReplacementPlugin } = require('webpack'); | |
| const { AngularCompilerPlugin } = require('@ngtools/webpack'); | |
| const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | |
| const postcssPlugins = function (env) { | |
| // safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193 | |
| const importantCommentRe = /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i; | |
| const baseHref = ''; | |
| const deployUrl = ''; | |
| const minimizeOptions = { | |
| autoprefixer: false, | |
| safe: true, | |
| mergeLonghand: false, | |
| discardComments: { remove: (comment) => !importantCommentRe.test(comment) } | |
| }; | |
| return [ | |
| postcssUrl({ | |
| url: (URL) => { | |
| // Only convert root relative URLs, which CSS-Loader won't process into require(). | |
| if (!URL.url.startsWith('/') || URL.url.startsWith('//')) { | |
| return URL.url; | |
| } | |
| if (deployUrl.match(/:\/\//)) { | |
| // If deployUrl contains a scheme, ignore baseHref use deployUrl as is. | |
| return `${deployUrl.replace(/\/$/, '')}${URL.url}`; | |
| } | |
| else if (baseHref.match(/:\/\//)) { | |
| // If baseHref contains a scheme, include it as is. | |
| return baseHref.replace(/\/$/, '') + | |
| `/${deployUrl}/${URL.url}`.replace(/\/\/+/g, '/'); | |
| } | |
| else { | |
| // Join together base-href, deploy-url and the original URL. | |
| // Also dedupe multiple slashes into single ones. | |
| return `/${baseHref}/${deployUrl}/${URL.url}`.replace(/\/\/+/g, '/'); | |
| } | |
| } | |
| }), | |
| autoprefixer(), | |
| customProperties({ preserve: true }) | |
| ].concat(env === 'prod' ? [cssnano(minimizeOptions)] : []); | |
| }; | |
| const builder = (customer, prodEnv) => { | |
| let plugins = [ | |
| new NoEmitOnErrorsPlugin(), | |
| new CleanWebpackPlugin(['target/classes/static/' + customer]), | |
| new MiniCssExtractPlugin({ | |
| filename: '[name].css', | |
| chunkFilename: '[id].css' | |
| }), | |
| new CopyWebpackPlugin([ | |
| { | |
| context: 'src/main/angular', | |
| to: '', | |
| from: { | |
| glob: 'assets/**/*', | |
| dot: true | |
| } | |
| }, | |
| { | |
| context: 'src/main/angular', | |
| to: '', | |
| from: { | |
| glob: 'favicon.ico', | |
| dot: true | |
| } | |
| } | |
| ], { | |
| ignore: [ | |
| '.gitkeep', | |
| '**/.DS_Store' | |
| ], | |
| debug: 'warning' | |
| }), | |
| //Replace the actual environment file with the correct one passed in via env args | |
| new NormalModuleReplacementPlugin(/(.*)\environments\/environment(\.*)/, function(resource) { | |
| resource.request = resource.request.replace('environments/environment', | |
| `environments/${customer}/environment.${prodEnv}`); | |
| }), | |
| //Replace the actual chart-colors file with the correct one based on customer | |
| new NormalModuleReplacementPlugin(/(.*)\environments\/chart-colors.json/, function(resource) { | |
| resource.request = resource.request.replace('environments/chart-colors.json', | |
| `environments/${customer}/chart-colors.json`); | |
| }), | |
| //Replace the actual lang file with the correct one based on customer | |
| new NormalModuleReplacementPlugin(/(.*)\environments\/lang.json/, function(resource) { | |
| resource.request = resource.request.replace('environments/lang.json', | |
| `environments/${customer}/lang.json`); | |
| }), | |
| //Replace the actual scss file with the correct one based on customer | |
| new NormalModuleReplacementPlugin(/(.*)\environments\/styles.scss/, function(resource) { | |
| resource.request = resource.request.replace('environments/styles.scss', | |
| `environments/${customer}/styles.scss`); | |
| }), | |
| new AngularCompilerPlugin({ | |
| mainPath: 'main.ts', | |
| platform: 0, | |
| sourceMap: (prodEnv === 'dev') ? true : false, | |
| tsConfigPath: 'src/main/angular/tsconfig.app.json', | |
| skipCodeGeneration: false, | |
| compilerOptions: {} | |
| }), | |
| new webpack.ProvidePlugin({ | |
| $: 'jquery', | |
| jQuery: 'jquery', | |
| "window.jQuery": 'jquery', | |
| Hammer: 'hammerjs/hammer' | |
| }) | |
| ]; | |
| let devPlugins = [ | |
| new SourceMapDevToolPlugin({ | |
| filename: '[file].map[query]', | |
| moduleFilenameTemplate: '[resource-path]', | |
| fallbackModuleFilenameTemplate: '[resource-path]?[hash]', | |
| sourceRoot: 'webpack:///' | |
| }), | |
| new BundleAnalyzerPlugin({ | |
| generateStatsFile: true | |
| }) | |
| ]; | |
| let prodPlugins = [ | |
| new UglifyJsPlugin({ | |
| parallel: true, | |
| sourceMap: false | |
| }) | |
| ]; | |
| plugins = prodEnv === 'dev' | |
| ? plugins.concat(devPlugins) | |
| : plugins.concat(prodPlugins); | |
| return { | |
| resolve: { | |
| extensions: [ | |
| '.ts', | |
| '.js' | |
| ], | |
| modules: [ | |
| './node_modules' | |
| ], | |
| symlinks: true, | |
| alias: { | |
| "rxjs/" : './node_modules/rxjs/_esm2015/' | |
| }, | |
| mainFields: [ | |
| 'browser', | |
| 'module', | |
| 'main' | |
| ] | |
| }, | |
| resolveLoader: { | |
| modules: [ | |
| './node_modules' | |
| ] | |
| }, | |
| entry: { | |
| main: [ | |
| './src/main/angular/main.ts' | |
| ], | |
| polyfills: [ | |
| './src/main/angular/polyfills.ts' | |
| ] | |
| }, | |
| optimization: { | |
| splitChunks: { | |
| cacheGroups: { | |
| vendor: { | |
| chunks: 'initial', | |
| test: path.resolve(__dirname, 'node_modules'), | |
| name: 'vendor', | |
| enforce: true, | |
| filename: 'vendor.chunk.js' | |
| } | |
| } | |
| } | |
| }, | |
| output: { | |
| path: path.join(process.cwd(), 'target', 'classes', 'static', customer), | |
| filename: '[name].bundle.js', | |
| chunkFilename: '[id].chunk.js', | |
| crossOriginLoading: false | |
| }, | |
| module: { | |
| rules: [ | |
| { | |
| test: /\.html$/, | |
| loader: 'raw-loader' | |
| }, | |
| { | |
| test: /\.(eot|svg|cur)$/, | |
| loader: 'file-loader', | |
| options: { | |
| name: '[name].[hash:20].[ext]', | |
| limit: 10000 | |
| } | |
| }, | |
| { | |
| test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/, | |
| loader: 'url-loader', | |
| options: { | |
| name: '[name].[hash:20].[ext]', | |
| limit: 10000 | |
| } | |
| }, | |
| { | |
| test: /\.css$/, | |
| use: [ | |
| 'exports-loader?module.exports.toString()', | |
| { | |
| loader: 'css-loader', | |
| options: { | |
| sourceMap: false, | |
| importLoaders: 1 | |
| } | |
| }, | |
| { | |
| loader: 'postcss-loader', | |
| options: { | |
| ident: 'postcss', | |
| plugins: postcssPlugins(prodEnv) | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| include: [ | |
| path.join(process.cwd(), `src/main/angular/environments/${customer}/styles.scss`) | |
| ], | |
| test: /\.css$/, | |
| use: [ | |
| 'style-loader', | |
| { | |
| loader: 'css-loader', | |
| options: { | |
| sourceMap: false, | |
| importLoaders: 1 | |
| } | |
| }, | |
| { | |
| loader: 'postcss-loader', | |
| options: { | |
| ident: 'postcss', | |
| plugins: postcssPlugins(prodEnv) | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| include: [ | |
| path.join(process.cwd(), `src/main/angular/environments/${customer}/styles.scss`) | |
| ], | |
| test: /\.scss$/, | |
| use: [ | |
| MiniCssExtractPlugin.loader, | |
| { | |
| loader: 'css-loader', | |
| options: { | |
| sourceMap: false, | |
| importLoaders: 1 | |
| } | |
| }, | |
| { | |
| loader: 'postcss-loader', | |
| options: { | |
| ident: 'postcss', | |
| plugins: postcssPlugins(prodEnv) | |
| } | |
| }, | |
| { | |
| loader: 'sass-loader', | |
| options: { | |
| sourceMap: false, | |
| precision: 8, | |
| includePaths: [path.join(process.cwd(), 'src', 'main', 'angular')] | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| test: /\.ts$/, | |
| loader: '@ngtools/webpack' | |
| } | |
| ] | |
| }, | |
| plugins: plugins, | |
| node: { | |
| fs: 'empty', | |
| global: true, | |
| crypto: 'empty', | |
| tls: 'empty', | |
| net: 'empty', | |
| process: true, | |
| module: false, | |
| clearImmediate: false, | |
| setImmediate: false | |
| }, | |
| devServer: { | |
| historyApiFallback: true | |
| } | |
| }; | |
| }; | |
| module.exports = { | |
| build: builder | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment