@@ -143,6 +143,18 @@ export default class DocgenPlugin implements webpack.WebpackPluginInstance {
143143 }
144144
145145 apply ( compiler : webpack . Compiler ) : void {
146+ // Property compiler.version is set only starting from webpack 5
147+ const webpackVersion = compiler . webpack ?. version || "" ;
148+ const isWebpack5 = parseInt ( webpackVersion . split ( "." ) [ 0 ] , 10 ) >= 5 ;
149+
150+ if ( isWebpack5 ) {
151+ this . applyWebpack5 ( compiler ) ;
152+ } else {
153+ this . applyWebpack4 ( compiler ) ;
154+ }
155+ }
156+
157+ applyWebpack5 ( compiler : webpack . Compiler ) : void {
146158 const pluginName = "DocGenPlugin" ;
147159 const {
148160 docgenOptions,
@@ -156,29 +168,24 @@ export default class DocgenPlugin implements webpack.WebpackPluginInstance {
156168 const { exclude = [ ] , include = [ "**/**.tsx" ] } = this . options ;
157169 const isExcluded = matchGlob ( exclude ) ;
158170 const isIncluded = matchGlob ( include ) ;
159- // Property compiler.version is set only starting from webpack 5
160- const webpackVersion = compiler . webpack ?. version || "" ;
161- const isWebpack5 = parseInt ( webpackVersion . split ( "." ) [ 0 ] , 10 ) >= 5 ;
162171
163172 compiler . hooks . compilation . tap (
164173 pluginName ,
165174 ( compilation : webpack . Compilation ) => {
166- if ( isWebpack5 ) {
167- // Since this file is needed only for webpack 5, load it only then
168- // to simplify the implementation of the file.
169- //
170- // eslint-disable-next-line
171- const { DocGenDependency } = require ( "./dependency" ) ;
175+ // Since this file is needed only for webpack 5, load it only then
176+ // to simplify the implementation of the file.
177+ //
178+ // eslint-disable-next-line
179+ const { DocGenDependency } = require ( "./dependency" ) ;
172180
173- compilation . dependencyTemplates . set (
174- // eslint-disable-next-line
175- // @ts -ignore: Webpack 4 type
176- DocGenDependency ,
177- // eslint-disable-next-line
178- // @ts -ignore: Webpack 4 type
179- new DocGenDependency . Template ( )
180- ) ;
181- }
181+ compilation . dependencyTemplates . set (
182+ // eslint-disable-next-line
183+ // @ts -ignore: Webpack 4 type
184+ DocGenDependency ,
185+ // eslint-disable-next-line
186+ // @ts -ignore: Webpack 4 type
187+ new DocGenDependency . Template ( )
188+ ) ;
182189
183190 compilation . hooks . seal . tap ( pluginName , ( ) => {
184191 const modulesToProcess : [ string , webpack . Module ] [ ] = [ ] ;
@@ -217,38 +224,122 @@ export default class DocgenPlugin implements webpack.WebpackPluginInstance {
217224 // 3. Process and parse each module and add the type information
218225 // as a dependency
219226 modulesToProcess . forEach ( ( [ name , module ] ) => {
220- if ( isWebpack5 ) {
221- // Since this file is needed only for webpack 5, load it only then
222- // to simplify the implementation of the file.
223- //
227+ // Since this file is needed only for webpack 5, load it only then
228+ // to simplify the implementation of the file.
229+ //
230+ // eslint-disable-next-line
231+ const { DocGenDependency } = require ( "./dependency" ) ;
232+
233+ module . addDependency (
224234 // eslint-disable-next-line
225- const { DocGenDependency } = require ( "./dependency" ) ;
226-
227- module . addDependency (
228- // eslint-disable-next-line
229- // @ts -ignore: Webpack 4 type
230- new DocGenDependency (
231- generateDocgenCodeBlock ( {
232- filename : name ,
233- source : name ,
234- componentDocs : docGenParser . parseWithProgramProvider (
235- name ,
236- ( ) => tsProgram
237- ) ,
238- ...generateOptions ,
239- } ) . substring ( name . length )
240- )
241- ) ;
242- } else {
243- // Assume webpack 4 or earlier
244- processModule ( docGenParser , module , tsProgram , generateOptions ) ;
245- }
235+ // @ts -ignore: Webpack 4 type
236+ new DocGenDependency (
237+ generateDocgenCodeBlock ( {
238+ filename : name ,
239+ source : name ,
240+ componentDocs : docGenParser . parseWithProgramProvider (
241+ name ,
242+ ( ) => tsProgram
243+ ) ,
244+ ...generateOptions ,
245+ } ) . substring ( name . length )
246+ )
247+ ) ;
246248 } ) ;
247249 } ) ;
248250 }
249251 ) ;
250252 }
251253
254+ applyWebpack4 ( compiler : webpack . Compiler ) : void {
255+ const { docgenOptions, compilerOptions } = this . getOptions ( ) ;
256+ const parser = docGen . withCompilerOptions ( compilerOptions , docgenOptions ) ;
257+ const { exclude = [ ] , include = [ "**/**.tsx" ] } = this . options ;
258+ const isExcluded = matchGlob ( exclude ) ;
259+ const isIncluded = matchGlob ( include ) ;
260+
261+ compiler . hooks . make . tap ( this . name , ( compilation ) => {
262+ compilation . hooks . seal . tap ( this . name , ( ) => {
263+ const modulesToProcess : webpack . Module [ ] = [ ] ;
264+
265+ compilation . modules . forEach ( ( module : webpack . Module ) => {
266+ // eslint-disable-next-line
267+ // @ts -ignore: Webpack 4 type
268+ if ( ! module . built ) {
269+ // eslint-disable-next-line
270+ // @ts -ignore: Webpack 4 type
271+ debugExclude ( `Ignoring un-built module: ${ module . userRequest } ` ) ;
272+ return ;
273+ }
274+
275+ // eslint-disable-next-line
276+ // @ts -ignore: Webpack 4 type
277+ if ( module . external ) {
278+ // eslint-disable-next-line
279+ // @ts -ignore: Webpack 4 type
280+ debugExclude ( `Ignoring external module: ${ module . userRequest } ` ) ;
281+ return ;
282+ }
283+
284+ // eslint-disable-next-line
285+ // @ts -ignore: Webpack 4 type
286+ if ( ! module . rawRequest ) {
287+ debugExclude (
288+ // eslint-disable-next-line
289+ // @ts -ignore: Webpack 4 type
290+ `Ignoring module without "rawRequest": ${ module . userRequest } `
291+ ) ;
292+ return ;
293+ }
294+
295+ // eslint-disable-next-line
296+ // @ts -ignore: Webpack 4 type
297+ if ( isExcluded ( module . userRequest ) ) {
298+ debugExclude (
299+ // eslint-disable-next-line
300+ // @ts -ignore: Webpack 4 type
301+ `Module not matched in "exclude": ${ module . userRequest } `
302+ ) ;
303+ return ;
304+ }
305+
306+ // eslint-disable-next-line
307+ // @ts -ignore: Webpack 4 type
308+ if ( ! isIncluded ( module . userRequest ) ) {
309+ debugExclude (
310+ // eslint-disable-next-line
311+ // @ts -ignore: Webpack 4 type
312+ `Module not matched in "include": ${ module . userRequest } `
313+ ) ;
314+ return ;
315+ }
316+
317+ // eslint-disable-next-line
318+ // @ts -ignore: Webpack 4 type
319+ debugInclude ( module . userRequest ) ;
320+ modulesToProcess . push ( module ) ;
321+ } ) ;
322+
323+ const tsProgram = ts . createProgram (
324+ // eslint-disable-next-line
325+ // @ts -ignore: Webpack 4 type
326+ modulesToProcess . map ( ( v ) => v . userRequest ) ,
327+ compilerOptions
328+ ) ;
329+
330+ modulesToProcess . forEach ( ( m ) =>
331+ processModule ( parser , m , tsProgram , {
332+ docgenCollectionName : "STORYBOOK_REACT_CLASSES" ,
333+ setDisplayName : true ,
334+ typePropName : "type" ,
335+ } )
336+ ) ;
337+
338+ cache . save ( ) ;
339+ } ) ;
340+ } ) ;
341+ }
342+
252343 getOptions ( ) : {
253344 docgenOptions : docGen . ParserOptions ;
254345 generateOptions : {
0 commit comments