1717'use strict' ;
1818
1919const childProcess = require ( 'child_process' ) ;
20- const { createHash } = require ( 'crypto' ) ;
20+ const { randomFillSync } = require ( 'crypto' ) ;
2121const fs = require ( 'fs' ) ;
2222const { isRegExp } = require ( 'util' ) . types ;
2323const Module = require ( 'module' ) ;
@@ -213,6 +213,44 @@ function createDirRecursively(dir) {
213213 }
214214}
215215
216+ function removeDirRecursively ( dir ) {
217+ if ( fs . existsSync ( dir ) ) {
218+ fs . readdirSync ( dir ) . forEach ( ( file ) => {
219+ const curPath = path . join ( dir , file ) ;
220+ if ( fs . lstatSync ( curPath ) . isDirectory ( ) ) {
221+ removeDirRecursively ( curPath ) ;
222+ } else {
223+ fs . unlinkSync ( curPath ) ;
224+ }
225+ } ) ;
226+ fs . rmdirSync ( dir ) ;
227+ }
228+ }
229+
230+ const tmpFolder = ( ( ) => {
231+ const buf = Buffer . alloc ( 16 ) ;
232+ randomFillSync ( buf ) ;
233+ return path . join ( tmpdir ( ) , 'pkg' , `${ process . pid } .${ buf . toString ( 'hex' ) } ` ) ;
234+ } ) ( ) ;
235+
236+ function removeTemporaryFolderAndContent ( folder ) {
237+ if ( ! folder ) return ;
238+
239+ if ( ! fs . existsSync ( folder ) ) {
240+ return ;
241+ }
242+
243+ if ( NODE_VERSION_MAJOR <= 10 ) {
244+ return removeDirRecursively ( folder ) ;
245+ }
246+
247+ if ( NODE_VERSION_MAJOR <= 14 ) {
248+ return fs . rmdirSync ( folder , { recursive : true } ) ;
249+ }
250+
251+ return fs . rmSync ( folder , { recursive : true } ) ;
252+ }
253+
216254/*
217255
218256// TODO move to some test
@@ -644,37 +682,23 @@ function payloadFileSync(pointer) {
644682 // open //////////////////////////////////////////////////////////
645683 // ///////////////////////////////////////////////////////////////
646684
647- function removeTemporaryFolderAndContent ( folder ) {
648- if ( ! folder ) return ;
649- if ( NODE_VERSION_MAJOR <= 14 ) {
650- if ( NODE_VERSION_MAJOR <= 10 ) {
651- // folder must be empty
652- for ( const f of fs . readdirSync ( folder ) ) {
653- fs . unlinkSync ( path . join ( folder , f ) ) ;
654- }
655- fs . rmdirSync ( folder ) ;
656- } else {
657- fs . rmdirSync ( folder , { recursive : true } ) ;
658- }
659- } else {
660- fs . rmSync ( folder , { recursive : true } ) ;
661- }
662- }
663685 const temporaryFiles = { } ;
664- const os = require ( 'os' ) ;
665- let tmpFolder = '' ;
686+
666687 process . on ( 'beforeExit' , ( ) => {
667688 removeTemporaryFolderAndContent ( tmpFolder ) ;
668689 } ) ;
690+
669691 function deflateSync ( snapshotFilename ) {
670- if ( ! tmpFolder ) {
671- tmpFolder = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'pkg-' ) ) ;
672- }
673692 const content = fs . readFileSync ( snapshotFilename , { encoding : 'binary' } ) ;
674- // content is already unzipped !
693+ const fName = path . join (
694+ tmpFolder ,
695+ process . platform === 'win32'
696+ ? findVirtualFileSystemKeyAndFollowLinks ( snapshotFilename ) . slice ( 2 )
697+ : findVirtualFileSystemKeyAndFollowLinks ( snapshotFilename )
698+ ) ;
699+
700+ createDirRecursively ( path . dirname ( fName ) ) ;
675701
676- const hash = createHash ( 'sha256' ) . update ( content ) . digest ( 'hex' ) ;
677- const fName = path . join ( tmpFolder , hash ) ;
678702 fs . writeFileSync ( fName , content , 'binary' ) ;
679703 return fName ;
680704 }
@@ -2160,18 +2184,6 @@ function payloadFileSync(pointer) {
21602184 const moduleFolder = path . dirname ( modulePath ) ;
21612185
21622186 if ( insideSnapshot ( modulePath ) ) {
2163- const moduleContent = fs . readFileSync ( modulePath ) ;
2164-
2165- // Node addon files and .so cannot be read with fs directly, they are loaded with process.dlopen which needs a filesystem path
2166- // we need to write the file somewhere on disk first and then load it
2167- // the hash is needed to be sure we reload the module in case it changes
2168- const hash = createHash ( 'sha256' ) . update ( moduleContent ) . digest ( 'hex' ) ;
2169-
2170- // Example: /tmp/pkg/<hash>
2171- const tmpFolder = path . join ( tmpdir ( ) , 'pkg' , hash ) ;
2172-
2173- createDirRecursively ( tmpFolder ) ;
2174-
21752187 // Example: moduleFolder = /snapshot/appname/node_modules/sharp/build/Release
21762188 const parts = moduleFolder . split ( path . sep ) ;
21772189 const mIndex = parts . indexOf ( 'node_modules' ) + 1 ;
@@ -2181,6 +2193,8 @@ function payloadFileSync(pointer) {
21812193 // it's a node addon file contained in node_modules folder
21822194 // we copy the entire module folder in tmp folder
21832195 if ( mIndex > 0 ) {
2196+ createDirRecursively ( path . join ( tmpFolder , 'node_modules' ) ) ;
2197+
21842198 // Example: modulePackagePath = sharp/build/Release
21852199 const modulePackagePath = parts . slice ( mIndex ) . join ( path . sep ) ;
21862200 // Example: modulePkgFolder = /snapshot/appname/node_modules/sharp
@@ -2189,11 +2203,21 @@ function payloadFileSync(pointer) {
21892203 // here we copy all files from the snapshot module folder to temporary folder
21902204 // we keep the module folder structure to prevent issues with modules that are statically
21912205 // linked using relative paths (Fix #1075)
2192- copyFolderRecursiveSync ( modulePkgFolder , tmpFolder ) ;
2206+ copyFolderRecursiveSync (
2207+ modulePkgFolder ,
2208+ path . join ( tmpFolder , 'node_modules' )
2209+ ) ;
21932210
2194- // Example: /tmp/pkg/<hash>/sharp/build/Release/sharp.node
2195- newPath = path . join ( tmpFolder , modulePackagePath , moduleBaseName ) ;
2211+ // Example: /tmp/pkg/<hash>/node_modules/sharp/build/Release/sharp.node
2212+ newPath = path . join (
2213+ tmpFolder ,
2214+ 'node_modules' ,
2215+ modulePackagePath ,
2216+ moduleBaseName
2217+ ) ;
21962218 } else {
2219+ createDirRecursively ( tmpFolder ) ;
2220+
21972221 const tmpModulePath = path . join ( tmpFolder , moduleBaseName ) ;
21982222
21992223 if ( ! fs . existsSync ( tmpModulePath ) ) {
0 commit comments