1
- import { declare } from ' @babel/helper-plugin-utils'
1
+ import { declare } from " @babel/helper-plugin-utils" ;
2
2
import syntaxDynamicImport from '@babel/plugin-syntax-dynamic-import'
3
3
import chunkNameProperty from './properties/chunkName'
4
4
import isReadyProperty from './properties/isReady'
@@ -20,194 +20,164 @@ const properties = [
20
20
21
21
const LOADABLE_COMMENT = '#__LOADABLE__'
22
22
23
- /**
24
- * The options for the plugin
25
- * @typedef {Object } LoadabelBabelPluginOptions
26
- * @property {string } [defaultImportSpecifier] - The default import specifier, defaults to `loadable`
27
- * @property {boolean } [moduleFederation] - Whether to use module federation
28
- */
29
-
30
- /**
31
- * The options for the plugin
32
- * @typedef {Object } PropertyFactoryOptions
33
- * @property {import('@babel/core').NodePath<import('@babel/types').CallExpression> } callPath
34
- * @property {import('@babel/core').NodePath<import('@babel/types').FunctionExpression | import('@babel/types').ArrowFunctionExpression | import('@babel/types').ObjectMethod> } funcPath
35
- * @property {import('@babel/core').NodePath<import('@babel/types').ObjectExpression> } path
36
- */
37
-
38
- /**
39
- * The factory for a property
40
- * @typedef {Function } PropertyFactory
41
- * @param {PropertyFactoryOptions } options
42
- * @returns {import('@babel/types').ObjectMethod }
43
- */
44
-
45
- const loadablePlugin = declare (
46
- /**
47
- *
48
- * @param {import('@babel/helper-plugin-utils').BabelAPI } api
49
- * @param {LoadabelBabelPluginOptions } babelOptions
50
- * @returns {import('@babel/core').PluginObj }
51
- */
52
- ( api , babelOptions ) => {
53
- const { defaultImportSpecifier = 'loadable' } = babelOptions
54
-
55
- const { types : t } = api
56
-
57
- function collectImportCallPaths ( startPath ) {
58
- const imports = [ ]
59
- startPath . traverse ( {
60
- Import ( importPath ) {
61
- imports . push ( importPath . parentPath )
62
- } ,
63
- } )
64
- return imports
65
- }
23
+ const loadablePlugin = declare ( ( api , babelOptions ) => {
24
+ const { defaultImportSpecifier = 'loadable' } = babelOptions
66
25
67
- const propertyFactories = properties . map ( init => init ( api , babelOptions ) )
26
+ const { types : t } = api
68
27
69
- function isValidIdentifier (
70
- path ,
71
- loadableImportSpecifier ,
72
- lazyImportSpecifier ,
28
+ function collectImportCallPaths ( startPath ) {
29
+ const imports = [ ]
30
+ startPath . traverse ( {
31
+ Import ( importPath ) {
32
+ imports . push ( importPath . parentPath )
33
+ } ,
34
+ } )
35
+ return imports
36
+ }
37
+
38
+ const propertyFactories = properties . map ( init => init ( api , babelOptions ) )
39
+
40
+ function isValidIdentifier (
41
+ path ,
42
+ loadableImportSpecifier ,
43
+ lazyImportSpecifier ,
44
+ ) {
45
+ // `loadable()`
46
+ if (
47
+ loadableImportSpecifier &&
48
+ path . get ( 'callee' ) . isIdentifier ( { name : loadableImportSpecifier } )
73
49
) {
74
- // `loadable()`
75
- if (
76
- loadableImportSpecifier &&
77
- path . get ( 'callee' ) . isIdentifier ( { name : loadableImportSpecifier } )
78
- ) {
79
- return true
80
- }
81
-
82
- // `lazy()`
83
- if (
84
- lazyImportSpecifier &&
85
- path . get ( 'callee' ) . isIdentifier ( { name : lazyImportSpecifier } )
86
- ) {
87
- return true
88
- }
89
-
90
- // `loadable.lib()`
91
- return (
92
- loadableImportSpecifier &&
93
- path . get ( 'callee' ) . isMemberExpression ( ) &&
94
- path
95
- . get ( 'callee.object' )
96
- . isIdentifier ( { name : loadableImportSpecifier } ) &&
97
- path . get ( 'callee.property' ) . isIdentifier ( { name : 'lib' } )
98
- )
50
+ return true
99
51
}
100
52
101
- function hasLoadableComment ( path ) {
102
- const comments = path . get ( 'leadingComments' )
103
- const comment = comments . find (
104
- ( { node } ) =>
105
- node && node . value && String ( node . value ) . includes ( LOADABLE_COMMENT ) ,
106
- )
107
- if ( ! comment ) return false
108
- comment . remove ( )
53
+ // `lazy()`
54
+ if (
55
+ lazyImportSpecifier &&
56
+ path . get ( 'callee' ) . isIdentifier ( { name : lazyImportSpecifier } )
57
+ ) {
109
58
return true
110
59
}
111
60
112
- function getFuncPath ( path ) {
113
- const funcPath = path . isCallExpression ( ) ? path . get ( 'arguments.0' ) : path
114
- if (
115
- ! funcPath . isFunctionExpression ( ) &&
116
- ! funcPath . isArrowFunctionExpression ( ) &&
117
- ! funcPath . isObjectMethod ( )
118
- ) {
119
- return null
120
- }
121
- return funcPath
61
+ // `loadable.lib()`
62
+ return (
63
+ loadableImportSpecifier &&
64
+ path . get ( 'callee' ) . isMemberExpression ( ) &&
65
+ path
66
+ . get ( 'callee.object' )
67
+ . isIdentifier ( { name : loadableImportSpecifier } ) &&
68
+ path . get ( 'callee.property' ) . isIdentifier ( { name : 'lib' } )
69
+ )
70
+ }
71
+
72
+ function hasLoadableComment ( path ) {
73
+ const comments = path . get ( 'leadingComments' )
74
+ const comment = comments . find (
75
+ ( { node } ) =>
76
+ node && node . value && String ( node . value ) . includes ( LOADABLE_COMMENT ) ,
77
+ )
78
+ if ( ! comment ) return false
79
+ comment . remove ( )
80
+ return true
81
+ }
82
+
83
+ function getFuncPath ( path ) {
84
+ const funcPath = path . isCallExpression ( ) ? path . get ( 'arguments.0' ) : path
85
+ if (
86
+ ! funcPath . isFunctionExpression ( ) &&
87
+ ! funcPath . isArrowFunctionExpression ( ) &&
88
+ ! funcPath . isObjectMethod ( )
89
+ ) {
90
+ return null
122
91
}
92
+ return funcPath
93
+ }
123
94
124
- function transformImport ( path ) {
125
- const callPaths = collectImportCallPaths ( path )
95
+ function transformImport ( path ) {
96
+ const callPaths = collectImportCallPaths ( path )
126
97
127
- // Ignore loadable function that does not have any "import" call
128
- if ( callPaths . length === 0 ) return
98
+ // Ignore loadable function that does not have any "import" call
99
+ if ( callPaths . length === 0 ) return
129
100
130
- // Multiple imports call is not supported
131
- if ( callPaths . length > 1 ) {
132
- throw new Error (
133
- 'loadable: multiple import calls inside `loadable()` function are not supported.' ,
134
- )
135
- }
101
+ // Multiple imports call is not supported
102
+ if ( callPaths . length > 1 ) {
103
+ throw new Error (
104
+ 'loadable: multiple import calls inside `loadable()` function are not supported.' ,
105
+ )
106
+ }
136
107
137
- const [ callPath ] = callPaths
108
+ const [ callPath ] = callPaths
138
109
139
- const funcPath = getFuncPath ( path )
140
- if ( ! funcPath ) return
110
+ const funcPath = getFuncPath ( path )
111
+ if ( ! funcPath ) return
141
112
142
- funcPath . node . params = funcPath . node . params || [ ]
113
+ funcPath . node . params = funcPath . node . params || [ ]
143
114
144
- const object = t . objectExpression (
145
- propertyFactories . map ( getProperty =>
146
- getProperty ( { path, callPath, funcPath } ) ,
147
- ) ,
148
- )
115
+ const object = t . objectExpression (
116
+ propertyFactories . map ( getProperty =>
117
+ getProperty ( { path, callPath, funcPath } ) ,
118
+ ) ,
119
+ )
149
120
150
- if ( funcPath . isObjectMethod ( ) ) {
151
- funcPath . replaceWith (
152
- t . objectProperty ( funcPath . node . key , object , funcPath . node . computed ) ,
153
- )
154
- } else {
155
- funcPath . replaceWith ( object )
156
- }
121
+ if ( funcPath . isObjectMethod ( ) ) {
122
+ funcPath . replaceWith (
123
+ t . objectProperty ( funcPath . node . key , object , funcPath . node . computed ) ,
124
+ )
125
+ } else {
126
+ funcPath . replaceWith ( object )
157
127
}
158
-
159
- return {
160
- inherits : syntaxDynamicImport ,
161
- visitor : {
162
- Program : {
163
- enter ( programPath ) {
164
- let loadableImportSpecifier = defaultImportSpecifier
165
- let lazyImportSpecifier = false
166
-
167
- programPath . traverse ( {
168
- ImportDefaultSpecifier ( path ) {
169
- if ( ! loadableImportSpecifier ) {
170
- const { parent } = path
171
- const { local } = path . node
172
- loadableImportSpecifier =
173
- parent . source . value == '@loadable/component' &&
174
- local &&
175
- local . name
176
- }
177
- } ,
178
- ImportSpecifier ( path ) {
179
- if ( ! lazyImportSpecifier ) {
180
- const { parent } = path
181
- const { imported , local } = path . node
182
- lazyImportSpecifier =
183
- parent . source . value == '@loadable/component' &&
184
- imported &&
185
- imported . name == 'lazy' &&
186
- local &&
187
- local . name
188
- }
189
- } ,
190
- CallExpression ( path ) {
191
- if (
192
- ! isValidIdentifier (
193
- path ,
194
- loadableImportSpecifier ,
195
- lazyImportSpecifier ,
196
- )
128
+ }
129
+
130
+ return {
131
+ inherits : syntaxDynamicImport ,
132
+ visitor : {
133
+ Program : {
134
+ enter ( programPath ) {
135
+ let loadableImportSpecifier = defaultImportSpecifier
136
+ let lazyImportSpecifier = false
137
+
138
+ programPath . traverse ( {
139
+ ImportDefaultSpecifier ( path ) {
140
+ if ( ! loadableImportSpecifier ) {
141
+ const { parent } = path
142
+ const { local } = path . node
143
+ loadableImportSpecifier =
144
+ parent . source . value == '@loadable/component' &&
145
+ local &&
146
+ local . name
147
+ }
148
+ } ,
149
+ ImportSpecifier ( path ) {
150
+ if ( ! lazyImportSpecifier ) {
151
+ const { parent } = path
152
+ const { imported , local } = path . node
153
+ lazyImportSpecifier =
154
+ parent . source . value == '@loadable/component' &&
155
+ imported &&
156
+ imported . name == 'lazy' &&
157
+ local &&
158
+ local . name
159
+ }
160
+ } ,
161
+ CallExpression ( path ) {
162
+ if (
163
+ ! isValidIdentifier (
164
+ path ,
165
+ loadableImportSpecifier ,
166
+ lazyImportSpecifier ,
197
167
)
198
- return
199
- transformImport ( path )
200
- } ,
201
- 'ArrowFunctionExpression|FunctionExpression|ObjectMethod' : path => {
202
- if ( ! hasLoadableComment ( path ) ) return
203
- transformImport ( path )
204
- } ,
205
- } )
206
- } ,
168
+ )
169
+ return
170
+ transformImport ( path )
171
+ } ,
172
+ 'ArrowFunctionExpression|FunctionExpression|ObjectMethod' : path => {
173
+ if ( ! hasLoadableComment ( path ) ) return
174
+ transformImport ( path )
175
+ } ,
176
+ } )
207
177
} ,
208
178
} ,
209
- }
210
- } ,
211
- )
179
+ } ,
180
+ }
181
+ } )
212
182
213
183
export default loadablePlugin
0 commit comments