@@ -14,6 +14,7 @@ import { logger, LOGGER_LEVELS } from "./logger";
1414import { hashFile } from "./pages/hash" ;
1515import { isJwtExpired } from "./pages/upload" ;
1616import { APIError } from "./parse" ;
17+ import { createPatternMatcher } from "./utils/filesystem" ;
1718import type { Config } from "./config" ;
1819import type { ExperimentalAssets } from "./config/environment" ;
1920
@@ -220,10 +221,20 @@ export const buildAssetsManifest = async (dir: string) => {
220221 const files = await readdir ( dir , { recursive : true } ) ;
221222 const manifest : AssetManifest = { } ;
222223 let counter = 0 ;
224+
225+ const ignoreFn = await createAssetIgnoreFunction ( dir ) ;
226+
223227 await Promise . all (
224228 files . map ( async ( file ) => {
225229 const filepath = path . join ( dir , file ) ;
226230 const relativeFilepath = path . relative ( dir , filepath ) ;
231+
232+ if ( ignoreFn ?.( relativeFilepath ) ) {
233+ logger . debug ( "Ignoring asset:" , relativeFilepath ) ;
234+ // This file should not be included in the manifest.
235+ return ;
236+ }
237+
227238 const filestat = await stat ( filepath ) ;
228239
229240 if ( filestat . isSymbolicLink ( ) || filestat . isDirectory ( ) ) {
@@ -361,3 +372,28 @@ const decodeFilepath = (filePath: string) => {
361372 . map ( ( segment ) => decodeURIComponent ( segment ) )
362373 . join ( path . sep ) ;
363374} ;
375+
376+ /**
377+ * Create a function for filtering out ignored assets.
378+ *
379+ * The generated function takes an asset path, relative to the asset directory,
380+ * and returns true if the asset should not be ignored.
381+ */
382+ async function createAssetIgnoreFunction ( dir : string ) {
383+ const CF_ASSETS_IGNORE_FILENAME = ".assetsignore" ;
384+
385+ const cfAssetIgnorePath = path . resolve ( dir , CF_ASSETS_IGNORE_FILENAME ) ;
386+
387+ if ( ! existsSync ( cfAssetIgnorePath ) ) {
388+ return null ;
389+ }
390+
391+ const ignorePatterns = (
392+ await readFile ( cfAssetIgnorePath , { encoding : "utf8" } )
393+ ) . split ( "\n" ) ;
394+
395+ // Always ignore the `.assetsignore` file.
396+ ignorePatterns . push ( CF_ASSETS_IGNORE_FILENAME ) ;
397+
398+ return createPatternMatcher ( ignorePatterns , true ) ;
399+ }
0 commit comments