const { commonLoaders, styleLoader, HTMLPlugins, default: common } = require('./webpack.common.js') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') const PrerenderSPAPlugin = require('prerender-spa-plugin') const WorkboxPlugin = require('workbox-webpack-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer const path = require('path') const cheerio = require('cheerio') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const prerenderConfig = () => ({ staticDir: path.resolve('dist'), renderer: new Renderer({ renderAfterTime: 5000, skipThirdPartyRequests: true }), postProcess: context => { const $ = cheerio.load(context.html) // force https on twitter emoji cdn $('img[src^="http://twemoji.maxcdn.com"]').each((i, el) => { $(el).attr('src', (_, path) => path.replace('http://', 'https://')) }) // Remove loader $('#outdated-browser').after(` `) // Remove piwik script $('script[src$="stats.data.gouv.fr/piwik.js"]').remove() context.html = $.html() return context } }) module.exports = { ...common, module: { rules: [...commonLoaders(), styleLoader(MiniCssExtractPlugin.loader)] }, output: { ...common.output, filename: ({ chunk }) => { return chunk.name === 'simulateur-iframe-integration' ? '[name].js' : '[name].[contenthash].bundle.js' } }, mode: 'production', devtool: 'source-map', plugins: [ ...common.plugins, ...HTMLPlugins({ injectTrackingScript: true }), process.env.ANALYZE_BUNDLE && new BundleAnalyzerPlugin(), new WorkboxPlugin.GenerateSW({ clientsClaim: true, skipWaiting: true, swDest: 'sw.js', runtimeCaching: [ { urlPattern: new RegExp( 'https://fonts.(?:googleapis|gstatic).com/(.*)' ), handler: 'cacheFirst', options: { cacheName: 'google-fonts', expiration: { maxEntries: 5 }, cacheableResponse: { statuses: [0, 200] } } } ], navigateFallback: '/fallback', navigateFallbackWhitelist: [/^\/[^_]+$/], // fallback for anything that doesn't start with navigateFallbackBlacklist: [ // The service worker should ignore source maps generated by Webpack /.*.map$/, /.*\?s=.*$/, /^\/stats/, /^\/robots\.txt$/, /^\/sitemap\.infrance\.fr\.txt$/, /^\/sitemap\.infrance\.en\.txt$/ ] }), new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: '[name].[hash].css', chunkFilename: '[id].[hash].css' }), process.env.ANALYZE_BUNDLE !== '1' && new PrerenderSPAPlugin({ ...prerenderConfig(), outputDir: path.resolve('dist', 'prerender', 'infrance'), routes: [ '/', '/social-security/salaried', '/iframes/simulateur-embauche' ], indexPath: path.resolve('dist', 'infrance.html') }), process.env.ANALYZE_BUNDLE !== '1' && new PrerenderSPAPlugin({ ...prerenderConfig(), outputDir: path.resolve('dist', 'prerender', 'mon-entreprise'), routes: [ '/', '/simulateurs/salarié', '/simulateurs/auto-entrepreneur', '/simulateurs/artiste-auteur', '/simulateurs/assimilé-salarié', '/simulateurs/indépendant', '/créer', '/coronavirus', '/gérer', '/iframes/simulateur-embauche', '/iframes/simulateur-chomage-partiel' ], indexPath: path.resolve('dist', 'mon-entreprise.html') }) ].filter(Boolean) }