如何将css或js文件的时间戳(或哈希)请求参数添加到NextJS 12构建文件.js中?ts=[时间戳]



在NextJs应用程序中构建后,我需要有机会获得下一种形式的js和css文件名:./path/file.js?ts=[时间戳]./path/file.css?ts=[时间戳]

我找到了下一个解决方案:

  1. 创建_document.tsx并使用inherit from document创建类
class StaticDocument extends Document {
render () {
return (
<Html>
<CustomHead />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
  1. 准备从Head扩展的CustomHead。我在Head类的库中找到了下一个函数,并覆盖了它们:getDynamicChunks、getScripts、getCssLinks:
declare type DocumentFiles = {
sharedFiles: readonly string[];
pageFiles: readonly string[];
allFiles: readonly string[];
};
const timestamp = new Date().getTime();
function getDynamicChunks(context: any, props: any, files: DocumentFiles) {
const { dynamicImports , assetPrefix , isDevelopment , devOnlyCacheBusterQueryString , disableOptimizedLoading , crossOrigin ,  } = context;
return dynamicImports.map((file: any)=>{
if (!file.endsWith('.js') || files.allFiles.includes(file)) return null;
console.log('file', file);
return React.createElement('script', {
async: !isDevelopment && disableOptimizedLoading,
defer: !disableOptimizedLoading,
key: file,
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + timestamp)}`,
nonce: props.nonce,
crossOrigin: props.crossOrigin || crossOrigin
});
});
}
function getScripts(context: any, props: any, files: DocumentFiles) {
let ref;
const { assetPrefix , buildManifest , isDevelopment , devOnlyCacheBusterQueryString , disableOptimizedLoading , crossOrigin ,  } = context;
const normalScripts = files.allFiles.filter((file)=>file.endsWith('.js'));
const lowPriorityScripts = (ref = buildManifest.lowPriorityFiles) == null ? void 0 : ref.filter((file: any)=>file.endsWith('.js'));
return [
...normalScripts,
...lowPriorityScripts
].map((file)=>{
return React.createElement('script', {
key: file,
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + timestamp)}`,
nonce: props.nonce,
async: !isDevelopment && disableOptimizedLoading,
defer: !disableOptimizedLoading,
crossOrigin: props.crossOrigin || crossOrigin
});
});
}
class CustomHead extends Head {
getDynamicChunks(files: DocumentFiles): (JSX.Element | null)[] {
return getDynamicChunks(this.context, this.props, files);
}
getScripts(files: DocumentFiles): JSX.Element[] {
return getScripts(this.context, this.props, files);
}
getCssLinks(files: DocumentFiles) {
const { assetPrefix , devOnlyCacheBusterQueryString , dynamicImports , crossOrigin , optimizeCss , optimizeFonts ,  } = this.context;
const cssFiles = files.allFiles.filter((f)=>f.endsWith('.css'));
const sharedFiles = new Set(files.sharedFiles);
// Unmanaged files are CSS files that will be handled directly by the
// webpack runtime (`mini-css-extract-plugin`).
let unmangedFiles: any = new Set([]);
let dynamicCssFiles = Array.from(new Set(dynamicImports.filter((file)=>file.endsWith('.css'))));
if (dynamicCssFiles.length) {
const existing = new Set(cssFiles);
dynamicCssFiles = dynamicCssFiles.filter((f)=>!(existing.has(f) || sharedFiles.has(f)));
unmangedFiles = new Set(dynamicCssFiles);
cssFiles.push(...dynamicCssFiles);
}
let cssLinkElements: any[] = [];
cssFiles.forEach((file)=>{
const isSharedFile = sharedFiles.has(file);
if (!optimizeCss) {
cssLinkElements.push(React.createElement('link', {
key: `${file}-preload`,
nonce: this.props.nonce,
rel: 'preload',
href: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + timestamp)}`,
as: 'style',
crossOrigin: this.props.crossOrigin || crossOrigin
}));
}
const isUnmanagedFile = unmangedFiles.has(file);
cssLinkElements.push(/*#__PURE__*/ React.createElement('link', {
key: file,
nonce: this.props.nonce,
rel: 'stylesheet',
href: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + timestamp)}`,
crossOrigin: this.props.crossOrigin || crossOrigin,
'data-n-g': isUnmanagedFile ? undefined : isSharedFile ? '' : undefined,
'data-n-p': isUnmanagedFile ? undefined : isSharedFile ? undefined : ''
}));
});
if (process.env.NODE_ENV !== 'development' && optimizeFonts) {
cssLinkElements = this.makeStylesheetInert(cssLinkElements);
}
return cssLinkElements.length === 0 ? null : cssLinkElements;
}
}

我找到了所有负责创建链接的行,并推送了带有时间戳的附加代码:('?ts='+时间戳(。

  1. 我调试了它,_documents.tsx在npm run dev上运行。它也在构建过程中运行。但_document.tsx的构建过程包括两个步骤:a(构建到.next文件夹,b(_document.js仅在构建过程中执行。它不会在npm启动时调用

最新更新