Implement discount fingerprinting without webpack (#17337)

This commit is contained in:
James M. Greene 2021-01-19 23:00:54 -06:00 коммит произвёл GitHub
Родитель 87dbf0a19f
Коммит 9724f763f5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 35 добавлений и 5 удалений

Просмотреть файл

@ -23,7 +23,7 @@
/> />
{% endfor %} {% endfor %}
<link rel="stylesheet" href="/dist/index.css"> <link rel="stylesheet" href="{{ builtAssets.main.css }}">
<link rel="alternate icon" type="image/png" href="/assets/images/site/favicon.png"> <link rel="alternate icon" type="image/png" href="/assets/images/site/favicon.png">
<link rel="icon" type="image/svg+xml" href="/assets/images/site/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/assets/images/site/favicon.svg">
</head> </head>

Просмотреть файл

@ -1 +1 @@
<script src="/dist/index.js"></script> <script src="{{ builtAssets.main.js }}"></script>

Просмотреть файл

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Docs TOC</title> <title>Docs TOC</title>
<link rel="stylesheet" href="/dist/index.css"> <link rel="stylesheet" href="{{ builtAssets.main.css }}">
<link rel="alternate icon" type="image/png" href="/assets/images/site/favicon.png"> <link rel="alternate icon" type="image/png" href="/assets/images/site/favicon.png">
<link rel="icon" type="image/svg+xml" href="/assets/images/site/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/assets/images/site/favicon.svg">
</head> </head>

23
lib/built-asset-urls.js Normal file
Просмотреть файл

@ -0,0 +1,23 @@
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
// Get an MD4 Digest Hex content hash, loosely based on Webpack `[contenthash]`
function getContentHash (absFilePath) {
const buffer = fs.readFileSync(absFilePath)
const hash = crypto.createHash('md4')
hash.update(buffer)
return hash.digest('hex')
}
function getUrl (relFilePath) {
const absFilePath = path.join(process.cwd(), relFilePath)
return `/${relFilePath}?hash=${getContentHash(absFilePath)}`
}
module.exports = {
main: {
js: getUrl('dist/index.js'),
css: getUrl('dist/index.css')
}
}

Просмотреть файл

@ -7,6 +7,7 @@ const { getVersionStringFromPath, getProductStringFromPath, getPathWithoutLangua
const productNames = require('../lib/product-names') const productNames = require('../lib/product-names')
const warmServer = require('../lib/warm-server') const warmServer = require('../lib/warm-server')
const featureFlags = Object.keys(require('../feature-flags')) const featureFlags = Object.keys(require('../feature-flags'))
const builtAssets = require('../lib/built-asset-urls')
// Supply all route handlers with a baseline `req.context` object // Supply all route handlers with a baseline `req.context` object
// Note that additional middleware in middleware/index.js adds to this context object // Note that additional middleware in middleware/index.js adds to this context object
@ -42,5 +43,8 @@ module.exports = async function contextualize (req, res, next) {
req.context.siteTree = siteTree req.context.siteTree = siteTree
req.context.pages = pageMap req.context.pages = pageMap
// JS + CSS asset paths
req.context.builtAssets = builtAssets
return next() return next()
} }

Просмотреть файл

@ -4,6 +4,7 @@ const { get, getDOM, head } = require('../helpers/supertest')
const { describeViaActionsOnly } = require('../helpers/conditional-runs') const { describeViaActionsOnly } = require('../helpers/conditional-runs')
const path = require('path') const path = require('path')
const { loadPages } = require('../../lib/pages') const { loadPages } = require('../../lib/pages')
const builtAssets = require('../../lib/built-asset-urls')
describe('server', () => { describe('server', () => {
jest.setTimeout(60 * 1000) jest.setTimeout(60 * 1000)
@ -694,7 +695,8 @@ describe('?json query param for context debugging', () => {
describe('stylesheets', () => { describe('stylesheets', () => {
it('compiles and sets the right content-type header', async () => { it('compiles and sets the right content-type header', async () => {
const res = await get('/dist/index.css') const stylesheetUrl = builtAssets.main.css
const res = await get(stylesheetUrl)
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
expect(res.headers['content-type']).toBe('text/css; charset=UTF-8') expect(res.headers['content-type']).toBe('text/css; charset=UTF-8')
}) })
@ -703,7 +705,8 @@ describe('stylesheets', () => {
describe('client-side JavaScript bundle', () => { describe('client-side JavaScript bundle', () => {
let res let res
beforeAll(async (done) => { beforeAll(async (done) => {
res = await get('/dist/index.js') const scriptUrl = builtAssets.main.js
res = await get(scriptUrl)
done() done()
}) })