在 NextJs 應用程序中構建後,我需要有機會獲得下一種形式的 js 和 css 文件名:
./path/file.js?ts=[時間戳]
./path/file.css?ts=[時間戳]
我找到了下一個解決方案:
- 創建 _document.tsx 並創建繼承自 Document 的類。
class StaticDocument 擴展 Document {
使成為 () {
返回 (
)
}
}
- 準備從 Head 擴展的 CustomHead。我在 Head 類的庫中找到了下一個函數並覆蓋了它們:getDynamicChunks、getScripts、getCssLinks:
聲明類型 DocumentFiles = {
sharedFiles: 只讀字符串[];
pageFiles: 只讀字符串[];
allFiles: 只讀字符串[];
};
const timestamp = new Date().getTime();
函數getDynamicChunks(上下文:任意,道具:任意,文件:DocumentFiles){
const { dynamicImports , assetsPrefix , isDevelopment , devOnlyCacheBusterQueryString , disableOptimizedLoading , crossOrigin , } = context;
return dynamicImports.map((file: any)=>{
if (!file.endsWith('.js') || files.allFiles.includes(file)) return null;
console.log('文件', 文件);
返回 React.createElement('腳本', {
異步:!isDevelopment && disableOptimizedLoading,
defer: !disableOptimizedLoading,
鍵:文件,
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + 時間戳)}`,
隨機數:props.nonce,
crossOrigin: props.crossOrigin ||跨域
});
});
}
函數getScripts(上下文:任意,道具:任意,文件:DocumentFiles){
讓參考;
const { assetsPrefix , 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'));
返回 [
...正常腳本,
...低優先級腳本
].map((文件)=>{
返回 React.createElement('腳本', {
鍵:文件,
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + 時間戳)}`,
隨機數:props.nonce,
異步:!isDevelopment && disableOptimizedLoading,
defer: !disableOptimizedLoading,
crossOrigin: props.crossOrigin ||跨域
});
});
}
類 CustomHead 擴展 Head {
getDynamicChunks(files: DocumentFiles): (JSX.Element | null)[] {
返回 getDynamicChunks(this.context, this.props, files);
}
getScripts(文件:DocumentFiles):JSX.Element[] {
返回 getScripts(this.context, this.props, files);
}
getCssLinks(文件:文檔文件){
常量 {assetPrefix , devOnlyCacheBusterQueryString , dynamicImports , crossOrigin , optimizeCss , optimizeFonts , } = this.context;
const cssFiles = files.allFiles.filter((f)=>f.endsWith('.css'));
const sharedFiles = new Set(files.sharedFiles);
// 非託管文件是 CSS 文件,將由
// webpack 運行時 (`mini-css-extract-plugin`)。
讓 unmangedFiles: any = new Set([]);
讓 dynamicCssFiles = Array.from(new Set(dynamicImports.filter((file)=>file.endsWith('.css'))));
if (dynamicCssFiles.length) {
常量現有 = 新設置(cssFiles);
dynamicCssFiles = dynamicCssFiles.filter((f)=>!(existing.has(f) || sharedFiles.has(f)));
unmangedFiles = new Set(dynamicCssFiles);
cssFiles.push(...dynamicCssFiles);
}
讓 cssLinkElements: any[] = [];
cssFiles.forEach((文件)=>{
const isSharedFile = sharedFiles.has(file);
if (!optimizeCss) {
cssLinkElements.push(React.createElement('link', {
鍵:`${file}-preload`,
隨機數:this.props.nonce,
rel: '預加載',
href: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + 時間戳)}`,
如:'風格',
crossOrigin: this.props.crossOrigin ||跨域
}));
}
const isUnmanagedFile = unmangedFiles.has(file);
cssLinkElements.push(/*#__PURE__*/ React.createElement('link', {
鍵:文件,
隨機數:this.props.nonce,
rel: '樣式表',
href: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + 時間戳)}`,
crossOrigin: this.props.crossOrigin ||跨域,
'data-n-g': isUnmanagedFile ?未定義:isSharedFile? '' : 不明確的,
'data-n-p': isUnmanagedFile ?未定義:isSharedFile?不明確的 : ''
}));
});
if (process.env.NODE_ENV !== 'development' && optimizeFonts) {
cssLinkElements = this.makeStylesheetInert(cssLinkElements);
}
返回 cssLinkElements.length === 0 ?空:cssLinkElements;
}
}
我找到了負責創建鏈接的所有行,並推送了帶有時間戳的附加代碼:(‘?ts=’ + timestamp)。
- 我對其進行了調試,_documents.tsx 在 npm run dev 上運行。它也在構建過程中運行。但是 _document.tsx 的構建過程包含兩個步驟:a) 構建到 .next 文件夾和 b) _document.js 僅在構建過程中執行。它不會在 npm start 上調用。