1
1
import { fileURLToPath } from 'node:url'
2
- import { createRequire } from 'node:module'
3
2
import { transformAsync } from '@babel/core'
4
3
import t from '@babel/types'
5
4
import autoprefixer from 'autoprefixer'
@@ -9,50 +8,11 @@ import postcssDirPseudoClass from 'postcss-dir-pseudo-class'
9
8
const ROOT = new URL ( '../../' , import . meta. url )
10
9
const PACKAGES_ROOT = fileURLToPath ( new URL ( './packages/' , ROOT ) )
11
10
12
- // To enable the plugin, it looks like we need to interact with the resolution
13
- // algorithm, but we need to stop afterwards otherwise it messes up somewhere
14
- // else. This hack can be removed when we get rid of JSX inside of .js files.
15
- let counter = 0
16
-
17
- const moduleTypeCache = new Map ( )
18
- function isTypeModule ( file ) {
19
- const packageFolder = file . slice ( 0 , file . indexOf ( '/src/' ) + 1 )
20
-
21
- const cachedValue = moduleTypeCache . get ( packageFolder )
22
- if ( cachedValue != null ) return cachedValue
23
-
24
- // eslint-disable-next-line import/no-dynamic-require, global-require
25
- const { type } = createRequire ( packageFolder ) ( './package.json' )
26
- const typeModule = type === 'module'
27
- moduleTypeCache . set ( packageFolder , typeModule )
28
- return typeModule
29
- }
30
- const packageLibImport = / ^ @ u p p y \/ ( [ ^ / ] + ) \/ l i b \/ ( .+ ) $ /
31
- const packageEntryImport = / ^ @ u p p y \/ ( [ ^ / ] + ) $ /
32
- function isSpecifierTypeModule ( specifier ) {
33
- const packageLib = packageLibImport . exec ( specifier )
34
- if ( packageLib != null ) {
35
- return isTypeModule ( `${ PACKAGES_ROOT } @uppy/${ packageLib [ 1 ] } /src/${ packageLib [ 2 ] } ` )
36
- }
37
- const packageEntry = packageEntryImport . exec ( specifier )
38
- if ( packageEntry != null ) {
39
- return isTypeModule ( `${ PACKAGES_ROOT } @uppy/${ packageEntry [ 1 ] } /src/index.js` )
40
- }
41
- return false
42
- }
43
-
44
- const JS_FILE_EXTENSION = / \. j s x ? $ /
45
-
46
11
/**
47
12
* @type {import('vite').UserConfig }
48
13
*/
49
14
const config = {
50
15
envDir : fileURLToPath ( ROOT ) ,
51
- build : {
52
- commonjsOptions : {
53
- defaultIsModuleExports : true ,
54
- } ,
55
- } ,
56
16
css : {
57
17
postcss : {
58
18
plugins : [
@@ -87,98 +47,49 @@ const config = {
87
47
] ,
88
48
} ,
89
49
plugins : [
90
- // TODO: remove plugin when we switch to ESM and get rid of JSX inside .js files .
50
+ // TODO: remove plugin when we remove the socket.io require call in @uppy /transloadit/src/Assembly .
91
51
{
92
- name : 'vite-plugin-jsx-commonjs' ,
93
- // TODO: remove this hack when we get rid of JSX inside .js files.
94
- enforce : 'pre' ,
52
+ name : 'vite-plugin-rewrite-dynamic-socketIo-require' ,
95
53
// eslint-disable-next-line consistent-return
96
54
resolveId ( id ) {
97
- if ( id . startsWith ( PACKAGES_ROOT ) && JS_FILE_EXTENSION . test ( id ) ) {
98
- return id
99
- }
100
- // TODO: remove this hack when we get rid of JSX inside .js files.
101
- if ( counter ++ < 2 ) {
55
+ if ( id . startsWith ( PACKAGES_ROOT ) && id . endsWith ( 'transloadit/src/Assembly.js' ) ) {
102
56
return id
103
57
}
104
58
} ,
105
59
transform ( code , id ) {
106
- if ( id . startsWith ( PACKAGES_ROOT ) && JS_FILE_EXTENSION . test ( id ) ) {
107
- return transformAsync ( code , isTypeModule ( id ) ? {
60
+ if ( id . startsWith ( PACKAGES_ROOT ) && id . endsWith ( 'transloadit/src/Assembly.js' ) ) {
61
+ return transformAsync ( code , {
108
62
plugins : [
109
- id . endsWith ( '.jsx' ) ? [ '@babel/plugin-transform-react-jsx' , { pragma : 'h' } ] : { } ,
110
63
{
111
- // On type: "module" packages, we still want to rewrite import
112
- // statements that tries to access a named export from a CJS
113
- // module to using only the default import.
114
64
visitor : {
115
- ImportDeclaration ( path ) {
116
- const { specifiers, source : { value } } = path . node
117
- if ( value . startsWith ( '@uppy/' ) && ! isSpecifierTypeModule ( value )
118
- && specifiers . some ( node => node . type !== 'ImportDefaultSpecifier' ) ) {
119
- const oldSpecifiers = specifiers [ 0 ] . type === 'ImportDefaultSpecifier'
120
- // If there's a default import, it must come first.
121
- ? specifiers . splice ( 1 )
122
- // If there's no default import, we create one from a random identifier.
123
- : specifiers . splice ( 0 , specifiers . length , t . importDefaultSpecifier ( t . identifier ( `_import_${ counter ++ } ` ) ) )
124
- if ( oldSpecifiers [ 0 ] . type === 'ImportNamespaceSpecifier' ) {
125
- // import defaultVal, * as namespaceImport from '@uppy/package'
126
- // is transformed into:
127
- // import defaultVal from '@uppy/package'; const namespaceImport = defaultVal
128
- path . insertAfter (
129
- t . variableDeclaration ( 'const' , [ t . variableDeclarator (
130
- oldSpecifiers [ 0 ] . local ,
131
- specifiers [ 0 ] . local ,
132
- ) ] ) ,
133
- )
134
- } else {
135
- // import defaultVal, { exportedVal as importedName, other } from '@uppy/package'
136
- // is transformed into:
137
- // import defaultVal from '@uppy/package'; const { exportedVal: importedName, other } = defaultVal
138
- path . insertAfter ( t . variableDeclaration ( 'const' , [ t . variableDeclarator (
139
- t . objectPattern (
140
- oldSpecifiers . map ( specifier => t . objectProperty (
141
- t . identifier ( specifier . imported . name ) ,
142
- specifier . local ,
143
- ) ) ,
144
- ) ,
145
- specifiers [ 0 ] . local ,
146
- ) ] ) )
65
+ FunctionDeclaration ( path ) {
66
+ if ( path . node . id . name === 'requireSocketIo' ) {
67
+ const prevSibling = path . getPrevSibling ( )
68
+ if ( t . isImportDeclaration ( prevSibling ) && prevSibling . node . specifiers ?. length === 1
69
+ && t . isImportDefaultSpecifier ( prevSibling . node . specifiers [ 0 ] )
70
+ && prevSibling . node . specifiers [ 0 ] . local . name === 'socketIo' ) {
71
+ // The require call has already been rewritten to an import statement.
72
+ return
73
+ }
74
+ if ( ! t . isVariableDeclaration ( prevSibling ) ) {
75
+ const { type, loc } = prevSibling . node
76
+ throw new Error ( `Unexpected ${ type } at line ${ loc . start . line } , cannot apply requireSocketIo hack` )
147
77
}
148
- }
149
- } ,
150
-
151
- // Very specific hack to avoid a breaking change when the file was refactored to ESM.
152
- // TODO: remove this hack in the next release.
153
- ...( id . endsWith ( 'transloadit/src/Assembly.js' ) ? {
154
- FunctionDeclaration ( path ) {
155
- if ( path . node . id . name === 'requireSocketIo' ) {
156
- const prevSibling = path . getPrevSibling ( )
157
- if ( ! t . isVariableDeclaration ( prevSibling ) || prevSibling . node . declarations [ 0 ] . id . name !== 'socketIo' ) {
158
- // The require call has already been rewritten to an import statement.
159
- return
160
- }
161
78
162
- const { id :socketIoIdentifier } = prevSibling . node . declarations [ 0 ]
79
+ const { id :socketIoIdentifier } = prevSibling . node . declarations [ 0 ]
163
80
164
- prevSibling . replaceWith ( t . importDeclaration (
165
- [ t . importDefaultSpecifier ( socketIoIdentifier ) ] ,
166
- t . stringLiteral ( 'socket.io-client' ) ,
167
- ) )
168
- path . replaceWith ( t . functionDeclaration ( path . node . id , path . node . params , t . blockStatement ( [
169
- t . returnStatement ( socketIoIdentifier ) ,
170
- ] ) ) )
171
- }
172
- } ,
173
- } : null ) ,
81
+ prevSibling . replaceWith ( t . importDeclaration (
82
+ [ t . importDefaultSpecifier ( socketIoIdentifier ) ] ,
83
+ t . stringLiteral ( 'socket.io-client' ) ,
84
+ ) )
85
+ path . replaceWith ( t . functionDeclaration ( path . node . id , path . node . params , t . blockStatement ( [
86
+ t . returnStatement ( socketIoIdentifier ) ,
87
+ ] ) ) )
88
+ }
89
+ } ,
174
90
} ,
175
91
} ,
176
92
] ,
177
- } : {
178
- plugins : [
179
- [ '@babel/plugin-transform-react-jsx' , { pragma : 'h' } ] ,
180
- 'transform-commonjs' ,
181
- ] ,
182
93
} )
183
94
}
184
95
return code
0 commit comments