]>
git.proxmox.com Git - mirror_novnc.git/blob - utils/use_require.js
2e1e2d07e73eb7189cb6da223aa4545483534a35
3 var path
= require ( 'path' );
4 var program
= require ( 'commander' );
5 var fs
= require ( 'fs' );
6 var fse
= require ( 'fs-extra' );
7 var babel
= require ( 'babel-core' );
9 const SUPPORTED_FORMATS
= new Set ([ 'amd' , 'commonjs' , 'systemjs' , 'umd' ]);
12 . option ( '--as [format]' , `output files using various import formats instead of ES6 import and export. Supports ${Array.from(SUPPORTED_FORMATS)} .` )
13 . option ( '-m, --with-source-maps [type]' , 'output source maps when not generating a bundled app (type may be empty for external source maps, inline for inline source maps, or both) ' )
14 . option ( '--with-app' , 'process app files as well as core files' )
15 . option ( '--clean' , 'clear the lib folder before building' )
18 // the various important paths
20 main
: path
. resolve ( __dirname
, '..' ),
21 core
: path
. resolve ( __dirname
, '..' , 'core' ),
22 app
: path
. resolve ( __dirname
, '..' , 'app' ),
23 vendor
: path
. resolve ( __dirname
, '..' , 'vendor' ),
24 out_dir_base
: path
. resolve ( __dirname
, '..' , 'build' ),
25 lib_dir_base
: path
. resolve ( __dirname
, '..' , 'lib' ),
28 const no_copy_files
= new Set ([
29 // skip these -- they don't belong in the processed application
30 path
. join ( paths
. vendor
, 'sinon.js' ),
31 path
. join ( paths
. vendor
, 'browser-es-module-loader' ),
32 path
. join ( paths
. vendor
, 'promise.js' ),
35 const no_transform_files
= new Set ([
36 // don't transform this -- we want it imported as-is to properly catch loading errors
37 path
. join ( paths
. app
, 'error-handler.js' ),
40 no_copy_files
. forEach (( file
) => no_transform_files
. add ( file
));
42 // util.promisify requires Node.js 8.x, so we have our own
43 function promisify ( original
) {
46 let args
= Array
. prototype . slice
. call ( arguments
);
47 return new Promise (( resolve
, reject
) => {
48 original
. apply ( obj
, args
. concat (( err
, value
) => {
49 if ( err
) return reject ( err
);
56 const readFile
= promisify ( fs
. readFile
);
57 const writeFile
= promisify ( fs
. writeFile
);
59 const readdir
= promisify ( fs
. readdir
);
60 const lstat
= promisify ( fs
. lstat
);
62 const copy
= promisify ( fse
. copy
);
63 const ensureDir
= promisify ( fse
. ensureDir
);
65 const babelTransformFile
= promisify ( babel
. transformFile
);
67 // walkDir *recursively* walks directories trees,
68 // calling the callback for all normal files found.
69 var walkDir = function ( base_path
, cb
, filter
) {
70 return readdir ( base_path
)
72 let paths
= files
. map ( filename
=> path
. join ( base_path
, filename
));
73 return Promise
. all ( paths
. map (( filepath
) => {
74 return lstat ( filepath
)
76 if ( filter
!== undefined && ! filter ( filepath
, stats
)) return ;
78 if ( stats
. isSymbolicLink ()) return ;
79 if ( stats
. isFile ()) return cb ( filepath
);
80 if ( stats
. isDirectory ()) return walkDir ( filepath
, cb
, filter
);
86 var transform_html = function ( new_script
) {
87 // write out the modified vnc.html file that works with the bundle
88 var src_html_path
= path
. resolve ( __dirname
, '..' , 'vnc.html' );
89 var out_html_path
= path
. resolve ( paths
. out_dir_base
, 'vnc.html' );
90 return readFile ( src_html_path
)
91 . then ( contents_raw
=> {
92 var contents
= contents_raw
. toString ();
94 var start_marker
= '<!-- begin scripts --> \n ' ;
95 var end_marker
= '<!-- end scripts -->' ;
96 var start_ind
= contents
. indexOf ( start_marker
) + start_marker
. length
;
97 var end_ind
= contents
. indexOf ( end_marker
, start_ind
);
99 contents
= contents
. slice ( 0 , start_ind
) + ` ${new_script} \n ` + contents
. slice ( end_ind
);
103 . then (( contents
) => {
104 console
. log ( `Writing ${out_html_path} ` );
105 return writeFile ( out_html_path
, contents
);
109 var make_lib_files = function ( import_format
, source_maps
, with_app_dir
) {
110 if (! import_format
) {
111 throw new Error ( "you must specify an import format to generate compiled noVNC libraries" );
112 } else if (! SUPPORTED_FORMATS
. has ( import_format
)) {
113 throw new Error ( `unsupported output format " ${import_format} " for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported` );
116 // NB: we need to make a copy of babel_opts, since babel sets some defaults on it
117 const babel_opts
= () => ({
118 plugins
: [ `transform-es2015-modules- ${import_format} ` ],
120 sourceMaps
: source_maps
,
125 var out_path_base
= paths
. out_dir_base
;
126 in_path
= paths
. main
;
128 var out_path_base
= paths
. lib_dir_base
;
131 fse
. ensureDirSync ( out_path_base
);
133 const helpers
= require ( './use_require_helpers' );
134 const helper
= helpers
[ import_format
];
136 var handleDir
= ( js_only
, vendor_rewrite
, in_path_base
, filename
) => Promise
. resolve ()
138 if ( no_copy_files
. has ( filename
)) return ;
140 const out_path
= path
. join ( out_path_base
, path
. relative ( in_path_base
, filename
));
141 if ( path
. extname ( filename
) !== '.js' ) {
143 console
. log ( `Writing ${out_path} ` );
144 return copy ( filename
, out_path
);
146 return ; // skip non-javascript files
149 return ensureDir ( path
. dirname ( out_path
))
151 if ( no_transform_files
. has ( filename
)) {
152 console
. log ( `Writing ${out_path} ` );
153 return copy ( filename
, out_path
);
156 const opts
= babel_opts ();
157 if ( helper
&& helpers
. optionsOverride
) {
158 helper
. optionsOverride ( opts
);
160 // Adjust for the fact that we move the core files relative
161 // to the vendor directory
162 if ( vendor_rewrite
) {
163 opts
. plugins
. push ([ "import-redirect" ,
164 { "root" : out_path_base
,
165 "redirect" : { "vendor/(.+)" : "./vendor/$1" }}]);
168 return babelTransformFile ( filename
, opts
)
170 console
. log ( `Writing ${out_path} ` );
171 var { code
, map
, ast
} = res
;
172 if ( source_maps
=== true ) {
173 // append URL for external source map
174 code
+= ` \n //# sourceMappingURL= ${path.basename(out_path)} .map \n ` ;
176 return writeFile ( out_path
, code
)
178 if ( source_maps
=== true || source_maps
=== 'both' ) {
179 console
. log ( ` and ${out_path} .map` );
180 return writeFile ( ` ${out_path} .map` , JSON
. stringify ( map
));
187 if ( with_app_dir
&& helper
&& helper
. noCopyOverride
) {
188 helper
. noCopyOverride ( paths
, no_copy_files
);
193 let handler
= handleDir
. bind ( null , true , false , in_path
|| paths
. main
);
194 let filter
= ( filename
, stats
) => ! no_copy_files
. has ( filename
);
195 return walkDir ( paths
. vendor
, handler
, filter
);
198 let handler
= handleDir
. bind ( null , true , ! in_path
, in_path
|| paths
. core
);
199 let filter
= ( filename
, stats
) => ! no_copy_files
. has ( filename
);
200 return walkDir ( paths
. core
, handler
, filter
);
203 if (! with_app_dir
) return ;
204 let handler
= handleDir
. bind ( null , false , false , in_path
);
205 let filter
= ( filename
, stats
) => ! no_copy_files
. has ( filename
);
206 return walkDir ( paths
. app
, handler
, filter
);
209 if (! with_app_dir
) return ;
211 if (! helper
|| ! helper
. appWriter
) {
212 throw new Error ( `Unable to generate app for the ${import_format} format!` );
215 const out_app_path
= path
. join ( out_path_base
, 'app.js' );
216 console
. log ( `Writing ${out_app_path} ` );
217 return helper
. appWriter ( out_path_base
, out_app_path
)
218 . then ( transform_html
);
221 console
. error ( `Failure converting modules: ${err} ` );
227 console
. log ( `Removing ${paths.lib_dir_base} ` );
228 fse
. removeSync ( paths
. lib_dir_base
);
230 console
. log ( `Removing ${paths.out_dir_base} ` );
231 fse
. removeSync ( paths
. out_dir_base
);
234 make_lib_files ( program
. as
, program
. withSourceMaps
, program
. withApp
);