NextJs アプリでビルドした後、次の形式の js および css ファイル名を使用する機会が必要です。
./path/file.js?ts=[タイムスタンプ]
./path/file.css?ts=[タイムスタンプ]
次の解決策を見つけました:
class StaticDocument extends Document {
与える () {
戻る (
)
}
}
- Head から伸びる CustomHead を用意します。 Head クラスのライブラリで次の関数を見つけて上書きしました: getDynamicChunks、getScripts、getCssLinks:
型を宣言 DocumentFiles = {
sharedFiles: 読み取り専用文字列[];
pageFiles: 読み取り専用文字列[];
allFiles: 読み取り専用文字列[];
};
const タイムスタンプ = new Date().getTime();
function getDynamicChunks(context: any, props: any, files: DocumentFiles) {
const { dynamicImports 、 assetPrefix 、 isDevelopment 、 devOnlyCacheBusterQueryString 、 disableOptimizedLoading 、 crossOrigin 、 } = コンテキスト;
return dynamicImports.map((ファイル:任意)=>{
if (!file.endsWith('.js') || files.allFiles.includes(file)) は null を返します。
console.log('ファイル', ファイル);
return React.createElement('script', {
非同期: !isDevelopment && disableOptimizedLoading,
延期: !disableOptimizedLoading、
キー: ファイル、
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + タイムスタンプ)}`,
ノンス: props.nonce,
crossOrigin: props.crossOrigin || クロスオリジンcrossOrigin
});
});
}
function getScripts(context: any, props: any, files: DocumentFiles) {
参照してみましょう。
const { assetPrefix 、 buildManifest 、 isDevelopment 、 devOnlyCacheBusterQueryString 、 disableOptimizedLoading 、 crossOrigin 、 } = コンテキスト;
const normalScripts = files.allFiles.filter((file)=>file.endsWith('.js'));
const lowPriorityScripts = (ref = buildManifest.lowPriorityFiles) == null ? void 0 : ref.filter((ファイル: 任意)=>file.endsWith('.js'));
戻る [
...通常のスクリプト、
...lowPriorityScripts
].map((ファイル)=>{
return React.createElement('script', {
キー: ファイル、
src: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + タイムスタンプ)}`,
ノンス: props.nonce,
非同期: !isDevelopment && disableOptimizedLoading,
延期: !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(ファイル: 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);
// 管理されていないファイルは CSS ファイルであり、
// webpack ランタイム (`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((ファイル)=>{
const isSharedFile = sharedFiles.has(ファイル);
if (!optimizeCss) {
cssLinkElements.push(React.createElement('リンク', {
キー: `${file}-preload`,
ノンス: this.props.nonce,
rel: 'プリロード',
href: `${assetPrefix}/_next/${encodeURI(file)}${devOnlyCacheBusterQueryString || ('?ts=' + タイムスタンプ)}`,
as: 'スタイル',
crossOrigin: this.props.crossOrigin || crossOrigin
}));
}
const isUnmanagedFile = unmangedFiles.has(ファイル);
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 !== '開発' && optimizeFonts) {
cssLinkElements = this.makeStylesheetInert(cssLinkElements);
}
cssLinkElements.length === 0 を返しますか? null : cssLinkElements;
}
}
リンクを作成するすべての行を見つけ、タイムスタンプ ('?ts=' + タイムスタンプ) を含む追加のコードをプッシュしました。
- デバッグしたところ、npm run dev で _documents.tsx が実行されました。また、ビルドプロセスでも実行されます。ただし、_document.tsx のビルド プロセスは、a) .next フォルダーへのビルドと、b) ビルド プロセスでのみ _document.js が実行される 2 つのステップで構成されます。 npm start では呼び出されません。