From c093c13848e9e072a494cdaa5b71701c5fff8933 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Sat, 12 Aug 2023 17:00:15 -0400 Subject: [PATCH] build: emit ES5 & include dist folder in standalone repos --- .../_tools/scripts/publish_packages.js | 125 +++++++++--------- .../@stdlib/_tools/scripts/transform.js | 13 ++ 2 files changed, 76 insertions(+), 62 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/scripts/publish_packages.js b/lib/node_modules/@stdlib/_tools/scripts/publish_packages.js index 8dad5c5ebf9..de2a12b5559 100644 --- a/lib/node_modules/@stdlib/_tools/scripts/publish_packages.js +++ b/lib/node_modules/@stdlib/_tools/scripts/publish_packages.js @@ -596,15 +596,18 @@ function onTopics( error, data, info ) { * @returns {void} */ function publish( pkg, clbk ) { + var fmtProdMsgVersion; var triggerRelease; var customLicense; var isTopLevelNS; var workflowPath; var ghpagesOpts; + var jscodeshift; var pkgJsonPath; var repoExists; var readmePath; var noBundles; + var contents; var mainJSON; var schedule; var workflow; @@ -619,9 +622,11 @@ function publish( pkg, clbk ) { var nLines; var readme; var mdPath; + var alias; var deps; var dist; var file; + var opts; var src; var pth; var i; @@ -789,8 +794,11 @@ function publish( pkg, clbk ) { readme = replace( readme, '', distPkg ); writeFileSync( readmePath, readme ); + opts = { + 'cwd': dist + }; command = [ - 'find '+dist+' -type f -name \'*.md\' -print0 ', // Find all regular Markdown files in the destination directory and print their full names to standard output... + 'find . -type f -name \'*.md\' -print0 ', // Find all regular Markdown files in the destination directory and print their full names to standard output... '| xargs -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '\'s/', @@ -800,10 +808,10 @@ function publish( pkg, clbk ) { '/g\'' // Replace all occurrences and not just the first... ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); command = [ - 'find '+dist+' -type f -name \'*.md\' -print0 ', // Find all regular Markdown files in the destination directory and print their full names to standard output... + 'find . -type f -name \'*.md\' -print0 ', // Find all regular Markdown files in the destination directory and print their full names to standard output... '| xargs -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '"/', @@ -824,13 +832,13 @@ function publish( pkg, clbk ) { '"' ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); if ( isTopLevelNS ) { // Rewrite internal packages as relative paths outside of documentation: for ( i = 0; i < MAX_TREE_DEPTH; i++ ) { command = [ - 'find '+dist+' -mindepth '+(1+i)+' -maxdepth '+(2+i)+' -type f \\( -name \'*.[jt]s\' \\) -print0 ', // Find all JavaScript and TypeScript files in the destination directory at the respective depth and print their full names to standard output... + 'find . -mindepth '+(1+i)+' -maxdepth '+(2+i)+' -type f \\( -name \'*.[jt]s\' \\) -print0 ', // Find all JavaScript and TypeScript files in the destination directory at the respective depth and print their full names to standard output... '| xargs -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '"/', @@ -848,7 +856,7 @@ function publish( pkg, clbk ) { ].join( '' ); debug( 'Executing command: %s', command ); try { - shell( command ); + shell( command, opts ); } catch ( err ) { // Break out of loop in case of no input files... debug( 'Encountered an error: %s', err.message ); @@ -858,7 +866,7 @@ function publish( pkg, clbk ) { } else { command = [ - 'find '+dist+' -type f \\( -name \'*.[jt]s\' -o -name \'*.md\' -o -name \'cli\' -o -name \'*.js.txt\' \\) -print0 ', // Find all JavaScript and TypeScript files in the destination directory and print their full names to standard output... + 'find . -type f \\( -name \'*.[jt]s\' -o -name \'*.md\' -o -name \'cli\' -o -name \'*.js.txt\' \\) -print0 ', // Find all JavaScript and TypeScript files in the destination directory and print their full names to standard output... '| xargs -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '"/', @@ -885,11 +893,11 @@ function publish( pkg, clbk ) { '"' ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); // Rewrite related packages in READMEs to point to standalone packages: command = [ - 'find '+dist+' -type f -name \'*.md\' ', // Find all Markdown files in the destination directory and print their full names to standard output... + 'find . -type f -name \'*.md\' ', // Find all Markdown files in the destination directory and print their full names to standard output... '-exec ', // Convert standard input to the arguments for following `sed` command... 'sed -i ', // Edit files in-place... '\'', @@ -898,10 +906,10 @@ function publish( pkg, clbk ) { ' {} +' ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); command = [ - 'find '+dist+' -type f -name \'*.js\' -print0 ', // Find all JavaScript files in the destination directory and print their full names to standard output... + 'find . -type f -name \'*.js\' -print0 ', // Find all JavaScript files in the destination directory and print their full names to standard output... '| xargs -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '"/', @@ -913,10 +921,10 @@ function publish( pkg, clbk ) { '/2g"' // Replace all forward slashes in package name except the first one... ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); command = [ - 'find '+dist+' -type f -name \'include.gypi\' -print0 ', // Find all `include.gypi` files in the destination directory and print their full names to standard output... + 'find . -type f -name \'include.gypi\' -print0 ', // Find all `include.gypi` files in the destination directory and print their full names to standard output... '| xargs -r -0 ', // Convert standard input to the arguments for following `sed` command... 'sed -Ei ', // Edit files in-place without creating a backup... '"s/', @@ -926,10 +934,10 @@ function publish( pkg, clbk ) { '/"' ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); command = [ - 'find '+dist+' -type f -name \'manifest.json\' -print0 ', // Find all `manifest.json` files in the destination directory and print their full names to standard output... + 'find . -type f -name \'manifest.json\' -print0 ', // Find all `manifest.json` files in the destination directory and print their full names to standard output... '| xargs -r -0 ', // Convert standard input to the arguments for following `sed` command if `find` returns output... 'sed -Ei ', // Edit files in-place without creating a backup... '"/', @@ -941,7 +949,7 @@ function publish( pkg, clbk ) { '/2g"' // Replace all forward slashes in package names except the first one... ].join( '' ); debug( 'Executing command: %s', command ); - shell( command ); + shell( command, opts ); } pkgJSON.homepage = 'https://stdlib.io'; pkgJSON.repository = { @@ -1025,6 +1033,45 @@ function publish( pkg, clbk ) { mdPath = join( dist, '.github', 'PULL_REQUEST_TEMPLATE.md' ); writeFileSync( mdPath, replace( PULL_REQUEST_TEMPLATE, '', pth ) ); + + // Add `@stdlib/error-tools-fmtprodmsg` in package.json if the package depends on `@stdlib/string-format`: + if ( pkgJSON.dependencies[ '@stdlib/string-format' ] ) { + fmtProdMsgVersion = npmVersion( '@stdlib/error-tools-fmtprodmsg' ); + pkgJSON.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = fmtProdMsgVersion; + deps.push( '@stdlib/error-tools-fmtprodmsg' ); + } + + // Transform error messages and save files to `dist` subdirectory: + command = 'cp -r lib tmp && mkdir dist'; + shell( command, opts ); + jscodeshift = join( rootDir(), 'node_modules', '.bin', 'jscodeshift' ); + command = 'STDLIB_PKG=\'@stdlib/'+distPkg+'\' '+jscodeshift+' ./tmp/**/*.js ./tmp/*.js -t '+join( __dirname, 'transform.js' ); + debug( 'Executing command: %s', command ); + shell( command, opts ); + command = 'find ./tmp -name "*.js" -exec sed -E -i "1i\\/\\*\\* \\@license '+pkgJSON.license+' \\*\\/\n" {} \\;'; + shell( command, opts ); + command = [ + 'npx esbuild tmp/index.js --bundle --format=cjs --target=es5', + '--sourcemap --minify --platform=node --outfile=dist/index.js', + '--external:'+deps.join( ' --external:' ) + ].join( ' ' ); + debug( 'Executing command: %s', command ); + shell( command, opts ); + command = 'rm -rf tmp'; + shell( command, opts ); + + // Extract the alias from the Typescript definition file (after `export =` but before the semicolon): + command = 'grep -oP \'(?<=export = ).*?(?=;)\' docs/types/index.d.ts'; + alias = trim( shell( command, opts ).toString() ); + + // Create the contents of a `index.d.ts` file in `dist` subdirectory that reexports `docs/types/index.d.ts` (we don't want to duplicate type definitions, so we just reexport them): + contents = [ + '/// ', + 'import '+alias+' from \'../docs/types/index\';', + 'export = '+alias+';' + ].join( '\n' ); + writeFileSync( join( dist, 'dist', 'index.d.ts' ), contents ); + if ( flags[ 'skip-upload' ] ) { return invokeCallback( null, 'skipped' ); } @@ -1082,24 +1129,15 @@ function publish( pkg, clbk ) { * @private */ function publishToNPM() { - var fmtProdMsgVersion; - var jscodeshift; - var contents; var command; var escaped; var cliPkg; - var alias; var found; - var opts; var dep; console.log( 'Publishing '+dist+' to npm...' ); pkgJSON = populateDeps( pkgJSON, deps, devDeps, mainJSON, false ); - opts = { - 'cwd': dist - }; - command = 'rm -f docs/repl.txt && rm -f docs/types/test.ts'; shell( command, opts ); if ( hasCLI ) { @@ -1164,43 +1202,6 @@ function publish( pkg, clbk ) { } } } - // Add `@stdlib/error-tools-fmtprodmsg` in package.json if the package depends on `@stdlib/string-format`: - if ( pkgJSON.dependencies[ '@stdlib/string-format' ] ) { - fmtProdMsgVersion = npmVersion( '@stdlib/error-tools-fmtprodmsg' ); - pkgJSON.dependencies[ '@stdlib/error-tools-fmtprodmsg' ] = fmtProdMsgVersion; - deps.push( '@stdlib/error-tools-fmtprodmsg' ); - } - - // Transform error messages and save files to `dist` subdirectory: - command = 'cp -r lib tmp && mkdir dist'; - shell( command, opts ); - jscodeshift = join( rootDir(), 'node_modules', '.bin', 'jscodeshift' ); - command = 'STDLIB_PKG=\'@stdlib/'+distPkg+'\' '+jscodeshift+' ./tmp/**/*.js ./tmp/*.js -t '+join( __dirname, 'transform.js' ); - debug( 'Executing command: %s', command ); - shell( command, opts ); - command = 'find ./tmp -name "*.js" -exec sed -E -i "1i\\/\\*\\* \\@license '+pkgJSON.license+' \\*\\/\n" {} \\;'; - shell( command, opts ); - command = [ - 'npx esbuild tmp/index.js --bundle --format=cjs', - '--sourcemap --minify --platform=node --outfile=dist/index.js', - '--external:'+deps.join( ' --external:' ) - ].join( ' ' ); - debug( 'Executing command: %s', command ); - shell( command, opts ); - command = 'rm -rf tmp'; - shell( command, opts ); - - // Extract the alias from the Typescript definition file (after `export =` but before the semicolon): - command = 'grep -oP \'(?<=export = ).*?(?=;)\' docs/types/index.d.ts'; - alias = trim( shell( command, opts ).toString() ); - - // Create the contents of a `index.d.ts` file in `dist` subdirectory that reexports `docs/types/index.d.ts` (we don't want to duplicate type definitions, so we just reexport them): - contents = [ - '/// ', - 'import '+alias+' from \'../docs/types/index\';', - 'export = '+alias+';' - ].join( '\n' ); - writeFileSync( join( dist, 'dist', 'index.d.ts' ), contents ); // Replace GitHub MathJax equations with SVGs: command = 'find . -type f -name \'*.md\' -print0 | xargs -0 perl -0777 -i -pe \'s/```math\\n([\\s\\S]+?)\\n```\\n\\n//g\''; diff --git a/lib/node_modules/@stdlib/_tools/scripts/transform.js b/lib/node_modules/@stdlib/_tools/scripts/transform.js index 252ec4b7136..214dd5cdc9d 100644 --- a/lib/node_modules/@stdlib/_tools/scripts/transform.js +++ b/lib/node_modules/@stdlib/_tools/scripts/transform.js @@ -22,6 +22,7 @@ var logger = require( 'debug' ); var startsWith = require('@stdlib/string/starts-with'); +var endsWith = require('@stdlib/string/ends-with'); var replace = require( '@stdlib/string/replace' ); var pkg2id = require( '@stdlib/error/tools/pkg2id' ); var msg2id = require( '@stdlib/error/tools/msg2id'); @@ -76,6 +77,18 @@ function transformer( fileInfo, api ) { root.find(j.Program).forEach( onProgram ); + // We only need to keep a single "use strict" directive as all files are concatenated into a single bundle... + if ( !endsWith( fileInfo.path, 'index.js' ) ) { + root + .find( j.ExpressionStatement, { + 'expression': { + 'type': 'Literal', + 'value': 'use strict' + } + }) + .remove(); + } + requires = root.find( j.CallExpression, { 'callee': { 'name': 'require',