FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
patternfly-react/scripts/parse-dynamic-modules.mjs at main · patternfly/patternfly-react · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
patternfly
/
patternfly-react
Public
Notifications
You must be signed in to change notification settings
Fork
392
Star
862
Code
Issues
215
Pull requests
24
Discussions
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
patternfly-react
/
scripts
/
parse-dynamic-modules.mjs
Copy path
More file actions
More file actions
Latest commit
History
History
History
162 lines (134 loc) · 5.28 KB
Breadcrumbs
patternfly-react
/
scripts
/
parse-dynamic-modules.mjs
Copy path
File metadata and controls
162 lines (134 loc) · 5.28 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* eslint-disable no-console */
import
fs
from
'fs-extra'
;
import
{
createRequire
}
from
'node:module'
;
import
path
from
'node:path'
;
import
{
glob
}
from
'glob'
;
import
ts
from
'typescript'
;
const
require
=
createRequire
(
import
.
meta
.
url
)
;
/**
@type
{
ts.CompilerOptions
} */
const
tsConfigBase
=
require
(
path
.
resolve
(
import
.
meta
.
dirname
,
'../packages/tsconfig.base.json'
)
)
;
/**
@type
{
ts.CompilerOptions
} */
const
defaultCompilerOptions
=
{
target
:
tsConfigBase
.
target
,
module
:
tsConfigBase
.
module
,
moduleResolution
:
tsConfigBase
.
moduleResolution
,
esModuleInterop
:
tsConfigBase
.
esModuleInterop
,
allowJs
:
true
,
strict
:
false
,
skipLibCheck
:
true
,
noEmit
:
true
}
;
/**
* Map all exports of the given index module to their corresponding dynamic modules.
*
* Example: `@patternfly/react-core` package provides ESModules index at `dist/esm/index.js`
* which exports Alert component related code & types via `dist/esm/components/Alert/index.js`
* module.
*
* Given the example above, this function should return a mapping like so:
* ```js
* {
* Alert: 'dist/dynamic/components/Alert',
* AlertProps: 'dist/dynamic/components/Alert',
* AlertContext: 'dist/dynamic/components/Alert',
* // ...
* }
* ```
*
* The above mapping can be used when generating import statements like so:
* ```ts
* import { Alert } from '@patternfly/react-core/dist/dynamic/components/Alert';
* ```
*
* It may happen that the same export is provided by multiple dynamic modules;
* in such case, the resolution favors modules with most specific file paths, for example
* `dist/dynamic/components/Wizard/hooks` is favored over `dist/dynamic/components/Wizard`.
*
* Dynamic modules nested under `deprecated` or `next` directories are ignored.
*
* If the referenced index module does not exist, an empty object is returned.
*
*
@param
{
string
} basePath
*
@param
{
string
} indexModule
*
@param
{
string
} resolutionField
*
@param
{
ts.CompilerOptions
} tsCompilerOptions
*
@returns
{
Record<string, string>
}
*/
const
getDynamicModuleMap
=
(
basePath
,
indexModule
=
'dist/esm/index.js'
,
resolutionField
=
'module'
,
tsCompilerOptions
=
defaultCompilerOptions
)
=>
{
if
(
!
path
.
isAbsolute
(
basePath
)
)
{
throw
new
Error
(
'Package base path must be absolute'
)
;
}
const
indexModulePath
=
path
.
resolve
(
basePath
,
indexModule
)
;
if
(
!
fs
.
existsSync
(
indexModulePath
)
)
{
return
{
}
;
}
/**
@type
{
Record<string, string>
} */
const
dynamicModulePathToPkgDir
=
glob
.
sync
(
`
${
basePath
}
/dist/dynamic/**/package.json`
)
.
reduce
(
(
acc
,
pkgFile
)
=>
{
const
pkg
=
require
(
pkgFile
)
;
const
pkgModule
=
pkg
[
resolutionField
]
;
if
(
!
pkgModule
)
{
throw
new
Error
(
`Missing field
${
resolutionField
}
in
${
pkgFile
}
`
)
;
}
const
pkgResolvedPath
=
path
.
resolve
(
path
.
dirname
(
pkgFile
)
,
pkgModule
)
;
const
pkgRelativePath
=
path
.
dirname
(
path
.
relative
(
basePath
,
pkgFile
)
)
;
acc
[
pkgResolvedPath
]
=
pkgRelativePath
;
return
acc
;
}
,
{
}
)
;
const
dynamicModulePaths
=
Object
.
keys
(
dynamicModulePathToPkgDir
)
;
const
compilerHost
=
ts
.
createCompilerHost
(
tsCompilerOptions
)
;
const
program
=
ts
.
createProgram
(
[
indexModulePath
,
...
dynamicModulePaths
]
,
tsCompilerOptions
,
compilerHost
)
;
const
errorDiagnostics
=
ts
.
getPreEmitDiagnostics
(
program
)
.
filter
(
(
d
)
=>
d
.
category
===
ts
.
DiagnosticCategory
.
Error
)
;
if
(
errorDiagnostics
.
length
>
0
)
{
const
{
getCanonicalFileName
,
getCurrentDirectory
,
getNewLine
}
=
compilerHost
;
console
.
error
(
ts
.
formatDiagnostics
(
errorDiagnostics
,
{
getCanonicalFileName
,
getCurrentDirectory
,
getNewLine
}
)
)
;
throw
new
Error
(
`Detected TypeScript errors while parsing modules at
${
basePath
}
`
)
;
}
const
typeChecker
=
program
.
getTypeChecker
(
)
;
/**
@param
{
ts.SourceFile
} sourceFile */
const
getExportNames
=
(
sourceFile
)
=>
typeChecker
.
getExportsOfModule
(
typeChecker
.
getSymbolAtLocation
(
sourceFile
)
)
.
map
(
(
symbol
)
=>
symbol
.
getName
(
)
)
;
const
indexModuleExports
=
getExportNames
(
program
.
getSourceFile
(
indexModulePath
)
)
;
/**
@type
{
Record<string, string[]>
} */
const
dynamicModuleExports
=
dynamicModulePaths
.
reduce
(
(
acc
,
modulePath
)
=>
{
acc
[
modulePath
]
=
getExportNames
(
program
.
getSourceFile
(
modulePath
)
)
;
return
acc
;
}
,
{
}
)
;
/**
@param
{
string[]
} modulePaths */
const
getMostSpecificModulePath
=
(
modulePaths
)
=>
modulePaths
.
reduce
(
(
acc
,
p
)
=>
{
const
pathSpecificity
=
p
.
split
(
path
.
sep
)
.
length
;
const
currSpecificity
=
acc
.
split
(
path
.
sep
)
.
length
;
if
(
pathSpecificity
>
currSpecificity
)
{
return
p
;
}
if
(
pathSpecificity
===
currSpecificity
)
{
return
!
p
.
endsWith
(
'index.js'
)
&&
acc
.
endsWith
(
'index.js'
)
?
p
:
acc
;
}
return
acc
;
}
,
''
)
;
return
indexModuleExports
.
reduce
(
(
acc
,
exportName
)
=>
{
const
foundModulePaths
=
Object
.
keys
(
dynamicModuleExports
)
.
filter
(
(
modulePath
)
=>
dynamicModuleExports
[
modulePath
]
.
includes
(
exportName
)
)
;
const
filteredModulePaths
=
foundModulePaths
.
filter
(
(
modulePath
)
=>
{
const
dirNames
=
path
.
dirname
(
modulePath
)
.
split
(
path
.
sep
)
;
return
!
dirNames
.
includes
(
'deprecated'
)
&&
!
dirNames
.
includes
(
'next'
)
;
}
)
;
if
(
filteredModulePaths
.
length
>
0
)
{
acc
[
exportName
]
=
dynamicModulePathToPkgDir
[
getMostSpecificModulePath
(
filteredModulePaths
)
]
;
}
return
acc
;
}
,
{
}
)
;
}
;
export
default
getDynamicModuleMap
;
Back
|
FazBrowse Home
|
New Git URL