@@ -7,7 +7,9 @@ import { Headers, HeadersProps } from './headers';
7
7
8
8
const { ConcatSource, RawSource } = sources ;
9
9
10
- export type HeadersProvider = ( ) => HeadersProps | Promise < HeadersProps > ;
10
+ export type HeadersProvider = (
11
+ ...args : any [ ]
12
+ ) => HeadersProps | Promise < HeadersProps > ;
11
13
export type HeadersFile = string ;
12
14
13
15
export interface UserscriptOptions {
@@ -42,7 +44,7 @@ export class UserscriptPlugin {
42
44
) ;
43
45
44
46
compiler . hooks . compilation . tap ( PLUGIN , ( compilation ) => {
45
- compilation . hooks . processAssets . tap (
47
+ compilation . hooks . processAssets . tapPromise (
46
48
{
47
49
name : PLUGIN ,
48
50
stage : Compilation . PROCESS_ASSETS_STAGE_SUMMARIZE ,
@@ -89,42 +91,45 @@ export class UserscriptPlugin {
89
91
const { context, inputFileSystem } = this . compiler ;
90
92
const { root, headers : headersOptions } = this . options ;
91
93
92
- const defaultProps = await this . loadDefault (
94
+ const headersProps = await this . loadDefault (
93
95
root ?? context ,
94
96
inputFileSystem ,
95
97
) ;
96
- const headersProps = await this . resolveHeadersOptions ( headersOptions ) ;
97
- const headers = this . headersFactory ( {
98
- ...defaultProps ,
99
- ...headersProps ,
100
- } ) ;
101
98
102
- this . compilationData . set ( params , { headers } ) ;
103
- }
99
+ let headersProviders : HeadersProvider | undefined ;
104
100
105
- private async resolveHeadersOptions (
106
- headersOptions : UserscriptOptions [ 'headers' ] ,
107
- ) : Promise < HeadersProps > {
108
- const { inputFileSystem } = this . compiler ;
109
101
if ( typeof headersOptions === 'string' ) {
110
- return await readJSON < HeadersProps > (
111
- headersOptions ,
112
- inputFileSystem as FsReadFile ,
102
+ Object . assign (
103
+ headersProps ,
104
+ await readJSON < HeadersProps > (
105
+ headersOptions ,
106
+ inputFileSystem as FsReadFile ,
107
+ ) ,
113
108
) ;
114
109
} else if ( typeof headersOptions === 'function' ) {
115
- return await headersOptions ( ) ;
110
+ headersProviders = headersOptions ;
116
111
} else {
117
- return headersOptions ?? { } ;
112
+ Object . assign ( headersProps , headersOptions ) ;
118
113
}
114
+
115
+ this . compilationData . set ( params , { headersProps, headersProviders } ) ;
119
116
}
120
117
121
- private emit ( compilation : Compilation ) : void {
118
+ private async emit ( compilation : Compilation ) : Promise < void > {
122
119
const data = this . compilationData . get ( compilation . params ) ;
123
120
124
121
if ( ! data ) return ;
125
122
126
- for ( const fileInfo of this . analyzeFileInfo ( compilation ) ) {
127
- this . emitAssets ( compilation , fileInfo , data ) ;
123
+ const fileInfoList = this . analyzeFileInfo ( compilation ) ;
124
+
125
+ await Promise . all (
126
+ fileInfoList . map ( ( fileInfo ) =>
127
+ this . emitAssets ( compilation , fileInfo , data ) ,
128
+ ) ,
129
+ ) ;
130
+
131
+ for ( const { file } of fileInfoList ) {
132
+ compilation .deleteAsset ( file ) ;
128
133
}
129
134
}
130
135
@@ -133,13 +138,13 @@ export class UserscriptPlugin {
133
138
134
139
for ( const entrypoint of compilation . entrypoints . values ( ) ) {
135
140
const chunk = entrypoint . getEntrypointChunk ( ) ;
136
- for ( const sourceFile of chunk . files ) {
137
- let q = sourceFile . indexOf ( '?' ) ;
141
+ for ( const file of chunk . files ) {
142
+ let q = file . indexOf ( '?' ) ;
138
143
if ( q < 0 ) {
139
- q = sourceFile . length ;
144
+ q = file . length ;
140
145
}
141
- const filename = sourceFile . slice ( 0 , q ) ;
142
- const query = sourceFile . slice ( q ) ;
146
+ const filename = file . slice ( 0 , q ) ;
147
+ const query = file . slice ( q ) ;
143
148
const extname = path . extname ( filename ) ;
144
149
145
150
if ( extname !== '.js' ) {
@@ -158,44 +163,65 @@ export class UserscriptPlugin {
158
163
159
164
fileInfo . push ( {
160
165
chunk,
161
- sourceFile ,
166
+ file ,
162
167
userjsFile,
163
168
metajsFile,
169
+ filename,
170
+ basename,
171
+ query,
172
+ extname,
173
+ dirname,
164
174
} ) ;
165
175
}
166
176
}
167
177
168
178
return fileInfo ;
169
179
}
170
180
171
- private emitAssets (
181
+ private async emitAssets (
172
182
compilation : Compilation ,
173
- { sourceFile , chunk , metajsFile , userjsFile } : FileInfo ,
183
+ fileInfo : FileInfo ,
174
184
data : CompilationData ,
175
- ) : void {
176
- const headersStr = data . headers . render ( ) ;
185
+ ) : Promise < void > {
186
+ const { file , chunk , metajsFile , userjsFile } = fileInfo ;
177
187
178
- compilation . updateAsset (
179
- sourceFile ,
180
- ( source ) => {
181
- return new ConcatSource ( headersStr , '\n' , source ) ;
182
- } ,
188
+ const headers = this . headersFactory ( {
189
+ ...data . headersProps ,
190
+ ...( await data . headersProviders ?.( fileInfo ) ) ,
191
+ } ) ;
192
+ const headersStr = headers . render ( ) ;
193
+
194
+ const sourceAsset = compilation . getAsset ( file ) ;
195
+ if ( ! sourceAsset ) {
196
+ return ;
197
+ }
198
+
199
+ compilation . emitAsset (
200
+ userjsFile ,
201
+ new ConcatSource ( headersStr , '\n' , sourceAsset . source ) ,
183
202
{
184
203
related : { metajs : metajsFile } ,
204
+ minimized : true ,
185
205
} ,
186
206
) ;
187
- compilation . renameAsset ( sourceFile , userjsFile ) ;
188
207
compilation . emitAsset ( metajsFile , new RawSource ( headersStr ) , {
189
- // prevent metajs from optimization
208
+ related : { userjs : userjsFile } ,
190
209
minimized : true ,
191
210
} ) ;
211
+
212
+ chunk . files . add ( userjsFile ) ;
192
213
chunk . auxiliaryFiles . add ( metajsFile ) ;
193
214
}
194
215
}
195
216
196
217
export interface FileInfo {
197
218
chunk : Chunk ;
198
- sourceFile : string ;
219
+ file : string ;
220
+ filename : string ;
221
+ basename : string ;
222
+ query : string ;
223
+ extname : string ;
224
+ dirname : string ;
199
225
userjsFile : string ;
200
226
metajsFile : string ;
201
227
}
@@ -210,5 +236,6 @@ interface PackageJson {
210
236
}
211
237
212
238
interface CompilationData {
213
- headers : Headers ;
239
+ headersProps : HeadersProps ;
240
+ headersProviders ?: HeadersProvider ;
214
241
}
0 commit comments