33const fs = require ( 'fs' ) ;
44const path = require ( 'path' ) ;
55
6- const filenames = process . argv . slice ( 2 ) ; // Trim off node and script name.
6+ const filenames = process . argv . slice ( 2 ) ; // Trim off node and script name.
77
88//////////////////////////////////////////////////////////////////////
99// Load deps files via require (since they're executalbe .js files).
@@ -40,7 +40,7 @@ globalThis.goog = {};
4040 * to {'module': 'goog'} for backwards-compatibility. Valid properties
4141 * and values include {'module': 'goog'} and {'lang': 'es6'}.
4242 */
43- goog . addDependency = function ( relPath , provides , _requires , opt_loadFlags ) {
43+ goog . addDependency = function ( relPath , provides , _requires , opt_loadFlags ) {
4444 // Ignore any non-ESM files, as they can't be imported.
4545 if ( opt_loadFlags ?. module !== 'es6' ) return ;
4646
@@ -61,7 +61,7 @@ require(path.resolve(__dirname, '../../build/deps.js'));
6161
6262/** RegExp matching goog.require statements. */
6363const requireRE =
64- / (?: c o n s t \s + (?: ( [ $ \w ] + ) | ( \{ [ ^ } ] * \} ) ) \s + = \s + ) ? g o o g .r e q u i r e ( T y p e ) ? \( ' ( [ ^ ' ] + ) ' \) ; / mg ;
64+ / (?: c o n s t \s + (?: ( [ $ \w ] + ) | ( \{ [ ^ } ] * \} ) ) \s + = \s + ) ? g o o g .r e q u i r e ( T y p e ) ? \( ' ( [ ^ ' ] + ) ' \) ; / gm ;
6565
6666/** RegExp matching key: value pairs in destructuring assignments. */
6767const keyValueRE = / ( [ $ \w ] + ) \s * : \s * ( [ $ \w ] + ) \s * (? = , | } ) / g;
@@ -80,72 +80,82 @@ for (const filename of filenames) {
8080 contents = contents . replace ( / ^ \s * [ " ' ] u s e s t r i c t [ " ' ] \s * ; * \n / m, '' ) ;
8181
8282 // Migrate from goog.module to goog.declareModuleId.
83- const closurePathRelative =
84- path . relative ( path . dirname ( path . resolve ( filename ) ) , closurePath ) ;
83+ const closurePathRelative = path . relative (
84+ path . dirname ( path . resolve ( filename ) ) ,
85+ closurePath ,
86+ ) ;
8587 contents = contents . replace (
86- / ^ g o o g .m o d u l e \( ' ( [ $ \w . ] + ) ' \) ; $ / m,
87- `import * as goog from '${ closurePathRelative } /goog.js';\n` +
88- `goog.declareModuleId('$1');` ) ;
88+ / ^ g o o g .m o d u l e \( ' ( [ $ \w . ] + ) ' \) ; $ / m,
89+ `import * as goog from '${ closurePathRelative } /goog.js';\n` +
90+ `goog.declareModuleId('$1');` ,
91+ ) ;
8992
9093 // Migrate from goog.require to import.
9194 contents = contents . replace (
92- requireRE ,
93- function (
94- orig , // Whole statement to be replaced.
95- name , // Name of named import of whole module (if applicable).
96- names , // {}-enclosed list of destructured imports.
97- type , // If truthy, it is a requireType not require.
98- moduleId , // goog.module ID that was goog.require()d.
99- ) {
100- const importPath = modulePaths [ moduleId ] ;
101- type = type ? ' type' : '' ;
102- if ( ! importPath ) {
103- console . warn ( `Unable to migrate goog.require('${
104- moduleId } ') as no ES module path known.`) ;
105- return orig ;
106- }
107- let relativePath =
108- path . relative ( path . dirname ( path . resolve ( filename ) ) , importPath ) ;
109- if ( relativePath [ 0 ] !== '.' ) relativePath = './' + relativePath ;
110- if ( name ) {
111- return `import${ type } * as ${ name } from '${ relativePath } ';` ;
112- } else if ( names ) {
113- names = names . replace ( keyValueRE , '$1 as $2' ) ;
114- return `import${ type } ${ names } from '${ relativePath } ';` ;
115- } else { // Side-effect only require.
116- return `import${ type } '${ relativePath } ';` ;
117- }
118- } ) ;
95+ requireRE ,
96+ function (
97+ orig , // Whole statement to be replaced.
98+ name , // Name of named import of whole module (if applicable).
99+ names , // {}-enclosed list of destructured imports.
100+ type , // If truthy, it is a requireType not require.
101+ moduleId , // goog.module ID that was goog.require()d.
102+ ) {
103+ const importPath = modulePaths [ moduleId ] ;
104+ type = type ? ' type' : '' ;
105+ if ( ! importPath ) {
106+ console . warn (
107+ `Unable to migrate goog.require('${ moduleId } ') as no ES module path known.` ,
108+ ) ;
109+ return orig ;
110+ }
111+ let relativePath = path . relative (
112+ path . dirname ( path . resolve ( filename ) ) ,
113+ importPath ,
114+ ) ;
115+ if ( relativePath [ 0 ] !== '.' ) relativePath = './' + relativePath ;
116+ if ( name ) {
117+ return `import${ type } * as ${ name } from '${ relativePath } ';` ;
118+ } else if ( names ) {
119+ names = names . replace ( keyValueRE , '$1 as $2' ) ;
120+ return `import${ type } ${ names } from '${ relativePath } ';` ;
121+ } else {
122+ // Side-effect only require.
123+ return `import${ type } '${ relativePath } ';` ;
124+ }
125+ } ,
126+ ) ;
119127
120128 // Find and update or remove old-style export assignemnts.
121129 /** @type {!Array<{name: string, re: RegExp>}> } */
122130 const easyExports = [ ] ;
123131 contents = contents . replace (
124- / ^ \s * e x p o r t s \. ( [ $ \w ] + ) \s * = \s * ( [ $ \w ] + ) \s * ; \n / gm,
125- function (
126- orig , // Whole statement to be replaced.
127- exportName , // Name to export item as.
128- declName , // Already-declared name for item being exported.
129- ) {
130- // Renamed exports have to be transalted as-is.
131- if ( exportName !== declName ) {
132- return `export {${ declName } as ${ exportName } };\n` ;
133- }
134- // OK, we're doing "export.foo = foo;". Can we update the
135- // declaration? We can't actualy modify it yet as we're in
136- // the middle of a search-and-replace on contents already, but
137- // we can delete the old export and later update the
138- // declaration into an export.
139- const declRE = new RegExp (
140- `^(\\s*)((?:const|let|var|function|class)\\s+${ declName } )\\b` ,
141- 'gm' ) ;
142- if ( contents . match ( declRE ) ) {
143- easyExports . push ( { exportName, declRE} ) ;
144- return '' ; // Delete existing export assignment.
145- } else {
146- return `export ${ exportName } ;\n` ; // Safe fallback.
147- }
148- } ) ;
132+ / ^ \s * e x p o r t s \. ( [ $ \w ] + ) \s * = \s * ( [ $ \w ] + ) \s * ; \n / gm,
133+ function (
134+ orig , // Whole statement to be replaced.
135+ exportName , // Name to export item as.
136+ declName , // Already-declared name for item being exported.
137+ ) {
138+ // Renamed exports have to be transalted as-is.
139+ if ( exportName !== declName ) {
140+ return `export {${ declName } as ${ exportName } };\n` ;
141+ }
142+ // OK, we're doing "export.foo = foo;". Can we update the
143+ // declaration? We can't actualy modify it yet as we're in
144+ // the middle of a search-and-replace on contents already, but
145+ // we can delete the old export and later update the
146+ // declaration into an export.
147+ const declRE = new RegExp (
148+ `^(\\s*)((?:const|let|var|function|class)\\s+${ declName } )\\b` ,
149+ 'gm' ,
150+ ) ;
151+ if ( contents . match ( declRE ) ) {
152+ easyExports . push ( { exportName, declRE} ) ;
153+ return '' ; // Delete existing export assignment.
154+ } else {
155+ return `export ${ exportName } ;\n` ; // Safe fallback.
156+ }
157+ } ,
158+ ) ;
149159 // Add 'export' to existing declarations where appropriate.
150160 for ( const { exportName, declRE} of easyExports ) {
151161 contents = contents . replace ( declRE , '$1export $2' ) ;
0 commit comments