const path = require('path') const TerserPlugin = require('terser-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer const CopyPlugin = require('copy-webpack-plugin') const { InjectManifest } = require('workbox-webpack-plugin') const ManifestPlugin = require('webpack-manifest-plugin') const ImageminPlugin = require('imagemin-webpack-plugin').default const { JSDOM } = require('jsdom') const tempy = require('tempy') const fs = require('fs') const magicFile = (text) => { const p = tempy.file() fs.writeFileSync(p, text) return p } // const magicAppend = (orig, text, sep = '\n') => magicFile(fs.readFileSync(orig) + sep + text) const jsMin = { pure_funcs: ["F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"], pure_getters: true, keep_fargs: false, unsafe_comps: true, unsafe: true, compress: true, mangle: true, } module.exports = { output: { filename: "main.js", path: path.join(__dirname, "dist"), publicPath: "/" }, module: { rules: [{ test: /\.elm$/, exclude: [/elm-stuff/, /node_modules/], loader: 'elm-webpack-loader', options: { optimize: true } }], }, plugins: [ new ManifestPlugin(), new ImageminPlugin({ disable: false, pngquant: { quality: '95-100' } }), new TerserPlugin({ terserOptions: jsMin, }), new HtmlWebpackPlugin({ hash: true, meta: { viewport: 'width=device-width, initial-scale=1' } }), new CopyPlugin([{ from: 'data', to: 'data' }, { from: 'wand.js', to: 'wand.js' }]), new PrerenderSPAPlugin({ staticDir: path.join(__dirname, 'dist'), routes: ROUTES, minify: { minifyCSS: { compatibility: 'ie9', level: 2 }, minifyJS: jsMin, collapseBooleanAttributes: true, collapseWhitespace: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, removeComments: true, sortAttributes: true, sortClassName: true, }, renderer: new Renderer({ renderAfterTime: 500, }), postProcess(renderedRoute) { const dom = new JSDOM(renderedRoute.html, { runScripts: 'outside-only' }) dom.window.eval(` const wandTarget = document.createElement('script') wandTarget.src = '/wand.js' document.body.appendChild(wandTarget) `) return { ...renderedRoute, html: dom.serialize(), } }, }), new InjectManifest({ importWorkboxFrom: 'local', swSrc: magicFile(` workbox.routing.registerNavigationRoute('/index.html'); workbox.precaching.precacheAndRoute(self.__precacheManifest); `), swDest: 'sw.js', }), ] }