@@ -14,15 +14,15 @@ const path = require('path');
1414const util = require ( 'util' ) ;
1515const opn = require ( 'opn' ) ;
1616const minimist = require ( 'minimist' ) ;
17-
18- const webpack = require ( "webpack" ) ;
17+ const webpack = require ( 'webpack' ) ;
1918
2019const APP_ROOT = path . dirname ( __dirname ) ;
2120const EXTENSIONS_ROOT = path . join ( APP_ROOT , 'extensions' ) ;
2221const WEB_MAIN = path . join ( APP_ROOT , 'src' , 'vs' , 'code' , 'browser' , 'workbench' , 'workbench-dev.html' ) ;
2322
2423const args = minimist ( process . argv , {
2524 boolean : [
25+ 'watch' ,
2626 'no-launch' ,
2727 'help'
2828 ] ,
@@ -37,6 +37,7 @@ const args = minimist(process.argv, {
3737if ( args . help ) {
3838 console . log (
3939 'yarn web [options]\n' +
40+ ' --watch Watch extensions that require browser specific builds\n' +
4041 ' --no-launch Do not open VSCode web in the browser\n' +
4142 ' --scheme Protocol (https or http)\n' +
4243 ' --host Remote host\n' +
@@ -55,6 +56,83 @@ const SCHEME = args.scheme || process.env.VSCODE_SCHEME || 'http';
5556const HOST = args . host || 'localhost' ;
5657const AUTHORITY = process . env . VSCODE_AUTHORITY || `${ HOST } :${ PORT } ` ;
5758
59+ const exists = ( path ) => util . promisify ( fs . exists ) ( path ) ;
60+ const readFile = ( path ) => util . promisify ( fs . readFile ) ( path ) ;
61+
62+ async function initialize ( ) {
63+ const extensionFolders = await util . promisify ( fs . readdir ) ( EXTENSIONS_ROOT ) ;
64+
65+ const staticExtensions = [ ] ;
66+
67+ const webpackConfigs = [ ] ;
68+
69+ await Promise . all ( extensionFolders . map ( async extensionFolder => {
70+ const packageJSONPath = path . join ( EXTENSIONS_ROOT , extensionFolder , 'package.json' ) ;
71+ if ( await exists ( packageJSONPath ) ) {
72+ try {
73+ const packageJSON = JSON . parse ( ( await readFile ( packageJSONPath ) ) . toString ( ) ) ;
74+ if ( packageJSON . main && ! packageJSON . browser ) {
75+ return ; // unsupported
76+ }
77+
78+ if ( packageJSON . browser ) {
79+ packageJSON . main = packageJSON . browser ;
80+ const webpackConfigPath = path . join ( EXTENSIONS_ROOT , extensionFolder , 'extension-browser.webpack.config.js' ) ;
81+ if ( ( await exists ( webpackConfigPath ) ) ) {
82+ const configOrFnOrArray = require ( webpackConfigPath ) ;
83+ function addConfig ( configOrFn ) {
84+ if ( typeof configOrFn === 'function' ) {
85+ webpackConfigs . push ( configOrFn ( { } , { } ) ) ;
86+ } else {
87+ webpackConfigs . push ( configOrFn ) ;
88+ }
89+ }
90+ if ( Array . isArray ( configOrFnOrArray ) ) {
91+ configOrFnOrArray . forEach ( addConfig ) ;
92+ } else {
93+ addConfig ( configOrFnOrArray ) ;
94+ }
95+ }
96+ }
97+
98+ packageJSON . extensionKind = [ 'web' ] ; // enable for Web
99+ staticExtensions . push ( {
100+ packageJSON,
101+ extensionLocation : { scheme : SCHEME , authority : AUTHORITY , path : `/static-extension/${ extensionFolder } ` }
102+ } ) ;
103+ } catch ( e ) {
104+ console . log ( e ) ;
105+ }
106+ }
107+ } ) ) ;
108+
109+ return new Promise ( ( resolve , reject ) => {
110+ if ( args . watch ) {
111+ webpack ( webpackConfigs ) . watch ( { } , ( err , stats ) => {
112+ if ( err ) {
113+ console . log ( err ) ;
114+ reject ( ) ;
115+ } else {
116+ console . log ( stats . toString ( ) ) ;
117+ resolve ( staticExtensions ) ;
118+ }
119+ } ) ;
120+ } else {
121+ webpack ( webpackConfigs ) . run ( ( err , stats ) => {
122+ if ( err ) {
123+ console . log ( err ) ;
124+ reject ( ) ;
125+ } else {
126+ console . log ( stats . toString ( ) ) ;
127+ resolve ( staticExtensions ) ;
128+ }
129+ } ) ;
130+ }
131+ } ) ;
132+ }
133+
134+ const staticExtensionsPromise = initialize ( ) ;
135+
58136const server = http . createServer ( ( req , res ) => {
59137 const parsedUrl = url . parse ( req . url , true ) ;
60138 const pathname = parsedUrl . pathname ;
@@ -141,46 +219,22 @@ function handleStaticExtension(req, res, parsedUrl) {
141219 * @param {import('http').ServerResponse } res
142220 */
143221async function handleRoot ( req , res ) {
144- const extensionFolders = await util . promisify ( fs . readdir ) ( EXTENSIONS_ROOT ) ;
145-
146- const staticExtensions = [ ] ;
147-
148- const webpackConfigs = [ ] ;
149-
150- await Promise . all ( extensionFolders . map ( async extensionFolder => {
151- try {
152- const packageJSON = JSON . parse ( ( await util . promisify ( fs . readFile ) ( path . join ( EXTENSIONS_ROOT , extensionFolder , 'package.json' ) ) ) . toString ( ) ) ;
153- if ( packageJSON . main && ! packageJSON . browser ) {
154- return ; // unsupported
155- }
156- if ( packageJSON . browser ) {
157- packageJSON . main = packageJSON . browser ;
158- const webpackConfigPath = path . join ( EXTENSIONS_ROOT , extensionFolder , 'extension-browser.webpack.config.js' ) ;
159- if ( ( await util . promisify ( fs . exists ) ( webpackConfigPath ) ) ) {
160- webpackConfigs . push ( require ( webpackConfigPath ) ) ;
161- packageJSON . main . replace ( '/out/' , '/dist/' ) ;
162- }
163- }
164-
165- packageJSON . extensionKind = [ 'web' ] ; // enable for Web
166- staticExtensions . push ( {
167- packageJSON,
168- extensionLocation : { scheme : SCHEME , authority : AUTHORITY , path : `/static-extension/${ extensionFolder } ` }
169- } ) ;
170- } catch ( error ) {
171- return null ;
222+ const match = req . url && req . url . match ( / \? ( [ ^ # ] + ) / ) ;
223+ let ghPath ;
224+ if ( match ) {
225+ const qs = new URLSearchParams ( match [ 1 ] ) ;
226+ ghPath = qs . get ( 'gh' ) ;
227+ if ( ghPath && ! ghPath . startsWith ( '/' ) ) {
228+ ghPath = '/' + ghPath ;
172229 }
173- } ) ) ;
174-
175- webpack ( webpackConfigs ) . watch ( { } , ( err , stats ) => {
176- if ( err ) {
177- console . log ( err ) ;
178- } else {
179- console . log ( stats . toString ( ) ) ;
180- }
181- } ) ;
230+ }
182231
183- const webConfiguration = escapeAttribute ( JSON . stringify ( { staticExtensions, folderUri : { scheme : 'memfs' , path : `/sample-folder` } } ) ) ;
232+ const staticExtensions = await staticExtensionsPromise ;
233+ const webConfiguration = escapeAttribute ( JSON . stringify ( {
234+ staticExtensions, folderUri : ghPath
235+ ? { scheme : 'github' , authority : 'github.com' , path : ghPath }
236+ : { scheme : 'memfs' , path : `/sample-folder` }
237+ } ) ) ;
184238
185239 const data = ( await util . promisify ( fs . readFile ) ( WEB_MAIN ) ) . toString ( )
186240 . replace ( '{{WORKBENCH_WEB_CONFIGURATION}}' , ( ) => webConfiguration ) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied
0 commit comments