From 447e72b16e82868e735e61bf83359ec63fc6aeb3 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Mon, 29 May 2023 12:44:29 +0100 Subject: [PATCH 1/3] refactor: Add CSS extraction for production build - Add `mini-css-extract-plugin` to `devDependencies` - Optimize production builds with `MiniCssExtractPlugin` - Improve CSS webpack rules for production and development builds --- package-lock.json | 29 +++++++++++++++ package.json | 1 + public/assets/app.css | 1 + public/assets/app.css.br | Bin 0 -> 963 bytes public/assets/app.js | 1 - public/assets/app.js.br | Bin 3842 -> 16694 bytes webpack.config.js | 74 +++++++++++++++++++++++++++------------ 7 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 public/assets/app.css create mode 100644 public/assets/app.css.br diff --git a/package-lock.json b/package-lock.json index 16b9a4de..75033586 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "cssnano": "^6.0.1", "eslint": "^8.41.0", "eslint-webpack-plugin": "^4.0.1", + "mini-css-extract-plugin": "^2.7.6", "postcss": "^8.4.24", "postcss-combine-duplicated-selectors": "^10.0.2", "postcss-combine-media-query": "^1.0.1", @@ -4956,6 +4957,25 @@ "node": ">=4" } }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10893,6 +10913,15 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, + "mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "requires": { + "schema-utils": "^4.0.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index e97174d5..987c3d5b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "cssnano": "^6.0.1", "eslint": "^8.41.0", "eslint-webpack-plugin": "^4.0.1", + "mini-css-extract-plugin": "^2.7.6", "postcss": "^8.4.24", "postcss-combine-duplicated-selectors": "^10.0.2", "postcss-combine-media-query": "^1.0.1", diff --git a/public/assets/app.css b/public/assets/app.css new file mode 100644 index 00000000..71e197ea --- /dev/null +++ b/public/assets/app.css @@ -0,0 +1 @@ +:root{--font-family-headings:"Archer SSm A","Archer SSm B",serif;--font-family-body:"Verlag A","Verlag B",sans-serif;--font-family-monospace:"Operator Mono SSm A","Operator Mono SSm B",monospace;--font-size-sm:0.75rem;--font-size-base:1rem;--font-size-md:1.25rem;--font-size-lg:1.5rem;--font-size-xl:1.75rem;--font-size-xxl:2rem;--font-size-xxxl:2.25rem;--color-primary:#334700;--color-secondary:#e3ffb7;--color-link:#00649e;--color-link-visited:#bc7aff;--color-primary-shadow:rgba(16,25,0,.4)}@supports (color:color(display-p3 0 0 0)){:root{--color-primary:color(display-p3 0.21567 0.27838 0.03615);--color-secondary:color(display-p3 0.91016 0.99842 0.74082);--color-link:color(display-p3 0.01045 0.38351 0.63618);--color-link-visited:color(display-p3 0.70467 0.47549 0.99958);--color-primary-shadow:color(display-p3 0.06762 0.09646 0.00441/0.4)}}@supports (color:oklch(0% 0 0)){:root{--color-primary:oklch(36.8% 0.1 125.505);--color-secondary:oklch(96.3% 0.1 125.505);--color-link:oklch(48.09% 0.146 241.41);--color-link-visited:oklch(70.44% 0.21 304.41);--color-primary-shadow:oklch(19.56% 0.054 125.505/40%)}}body{background-color:var(--color-secondary);color:var(--color-primary);font-family:var(--font-family-body);font-size:var(--font-size-md)}code{font-family:var(--font-family-monospace)}h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings)}.grid{display:grid;grid-template-columns:5vw 1fr 5vw;grid-template-rows:-webkit-min-content 1fr -webkit-min-content;grid-template-rows:min-content 1fr min-content;row-gap:1rem}#site-header{grid-column:2/3;grid-row:1/2}main{grid-row:2/3}footer,main{grid-column:2/3}footer{grid-row:3/4}footer .iwc-logo{max-width:85vw}a{color:var(--color-link)}a:visited{color:var(--color-link-visited)}#site-header a:visited{color:var(--color-link)}.hljs{border-radius:.5rem}.p-bridgy-twitter-content{display:none}.h-card .hovercard{-webkit-box-orient:vertical;-webkit-box-direction:normal;background-color:var(--color-secondary);border-radius:1rem;-webkit-box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);display:none;-ms-flex-direction:column;flex-direction:column;gap:.5rem;opacity:0;padding:1rem;position:absolute;-webkit-transition:opacity .5s ease-in-out;transition:opacity .5s ease-in-out;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:100}.h-card .hovercard .u-photo{max-width:6rem}.h-card .hovercard .social-icon{height:1rem;width:1rem}.h-card:hover .hovercard{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.h-entry{-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);padding-inline-start:.5rem}.h-entry .reply-to{font-style:italic}.h-entry .post-info a{text-decoration:none}.h-entry .note-metadata{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}.h-entry .note-metadata .syndication-links{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.h-entry .note-metadata .syndication-links a{text-decoration:none}.h-entry .note-metadata .syndication-links a svg{height:1rem;width:1rem} diff --git a/public/assets/app.css.br b/public/assets/app.css.br new file mode 100644 index 0000000000000000000000000000000000000000..f38bc392f07b926686758d024c9952e0b4da0501 GIT binary patch literal 963 zcmb2X%)`)gsPO$Fjoc2!M+aO}SL*)GU&T9r=^5cQhikQ7eebCGkrKIfW6-x3jk`Qg zfA&+}{n`HdrLTi&jt2 z^tuqH7FsjaVtRXsAOt_MMKB z)g7^y?AD#h)mzg3^3<#Et2mS0n;mod*P+^!&ywp;eo%bfc}irKXyW$wPLVf1R2Hjv zyGTa1uU@^jyG`}+p>~_UR|L+is=Bo`!7@sJ&*@2ADmF~n+-#XApE-4=3X0fhf8d%w zYbK|iOr<$b>QcFNGrzU9S7!9>}(`ee#B@Z0x#AkALSdzcRrgAW3@}r?WuD zVil$m-%Tv`U{}bw(sj<#XB7DR&KZv^A!*o?6=d{P@#(5uICa$RvC7wMzPZ zIcC0Q>NJ!26Rxor1?(0RNU%Kqzftj#zB+Ni zKq&J{;_ltub$h<09y1E=lSzy{W}`GSNze9~nPs(>AN|& zVNLFpeJ3R)Mc@6fx7?V-peP&aSMkNCFlkTx&zBJ{yWDnWMm^hmRylm(WCQ8yu)oTA zw;p_L+@;sxuEz5{a*NTEWttB4Xd*@;wN){M`BC$Rq1W zx25N!)i3bn*gTehBs4>9r|!~|wNHXxEPEw5eWLu-92v*?&W~0U-G0M9=}qz-ryWK{ z0!M$`IA}8M<>F8C{{^VjwybHBWY6{ST=;NykGAY>i|-px#jw8*VO}eztRQ;WM3zw| zcH#LYa|(}rRkdDOY_0?" ".concat(o[5]):""," {")),r+=n(o),e&&(r+="}"),o[2]&&(r+="}"),o[4]&&(r+="}"),r})).join("")},o.i=function(n,r,e,t,i){"string"==typeof n&&(n=[[null,n,void 0]]);var a={};if(e)for(var s=0;s0?" ".concat(l[5]):""," {").concat(l[1],"}")),l[5]=i),r&&(l[2]?(l[1]="@media ".concat(l[2]," {").concat(l[1],"}"),l[2]=r):l[2]=r),t&&(l[4]?(l[1]="@supports (".concat(l[4],") {").concat(l[1],"}"),l[4]=t):l[4]="".concat(t)),o.push(l))}},o}},537:function(n){n.exports=function(n){var o=n[1],r=n[3];if(!r)return o;if("function"==typeof btoa){var e=btoa(unescape(encodeURIComponent(JSON.stringify(r)))),t="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(e),i="/*# ".concat(t," */");return[o].concat([i]).join("\n")}return[o].join("\n")}},379:function(n){var o=[];function r(n){for(var r=-1,e=0;e0?" ".concat(r.layer):""," {")),e+=r.css,t&&(e+="}"),r.media&&(e+="}"),r.supports&&(e+="}");var i=r.sourceMap;i&&"undefined"!=typeof btoa&&(e+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),o.styleTagTransform(e,n,o.options)}(o,n,r)},remove:function(){!function(n){if(null===n.parentNode)return!1;n.parentNode.removeChild(n)}(o)}}}},589:function(n){n.exports=function(n,o){if(o.styleSheet)o.styleSheet.cssText=n;else{for(;o.firstChild;)o.removeChild(o.firstChild);o.appendChild(document.createTextNode(n))}}}},f={};function u(n){var o=f[n];if(void 0!==o)return o.exports;var r=f[n]={id:n,exports:{}};return p[n](r,r.exports,u),r.exports}u.n=function(n){var o=n&&n.__esModule?function(){return n.default}:function(){return n};return u.d(o,{a:o}),o},u.d=function(n,o){for(var r in o)u.o(o,r)&&!u.o(n,r)&&Object.defineProperty(n,r,{enumerable:!0,get:o[r]})},u.o=function(n,o){return Object.prototype.hasOwnProperty.call(n,o)},u.nc=void 0,n=u(379),o=u.n(n),r=u(795),e=u.n(r),t=u(569),i=u.n(t),a=u(565),s=u.n(a),c=u(216),A=u.n(c),l=u(589),C=u.n(l),d=u(661),(m={}).styleTagTransform=C(),m.setAttributes=s(),m.insert=i().bind(null,"head"),m.domAPI=e(),m.insertStyleElement=A(),o()(d.Z,m),d.Z&&d.Z.locals&&d.Z.locals}(); \ No newline at end of file diff --git a/public/assets/app.js.br b/public/assets/app.js.br index 824c5747de1d87a39965e86c5215177a966bb81c..961f6a0332b68f0ba0ac53e20328d3e031234540 100644 GIT binary patch literal 16694 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 literal 3842 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 Bb4&mL diff --git a/webpack.config.js b/webpack.config.js index 703b543a..447c6d42 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,6 +3,7 @@ const StyleLintPlugin = require('stylelint-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin'); const zlib = require('zlib'); const EslintPlugin = require('eslint-webpack-plugin'); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const config = { entry: ['./resources/js/app.js'], @@ -12,29 +13,6 @@ const config = { }, module: { rules: [{ - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: 'style-loader' - }, - { - loader: 'css-loader', - options: { - sourceMap: process.env.NODE_ENV !== 'production' - } - }, - { - loader: 'postcss-loader', - options: { - postcssOptions: { - config: path.resolve(__dirname, 'postcss.config.js'), - }, - sourceMap: process.env.NODE_ENV !== 'production' - } - } - ] - }, { test: /\.js$/, exclude: /node_modules/, use: { @@ -74,6 +52,56 @@ const config = { module.exports = (env, argv) => { if (argv.mode === 'development') { config.devtool = 'eval-source-map'; + + config.module.rules.push({ + test: /\.css$/, + exclude: /node_modules/, + use: [ + { + loader: 'style-loader' + }, + { + loader: 'css-loader', + options: { + sourceMap: true + } + }, + { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: path.resolve(__dirname, 'postcss.config.js'), + }, + sourceMap: true + } + } + ] + }); + } + + if (argv.mode === 'production') { + config.module.rules.push({ + test: /\.css$/, + exclude: /node_modules/, + use: [ + { + loader: MiniCssExtractPlugin.loader, + }, + { + loader: 'css-loader', + }, + { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: path.resolve(__dirname, 'postcss.config.js'), + }, + } + } + ] + }); + + config.plugins.push(new MiniCssExtractPlugin({filename: 'app.css'})); } return config; From e62f68f51430a4481060c1effcb7d8d537270769 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Mon, 29 May 2023 12:46:17 +0100 Subject: [PATCH 2/3] style: Improve security by updating CSP headers - Update `CSPHeader.php` to improve security by removing unsafe-inline. --- app/Http/Middleware/CSPHeader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Middleware/CSPHeader.php b/app/Http/Middleware/CSPHeader.php index d5cd4c53..07e77e3a 100644 --- a/app/Http/Middleware/CSPHeader.php +++ b/app/Http/Middleware/CSPHeader.php @@ -25,7 +25,7 @@ class CSPHeader ->header( 'Content-Security-Policy', "default-src 'self'; " . - "style-src 'self' 'unsafe-inline' cloud.typography.com jonnybarnes.uk; " . + "style-src 'self' cloud.typography.com jonnybarnes.uk; " . "img-src 'self' data: blob: https://pbs.twimg.com https://jbuk-media.s3-eu-west-1.amazonaws.com https://jbuk-media-dev.s3-eu-west-1.amazonaws.com https://secure.gravatar.com https://graph.facebook.com *.fbcdn.net https://*.cdninstagram.com https://*.4sqi.net https://upload.wikimedia.org; " . "font-src 'self' data:; " . "frame-src 'self' https://www.youtube.com blob:; " . From 16c945b3a6a4238c605602b326aa5b7220d87c1a Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Mon, 29 May 2023 12:50:24 +0100 Subject: [PATCH 3/3] chore: Improve production mode stylesheet loading workflow - Add production mode stylesheet link to master.blade.php file --- resources/views/master.blade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php index 16edef4c..d387c93b 100644 --- a/resources/views/master.blade.php +++ b/resources/views/master.blade.php @@ -8,6 +8,9 @@ @endif + @production + + @endproduction