Last active
August 21, 2019 14:30
-
-
Save moderndeveloperllc/a3774d2890fcff56d7b39b9883b0879f to your computer and use it in GitHub Desktop.
webpack config - BabelMultiTargetPlugin and HtmlWebpackDeployPlugin
This file contains 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
'use strict'; | |
const BabelMultiTargetPlugin = require('webpack-babel-multi-target-plugin').BabelMultiTargetPlugin; | |
const HtmlWebpackDeployPlugin = require('html-webpack-deploy-plugin'); | |
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); | |
const {InjectManifest} = require('workbox-webpack-plugin'); | |
const {resolve, join} = require('path'); | |
const {CleanWebpackPlugin} = require('clean-webpack-plugin'); | |
const CompressionPlugin = require('compression-webpack-plugin'); | |
const fs = require('fs'); | |
const helperWhitelist = require('./utils/helper-whitelist'); | |
const helperWhitelistModern = require('./utils/helper-whitelist-modern'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const merge = require('webpack-merge'); | |
const TerserWebpackPlugin = require('terser-webpack-plugin'); | |
const crypto = require('crypto'); | |
// const zlib = require('zlib'); | |
const ENV = process.argv.find((arg) => arg.includes('production')) | |
? 'production' | |
: 'development'; | |
const ANALYZE = process.argv.find((arg) => arg.includes('--analyze')); | |
const OUTPUT_PATH = ENV === 'production' ? resolve('dist') : resolve('src'); | |
const INDEX_TEMPLATE = resolve('./src/index.html'); | |
const key = () => { | |
try { | |
return fs.readFileSync('/usr/local/etc/nginx/ssl/star_wpm.key.pem'); | |
} catch (e) { | |
console.log(e); | |
} | |
}; | |
const cert = () => { | |
try { | |
return fs.readFileSync('/usr/local/etc/nginx/ssl/star_wpm.cert.pem'); | |
} catch (e) { | |
console.log(e); | |
} | |
}; | |
const ca = () => { | |
try { | |
return fs.readFileSync('/usr/local/etc/nginx/ssl/development-ca-chain.cert.pem'); | |
} catch (e) { | |
console.log(e); | |
} | |
}; | |
const helpers = [ | |
{ | |
from: resolve('./src/vendor/*.js'), | |
to: join(OUTPUT_PATH, 'vendor', '[name].[contenthash:8].[ext]'), | |
flatten: true, | |
}, | |
]; | |
const assets = [ | |
{ | |
from: resolve('./src/assets'), | |
to: join(OUTPUT_PATH, 'assets'), | |
}, | |
{ | |
from: resolve('./src/favicon.ico'), | |
to: OUTPUT_PATH, | |
}, | |
{ | |
from: resolve('./src/manifest.json'), | |
to: OUTPUT_PATH, | |
}, | |
{ | |
from: resolve('./src/styles/*.css'), | |
to: join(OUTPUT_PATH, 'styles'), | |
flatten: true, | |
}, | |
]; | |
const commonConfig = merge([ | |
{ | |
entry: './src/index.js', | |
output: { | |
path: OUTPUT_PATH, | |
filename: '[name].[chunkhash:8].js', | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.js$/, | |
use: [ | |
BabelMultiTargetPlugin.loader(), | |
'uglify-template-string-loader', | |
], | |
}, | |
], | |
}, | |
plugins: [ | |
new HtmlWebpackPlugin({ | |
template: INDEX_TEMPLATE, | |
minify: { | |
collapseWhitespace: true, | |
removeComments: true, | |
minifyCSS: true, | |
minifyJS: true, | |
}, | |
chunksSortMode: 'none', | |
}), | |
// Babel configuration for multiple output bundles targeting different sets | |
// of browsers | |
new BabelMultiTargetPlugin({ | |
babel: { | |
plugins: [ | |
[ | |
require('@babel/plugin-external-helpers'), | |
{ | |
whitelist: [...helperWhitelist, ...helperWhitelistModern], | |
}, | |
], | |
// Minify HTML and CSS in tagged template literals | |
[ | |
require('babel-plugin-template-html-minifier'), | |
{ | |
modules: { | |
'@polymer/polymer/lib/utils/html-tag.js': ['html'], | |
'lit-html': ['html'], | |
'lit-element': [ | |
'html', | |
{'name': 'css', 'encapsulation': 'style'}, | |
], | |
}, | |
htmlMinifier: { | |
collapseWhitespace: true, | |
minifyCSS: true, | |
removeComments: true, | |
sortAttributes: true, | |
sortClassName: true, | |
}, | |
}, | |
], | |
], | |
// @babel/preset-env options common for all bundles | |
presetOptions: { | |
// Don’t add polyfills, they are provided from webcomponents-loader.js | |
useBuiltIns: false, | |
debug: true, | |
}, | |
}, | |
// Modules excluded from targeting into different bundles | |
doNotTarget: [ | |
// Array of RegExp patterns | |
], | |
// Modules that should not be transpiled | |
exclude: [ | |
// Array of RegExp patterns | |
], | |
// Fix for `nomodule` attribute to work correctly in Safari 10.1 | |
safari10NoModuleFix: false, | |
// Target browsers with and without ES modules support | |
targets: { | |
esm: { | |
browsers: [ | |
'last 2 Chrome major versions', | |
'last 2 ChromeAndroid major versions', | |
'last 2 Edge major versions', | |
'last 2 Firefox major versions', | |
'last 2 Safari major versions', | |
'last 2 iOS major versions', | |
], | |
tagAssetsWithKey: false, // don’t append a suffix to the file name | |
esModule: true, // marks the bundle used with <script type="module"> | |
}, | |
es5: { | |
browsers: ['ie 11'], | |
tagAssetsWithKey: true, // append a suffix to the file name | |
noModule: true, // marks the bundle included without `type="module"` | |
}, | |
}, | |
}), | |
new HtmlWebpackDeployPlugin({ | |
assets: { | |
copy: [...helpers, ...assets], | |
scripts: [ | |
{ | |
append: false, | |
path: './vendor/regenerator-runtime.min.js', | |
attributes: {noModule: true}, | |
}, | |
{ | |
append: false, | |
path: './vendor/babel-helpers.min.js', | |
attributes: {noModule: true}, | |
}, | |
{ | |
append: false, | |
path: './vendor/babel-helpers-modern.min.js' | |
}], | |
hash: (assetName, hash) => { | |
if (assetName) { | |
const copyFrom = assetName.replace('./vendor', './src/vendor'); | |
const contentHash = crypto.createHash('md5'). | |
update(fs.readFileSync(copyFrom, 'utf8')). | |
digest('hex'). | |
slice(0, 8); | |
assetName = assetName.replace(/\.js$/, '.' + contentHash + '.js'); | |
return assetName; | |
} | |
return assetName; | |
}, | |
}, | |
packages: { | |
'@webcomponents/webcomponentsjs': { | |
copy: [ | |
{from: 'bundles', to: 'bundles/'}, | |
{from: 'webcomponents-loader.js', to: 'webcomponents-loader.js'}, | |
], | |
scripts: { | |
variableName: 'webcomponents', | |
append: false, | |
path: 'webcomponents-loader.js', | |
}, | |
}, | |
}, | |
useAssetsPath: false, | |
usePublicPath: false, | |
}), | |
], | |
}, | |
]); | |
const developmentConfig = merge([ | |
{ | |
devtool: 'cheap-module-source-map', | |
plugins: [], | |
devServer: { | |
contentBase: OUTPUT_PATH, | |
compress: true, | |
overlay: true, | |
port: 3000, | |
host: 'fms.wpm', | |
https: { | |
key: key(), | |
cert: cert(), | |
ca: ca(), | |
}, | |
headers: { | |
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', | |
'X-Frame-Options': 'SAMEORIGIN', | |
'X-Xss-Protection': '1; mode=block', | |
'X-Content-Type-Options': 'nosniff', | |
'Referrer-Policy': 'strict-origin-when-cross-origin', | |
'Content-Security-Policy': 'default-src \'self\'; script-src \'self\' storage.googleapis.com;' + | |
' style-src \'self\' \'unsafe-inline\'; font-src data:; connect-src \'self\' https://fms-engine.wpm:9443;', | |
}, | |
historyApiFallback: true, | |
}, | |
}, | |
]); | |
const analyzeConfig = ANALYZE ? [new BundleAnalyzerPlugin()] : []; | |
const productionConfig = merge([ | |
{ | |
devtool: 'nosources-source-map', | |
optimization: { | |
minimizer: [ | |
new TerserWebpackPlugin({ | |
terserOptions: { | |
output: { | |
comments: false, | |
}, | |
}, | |
sourceMap: true, | |
parallel: true, | |
}), | |
], | |
}, | |
plugins: [ | |
new CleanWebpackPlugin({verbose: true}), | |
new InjectManifest({ | |
swSrc: resolve('src', 'service-worker.js'), | |
swDest: resolve(OUTPUT_PATH, 'sw.js'), | |
exclude: [ | |
/.*\.map$/, | |
/.*\/webcomponents-(?!loader).*\.js$/, | |
/.*\.es5\..*\.js$/, | |
], | |
}), | |
new CompressionPlugin({test: /\.(js(\.map)?|css|html|svg)$/i}), | |
/* new CompressionPlugin({ | |
filename: '[path].br[query]', | |
algorithm: 'brotliCompress', | |
test: /\.(js(\.map)?|css|html|svg)$/i, | |
compressionOptions: {level: zlib.constants.BROTLI_MAX_QUALITY}, | |
threshold: 200, | |
minRatio: 0.8, | |
deleteOriginalAssets: false, | |
}),*/ | |
...analyzeConfig, | |
], | |
}, | |
]); | |
module.exports = (mode) => { | |
if (mode === 'production') { | |
return merge(commonConfig, productionConfig, {mode}); | |
} | |
return merge(commonConfig, developmentConfig, {mode}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment