|
| 1 | +/** |
| 2 | + * Generates Netlify HTTP2 Server Push headers and redirect rules for preact-cli |
| 3 | + * A lot of this code is borrowed from https://github.com/developit/preact-cli/blob/master/src/lib/webpack/push-manifest.js |
| 4 | + */ |
| 5 | + |
| 6 | +class NetlifyServerPushPlugin { |
| 7 | + apply(compiler) { |
| 8 | + compiler.plugin('emit', (compilation, callback) => { |
| 9 | + const routes = []; |
| 10 | + let mainJs; |
| 11 | + let mainCss; |
| 12 | + |
| 13 | + for (const filename in compilation.assets) { |
| 14 | + if (!/\.map$/.test(filename)) { |
| 15 | + if (/route-/.test(filename)) { |
| 16 | + routes.push(filename); |
| 17 | + } else if (/^style(.+)\.css$/.test(filename)) { |
| 18 | + mainCss = `Link: </${filename}>; rel=preload; as=style`; |
| 19 | + } else if (/^bundle(.+)\.js$/.test(filename)) { |
| 20 | + mainJs = `Link: </${filename}>; rel=preload; as=script`; |
| 21 | + } |
| 22 | + } |
| 23 | + } |
| 24 | + |
| 25 | + let headers = |
| 26 | + '/*\n\tCache-Control: public, max-age=3600, no-cache\n\tAccess-Control-Max-Age: 600\n/sw.js\n\tCache-Control: private, no-cache\n/*.chunk.*.js\n\tCache-Control: public, max-age=31536000'; |
| 27 | + |
| 28 | + const redirects = `/* /index.html 200`; |
| 29 | + |
| 30 | + routes.forEach(filename => { |
| 31 | + const path = filename |
| 32 | + .replace(/route-/, '/') |
| 33 | + .replace(/\.chunk(\.\w+)?\.js$/, '') |
| 34 | + .replace(/\/home/, '/'); |
| 35 | + const routeJs = `Link: </${filename}>; rel=preload; as=script`; |
| 36 | + headers = `${headers}\n${path}\n\t${mainCss}\n\t${mainJs}\n\t${routeJs}`; |
| 37 | + }); |
| 38 | + |
| 39 | + compilation.assets._headers = { |
| 40 | + source() { |
| 41 | + return headers; |
| 42 | + }, |
| 43 | + size() { |
| 44 | + return headers.length; |
| 45 | + }, |
| 46 | + }; |
| 47 | + |
| 48 | + compilation.assets._redirects = { |
| 49 | + source() { |
| 50 | + return redirects; |
| 51 | + }, |
| 52 | + size() { |
| 53 | + return redirects.length; |
| 54 | + }, |
| 55 | + }; |
| 56 | + |
| 57 | + callback(); |
| 58 | + }); |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +module.exports = function(config) { |
| 63 | + if (!config || !config.plugins) { |
| 64 | + throw new Error('You need to pass the webpack config to preact-cli-plugin-netlify!'); |
| 65 | + } |
| 66 | + config.plugins.push(new NetlifyServerPushPlugin()); |
| 67 | + const plugins = config.plugins; |
| 68 | + for (let pluginIndex = 0; pluginIndex < plugins.length; pluginIndex++) { |
| 69 | + const plugin = plugins[pluginIndex]; |
| 70 | + if (plugin && plugin.options && plugin.options.cacheId) { |
| 71 | + // Ignore genearted _headers and _redirects files from SW precaching |
| 72 | + Object.assign(plugin.options, { |
| 73 | + staticFileGlobsIgnorePatterns: [ |
| 74 | + ...plugin.options.staticFileGlobsIgnorePatterns, |
| 75 | + /_headers/, |
| 76 | + /_redirects/, |
| 77 | + ], |
| 78 | + }); |
| 79 | + } |
| 80 | + } |
| 81 | +}; |
0 commit comments