Change how CDN_HOST is passed down to make assets build reproducible (#14381)
* Change how CDN_HOST is passed down to make assets build reproducible * Change webpacker/webpack configuration to dynamically load publicPath based on meta header * Fix embedded layout missing the cdn-host meta header
This commit is contained in:
		
							parent
							
								
									53b22d247f
								
							
						
					
					
						commit
						4c45b43cb8
					
				
					 16 changed files with 46 additions and 24 deletions
				
			
		|  | @ -1,8 +1,7 @@ | |||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import unicodeMapping from '../features/emoji/emoji_unicode_mapping_light'; | ||||
| 
 | ||||
| const assetHost = process.env.CDN_HOST || ''; | ||||
| import { assetHost } from 'mastodon/utils/config'; | ||||
| 
 | ||||
| export default class AutosuggestEmoji extends React.PureComponent { | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import classNames from 'classnames'; | |||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import detectPassiveEvents from 'detect-passive-events'; | ||||
| import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji'; | ||||
| import { assetHost } from 'mastodon/utils/config'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' }, | ||||
|  | @ -25,7 +26,6 @@ const messages = defineMessages({ | |||
|   flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' }, | ||||
| }); | ||||
| 
 | ||||
| const assetHost = process.env.CDN_HOST || ''; | ||||
| let EmojiPicker, Emoji; // load asynchronously
 | ||||
| 
 | ||||
| const backgroundImageFn = () => `${assetHost}/emoji/sheet_10.png`; | ||||
|  |  | |||
|  | @ -1,11 +1,10 @@ | |||
| import { autoPlayGif } from '../../initial_state'; | ||||
| import unicodeMapping from './emoji_unicode_mapping_light'; | ||||
| import { assetHost } from 'mastodon/utils/config'; | ||||
| import Trie from 'substring-trie'; | ||||
| 
 | ||||
| const trie = new Trie(Object.keys(unicodeMapping)); | ||||
| 
 | ||||
| const assetHost = process.env.CDN_HOST || ''; | ||||
| 
 | ||||
| // Convert to file names from emojis. (For different variation selector emojis)
 | ||||
| const emojiFilenames = (emojis) => { | ||||
|   return emojis.map(v => unicodeMapping[v].filename); | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_pick | |||
| import AnimatedNumber from 'mastodon/components/animated_number'; | ||||
| import TransitionMotion from 'react-motion/lib/TransitionMotion'; | ||||
| import spring from 'react-motion/lib/spring'; | ||||
| import { assetHost } from 'mastodon/utils/config'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||
|  | @ -153,8 +154,6 @@ class Content extends ImmutablePureComponent { | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| const assetHost = process.env.CDN_HOST || ''; | ||||
| 
 | ||||
| class Emoji extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import GIFV from 'mastodon/components/gifv'; | |||
| import { me } from 'mastodon/initial_state'; | ||||
| import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js'; | ||||
| import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js'; | ||||
| import { assetHost } from 'mastodon/utils/config'; | ||||
| 
 | ||||
| const messages = defineMessages({ | ||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||
|  | @ -50,8 +51,6 @@ const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******') | |||
|   .replace(/\n/g, ' ') | ||||
|   .replace(/\*\*\*\*\*\*/g, '\n\n'); | ||||
| 
 | ||||
| const assetHost = process.env.CDN_HOST || ''; | ||||
| 
 | ||||
| class ImageLoader extends React.PureComponent { | ||||
| 
 | ||||
|   static propTypes = { | ||||
|  |  | |||
							
								
								
									
										10
									
								
								app/javascript/mastodon/utils/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/javascript/mastodon/utils/config.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| import ready from '../ready'; | ||||
| 
 | ||||
| export let assetHost = ''; | ||||
| 
 | ||||
| ready(() => { | ||||
|   const cdnHost = document.querySelector('meta[name=cdn-host]'); | ||||
|   if (cdnHost) { | ||||
|     assetHost = cdnHost.content || ''; | ||||
|   } | ||||
| }); | ||||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import loadPolyfills from '../mastodon/load_polyfills'; | ||||
| import { start } from '../mastodon/common'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import { delegate } from '@rails/ujs'; | ||||
| import ready from '../mastodon/ready'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import loadPolyfills from '../mastodon/load_polyfills'; | ||||
| import { start } from '../mastodon/common'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import ready from '../mastodon/ready'; | ||||
| 
 | ||||
| ready(() => { | ||||
|  |  | |||
							
								
								
									
										21
									
								
								app/javascript/packs/public-path.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/javascript/packs/public-path.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| // Dynamically set webpack's loading path depending on a meta header, in order
 | ||||
| // to share the same assets regardless of instance configuration.
 | ||||
| // See https://webpack.js.org/guides/public-path/#on-the-fly
 | ||||
| 
 | ||||
| function removeOuterSlashes(string) { | ||||
|   return string.replace(/^\/*/, '').replace(/\/*$/, ''); | ||||
| } | ||||
| 
 | ||||
| function formatPublicPath(host = '', path = '') { | ||||
|   let formattedHost = removeOuterSlashes(host); | ||||
|   if (formattedHost && !/^http/i.test(formattedHost)) { | ||||
|     formattedHost = `//${formattedHost}`; | ||||
|   } | ||||
|   const formattedPath = removeOuterSlashes(path); | ||||
|   return `${formattedHost}/${formattedPath}/`; | ||||
| } | ||||
| 
 | ||||
| const cdnHost = document.querySelector('meta[name=cdn-host]'); | ||||
| 
 | ||||
| // eslint-disable-next-line camelcase, no-undef, no-unused-vars
 | ||||
| __webpack_public_path__ = formatPublicPath(cdnHost ? cdnHost.content : '', process.env.PUBLIC_OUTPUT_PATH); | ||||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import escapeTextContentForBrowser from 'escape-html'; | ||||
| import loadPolyfills from '../mastodon/load_polyfills'; | ||||
| import ready from '../mastodon/ready'; | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import './public-path'; | ||||
| import loadPolyfills from '../mastodon/load_polyfills'; | ||||
| import { start } from '../mastodon/common'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| 
 | ||||
|     - if cdn_host? | ||||
|       %link{ rel: 'dns-prefetch', href: cdn_host }/ | ||||
|       %meta{ name: 'cdn-host', content: cdn_host }/ | ||||
| 
 | ||||
|     - if storage_host? | ||||
|       %link{ rel: 'dns-prefetch', href: storage_host }/ | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| 
 | ||||
|     - if cdn_host? | ||||
|       %link{ rel: 'dns-prefetch', href: cdn_host }/ | ||||
|       %meta{ name: 'cdn-host', content: cdn_host }/ | ||||
| 
 | ||||
|     - if storage_host? | ||||
|       %link{ rel: 'dns-prefetch', href: storage_host }/ | ||||
|  |  | |||
|  | @ -11,30 +11,17 @@ const settings = safeLoad(readFileSync(configPath), 'utf8')[env.RAILS_ENV || env | |||
| const themePath = resolve('config', 'themes.yml'); | ||||
| const themes = safeLoad(readFileSync(themePath), 'utf8'); | ||||
| 
 | ||||
| function removeOuterSlashes(string) { | ||||
|   return string.replace(/^\/*/, '').replace(/\/*$/, ''); | ||||
| } | ||||
| 
 | ||||
| function formatPublicPath(host = '', path = '') { | ||||
|   let formattedHost = removeOuterSlashes(host); | ||||
|   if (formattedHost && !/^http/i.test(formattedHost)) { | ||||
|     formattedHost = `//${formattedHost}`; | ||||
|   } | ||||
|   const formattedPath = removeOuterSlashes(path); | ||||
|   return `${formattedHost}/${formattedPath}/`; | ||||
| } | ||||
| 
 | ||||
| const output = { | ||||
|   path: resolve('public', settings.public_output_path), | ||||
|   publicPath: formatPublicPath(env.CDN_HOST, settings.public_output_path), | ||||
|   publicPath: `/${settings.public_output_path}/`, | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   settings, | ||||
|   themes, | ||||
|   env: { | ||||
|     CDN_HOST: env.CDN_HOST, | ||||
|     NODE_ENV: env.NODE_ENV, | ||||
|     PUBLIC_OUTPUT_PATH: settings.public_output_path, | ||||
|   }, | ||||
|   output, | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue