Repository URL to install this package:
|
Version:
1.2.8 ▾
|
/* eslint-disable max-statements */
/**
* @file resolves the entry assets available from our client bundle
* @see scripts/.plugins
* @name getClientBundleEntryAssets
*/
import { resolve } from 'path'
import { isString } from 'exotic'
import { exists, readJSON } from '@skava/persistence/dist/adapters/server'
import { getAbsoluteUrl } from './getDynamicPaths'
interface ManifestOutput {
[key: string]: string | ManifestOutput
}
let resultCache
function validateAssetsPath(assetsFilePath: string) {
if (!exists(assetsFilePath)) {
const errorMessage = `
We could not find the "${assetsFilePath}" file,
which contains a list of the assets of the client bundle.
Please ensure that the client bundle has been built.
`
const noAssets = new Error(errorMessage)
throw noAssets
}
}
function validateAssetEntryPointForIndex(
index?: ManifestOutput | string | undefined | any
) {
if (typeof index === 'undefined') {
throw new Error(
'No asset data found for expected "index" entry chunk of client bundle.'
)
}
}
function validateHackPath(assetObjJs: string) {
if (!isString(assetObjJs)) {
const value = JSON.stringify(assetObjJs, undefined, 2)
const error = 'must remap a string path. received: ' + value
throw new TypeError(error)
}
}
/**
* 1. add dynamic port
* 2. assert https unless localhost
* 3. validate
*/
function hackPath(assetObjJs: string = '') {
validateHackPath(assetObjJs)
const original = assetObjJs
const FINAL_URL = getAbsoluteUrl()
return assetObjJs
.replace('http://localhost:3000', FINAL_URL)
.replace('https://localhost:3000', FINAL_URL)
}
const toActualPath = (x: string) =>
x.includes('client') ? x.split('/').pop() : x
/**
* @desc retrieves the js/css for the named chunks that belong to our client bundle.
*
* @note the order of the chunk names is important. The same ordering will be
* used when rendering the scripts.
*
* This is useful to us for a couple of reasons:
* - It allows us to target the assets for a specific chunk, thereby only
* loading the assets we know we will need for a specific request.
* - The assets are hashed, and therefore they can't be "manually" added
* to the render logic. Having this method allows us to easily fetch
* the respective assets simply by using a chunk name. :)
*
* @example dist/dist/bundle/client/assets.json
* {"index":{"js":"http://0.0.0.0:5555/client/index.js"}}
*
* @example dist/dist/bundle/server/assets.json
* {"index":{"js":"http://0.0.0.0:5555/server/index.js"}}
*/
function getClientBundleEntryAssets() {
// Return the assets json cache if it exists.
// In development mode we always read the assets json file from disk to avoid
// any cases where an older version gets cached.
// @NOTE disabled @hack
// if (process.env.NODE_ENV === 'production' && resultCache) {
// return resultCache
// }
// const assetDir = process.env.BUILD_CONFIG_CLIENT_ASSETS_PATH
// const assetFileName = process.env.BUNDLE_ASSETS_FILE_NAME
const assetDir =
process.env.BUILD_CONFIG_CLIENT_ASSETS_PATH + '/dist/bundled/client/'
const assetFileName = 'manifest.json'
const assetFilePathRelative = `${assetDir}/${assetFileName}`
const assetsFilePath = resolve(assetFilePathRelative)
validateAssetsPath(assetsFilePath)
const assetsJSONCache = readJSON(assetsFilePath)
const outputPaths = Object.values(assetsJSONCache)
const outputNames = Object.keys(assetsJSONCache)
const index = outputPaths[0]
validateAssetEntryPointForIndex(index)
// @todo - this duplicates!!!
const assetObj = {
jsList: [...outputPaths.map(toActualPath)],
}
resultCache = assetObj
return resultCache
}
export { getClientBundleEntryAssets }
export default getClientBundleEntryAssets