1- import gulp from 'gulp' ;
2- const { src, dest, series, parallel } = gulp ;
3- import concat from 'gulp-concat' ;
4- import { deleteAsync , deleteSync } from 'del' ;
1+ import gulp , { src , dest , series , parallel , TaskFunction , TaskFunctionCallback } from 'gulp' ;
2+ import webpackStream from 'webpack-stream' ;
3+ import { deleteAsync } from 'del' ;
54import rename from 'gulp-rename' ;
65import zip from 'gulp-zip' ;
76import mocha from 'gulp-mocha' ;
87import { promises as fs } from 'fs' ;
98import open from 'open' ;
10- import { makePromise , runParallel , runSeries , contentTransform , execTask } from './gulputils.mjs ' ;
9+ import { makePromise , runParallel , runSeries , contentTransform , execTask } from './gulputils' ;
1110import newer from 'gulp-newer' ;
1211import minimist from 'minimist' ;
1312import karma from 'karma' ;
14- import { fileURLToPath } from 'url' ;
15- const __filename = fileURLToPath ( import . meta. url ) ;
13+ import path from 'path' ;
1614
17-
18- const BROWSERS = [ 'chrome' , 'firefox' , 'edge' ] ;
19- const BROWSER_FLAGS = { } ;
20- for ( const browser of BROWSERS ) {
21- BROWSER_FLAGS [ `--${ browser } ` ] = `for [${ browser } ] browser` ;
22- }
23-
24- function doubleInclusionGuard ( ) {
25- return contentTransform ( ( contents , file , enc ) =>
26- `if (!self["..SMLoaded:${ file . basename } "]) {
27- ${ contents } ;
28- self["..SMLoaded:${ file . basename } "]=true;
29- }` ) ;
30- }
15+ type Browser = 'chrome' | 'firefox' | 'edge'
16+ const BROWSERS : Browser [ ] = [ 'chrome' , 'firefox' , 'edge' ]
17+ const BROWSER_FLAGS = Object . fromEntries ( BROWSERS . map ( ( browser ) => [ `--${ browser } ` , `for [${ browser } ] browser` ] ) ) ;
3118
3219class BuildContext {
20+ browser : Browser ;
21+ version : number ;
3322
34- constructor ( browser , version ) {
23+ constructor ( browser : Browser , version : number ) {
3524 if ( ! browser ) throw new Error ( 'Browser is not defined' ) ;
3625 if ( ! version ) throw new Error ( 'Version is not defined' ) ;
3726 this . browser = browser ;
3827 this . version = version ;
3928
4029 // Bind all the functions of this instance
4130 for ( const prop of Object . getOwnPropertyNames ( BuildContext . prototype ) ) {
42- if ( this [ prop ] instanceof Function ) {
43- this [ prop ] = this [ prop ] . bind ( this ) ;
44- this [ prop ] . displayName = `[${ browser } ] ${ this [ prop ] . name } ` ;
31+ if ( ( this as any ) [ prop ] instanceof Function ) {
32+ ( this as any ) [ prop ] = ( this as any ) [ prop ] . bind ( this ) ;
33+ ( this as any ) [ prop ] . displayName = `[${ browser } ] ${ ( this as any ) [ prop ] . name } ` ;
4534 }
4635 }
4736 }
@@ -53,34 +42,13 @@ class BuildContext {
5342
5443 copySourceFiles ( ) {
5544 return src ( [
56- 'src/**/*.js' ,
57- 'src/**/*.mjs' ,
5845 'src/**/*.css' ,
5946 'src/**/*.html' ,
60- '!src/inject_frame.js' ,
61- '!src/inject_frame_permission.js' ,
62- '!src/inject_everywhere.js' ,
63- '!src/options/maps_embed.mjs' ,
64- '!src/options/maps_embed_with_key.mjs' ,
6547 ] )
6648 . pipe ( newer ( `${ this . pluginDir ( ) } /src` ) )
6749 . pipe ( dest ( `${ this . pluginDir ( ) } /src` ) ) ;
6850 }
6951
70- async copyMapsEmbedFile ( ) {
71- let mapsEmbedFile ;
72- try {
73- await fs . access ( 'src/options/maps_embed_with_key.mjs' ) ;
74- mapsEmbedFile = 'src/options/maps_embed_with_key.mjs' ;
75- } catch ( e ) {
76- mapsEmbedFile = 'src/options/maps_embed.mjs' ;
77- }
78- return src ( [ mapsEmbedFile ] )
79- . pipe ( rename ( 'options/maps_embed.mjs' ) )
80- . pipe ( newer ( `${ this . pluginDir ( ) } /src` ) )
81- . pipe ( dest ( `${ this . pluginDir ( ) } /src` ) ) ;
82- }
83-
8452 copyImages ( ) {
8553 return src ( [ 'images/**/*.png' ] , { encoding : false } )
8654 . pipe ( newer ( `${ this . pluginDir ( ) } /images` ) )
@@ -97,15 +65,15 @@ class BuildContext {
9765
9866 async generateDomainDotJs ( ) {
9967 const urls = this . _getGoogleMapUrls ( ) ;
100- await fs . mkdir ( ` ${ this . pluginDir ( ) } /src` , { recursive : true } ) ;
68+ await fs . mkdir ( this . intermediatesDir ( ) , { recursive : true } ) ;
10169 await fs . writeFile (
102- `${ this . pluginDir ( ) } /src/ domains.js ` ,
103- 'const SCROLLMAPS_DOMAINS = ' + JSON . stringify ( urls ) ) ;
70+ `${ this . intermediatesDir ( ) } /domains.override.ts ` ,
71+ 'export default ' + JSON . stringify ( urls ) ) ;
10472 }
10573
106- _processManifestTemplate ( content ) {
74+ _processManifestTemplate ( content : string ) {
10775 let manifest = JSON . parse ( content ) ;
108- let processObj = ( obj ) => {
76+ let processObj = ( obj : any ) => {
10977 if ( Array . isArray ( obj ) ) {
11078 let index = obj . indexOf ( '<%= all_google_maps_urls %>' ) ;
11179 if ( index !== - 1 ) {
@@ -171,34 +139,15 @@ class BuildContext {
171139
172140 MINIFY_FILES ( ) {
173141 return {
174- 'inject_everywhere' : [
175- "src/pref.js" ,
176- "src/Scrollability.js" ,
177- "src/ScrollableMap.js" ,
178- "src/inject_everywhere.js"
179- ] ,
180- 'inject_frame_permission' : [
181- "src/inject_frame_permission.js" ,
182- ] ,
183- 'scrollability_inject' : [ "src/Scrollability.js" ] ,
184- 'inject_frame' : [
185- "src/pref.js" ,
186- "src/Scrollability.js" ,
187- "src/ScrollableMap.js" ,
188- "src/permission.js" ,
189- `${ this . pluginDir ( ) } /src/domains.js` ,
190- "src/inject_frame.js"
191- ] ,
192- 'inject_main' : [
193- "src/inject_main.js" ,
194- ] ,
195- 'background' : [
196- "src/pref.js" ,
197- "src/permission.js" ,
198- "src/background.js" ,
199- `${ this . pluginDir ( ) } /src/domains.js` ,
200- ] ,
201- }
142+ 'inject_everywhere' : './src/inject_everywhere.ts' ,
143+ 'inject_frame_permission' : './src/inject_frame_permission.ts' ,
144+ 'inject_scrollability' : './src/Scrollability.ts' ,
145+ 'inject_frame' : './src/inject_frame.ts' ,
146+ 'inject_main' : './src/inject_main.ts' ,
147+ 'background' : './src/background.ts' ,
148+ 'options' : './src/options/options.ts' ,
149+ 'popup' : './src/popup/popup.ts' ,
150+ } ;
202151 }
203152
204153 zipExtension ( ) {
@@ -209,20 +158,37 @@ class BuildContext {
209158 }
210159
211160 async build ( ) {
212- const minifyTasks = Object . entries ( this . MINIFY_FILES ( ) ) . map ( ( [ output , sourceFiles ] ) => {
213- const minifyTask = ( ) =>
214- src ( sourceFiles )
215- . pipe ( newer ( { dest : `${ this . pluginDir ( ) } /${ output } .min.js` , extra : __filename } ) )
216- . pipe ( concat ( `${ output } .min.js` ) )
217- . pipe ( doubleInclusionGuard ( ) )
218- . pipe ( dest ( this . pluginDir ( ) ) ) ;
219- minifyTask . displayName = `[${ this . browser } ] minify_${ output } `
220- return minifyTask ;
221- } ) ;
161+ const webpackTask = ( ) => {
162+ const entries = this . MINIFY_FILES ( ) ;
163+ return src ( Object . values ( entries ) )
164+ . pipe ( webpackStream ( {
165+ entry : entries ,
166+ output : {
167+ filename : '[name].min.js' ,
168+ } ,
169+ resolve : {
170+ extensions : [ '.override.ts' , '.ts' , '.js' ] ,
171+ modules : [ `${ this . intermediatesDir ( ) } ` , 'src' , 'node_modules' ] ,
172+ } ,
173+ module : {
174+ rules : [
175+ {
176+ test : / \. t s $ / ,
177+ loader : 'ts-loader' ,
178+ exclude : / n o d e _ m o d u l e s / ,
179+ }
180+ ]
181+ } ,
182+ mode : 'production' ,
183+ } ) )
184+ . pipe ( dest ( this . pluginDir ( ) ) ) ;
185+
186+ } ;
187+ webpackTask . displayName = `[${ this . browser } ] webpack` ;
188+
222189 const buildUnpacked = parallel (
223- ... minifyTasks ,
190+ webpackTask ,
224191 this . copySourceFiles ,
225- this . copyMapsEmbedFile ,
226192 this . copyImages ,
227193 this . processManifest ,
228194 ) ;
@@ -271,22 +237,49 @@ class BuildContext {
271237 ) ;
272238 }
273239
274- runUnitTest ( watch = false ) {
275- const task = async ( done ) => {
276- let config = await karma . config . parseConfig ( null , {
277- frameworks : [ 'mocha' , 'chai' ] ,
278- files : [
279- 'test/unit/fakes.js' ,
280- `${ this . pluginDir ( ) } /src/domains.js` ,
281- `${ this . pluginDir ( ) } /src/permission.js` ,
282- `${ this . pluginDir ( ) } /src/Scrollability.js` ,
283- 'test/unit/permission_test.js' ,
284- 'test/unit/Scrollability_test.js'
285- ] ,
240+ async buildUnitTestDependencies ( ) {
241+ return src ( [ 'src/permission.ts' , 'src/Scrollability.ts' ] )
242+ . pipe ( webpackStream ( {
243+ entry : {
244+ permission : './src/permission.ts' ,
245+ Scrollability : './src/Scrollability.ts' ,
246+ } ,
247+ output : {
248+ filename : '[name].js' ,
249+ } ,
250+ resolve : {
251+ extensions : [ '.ts' , '.js' ] ,
252+ modules : [ 'src' , 'node_modules' ] ,
253+ } ,
254+ module : {
255+ rules : [
256+ {
257+ test : / \. t s $ / ,
258+ loader : 'ts-loader' ,
259+ exclude : / n o d e _ m o d u l e s / ,
260+ }
261+ ]
262+ } ,
263+ mode : 'development' ,
264+ } ) )
265+ . pipe ( dest ( `${ this . pluginDir ( ) } /src` ) ) ;
266+ }
267+
268+ runUnitTest ( watch = false ) : TaskFunction {
269+ const task = async ( done : TaskFunctionCallback ) => {
270+ const pluginConfig = {
271+ webpack : {
272+ resolve : {
273+ extensions : [ '.override.ts' , '.ts' , '.js' ] ,
274+ modules : [ `${ this . intermediatesDir ( ) } ` , 'src' , 'node_modules' ] ,
275+ } ,
276+ }
277+ }
278+ let config = karma . config . parseConfig ( path . resolve ( 'test/unit/karma.conf.js' ) , {
286279 singleRun : ! watch ,
287- browsers : [ 'ChromeHeadless' ] ,
288- } ) ;
289- new karma . Server ( config , done ) . start ( ) ;
280+ ... pluginConfig
281+ } , { throwErrors : true } ) ;
282+ new karma . Server ( config , ( ) => done ( ) ) . start ( ) ;
290283 } ;
291284 task . displayName = `[${ this . browser } ] runUnitTest` ;
292285 return task ;
@@ -336,7 +329,7 @@ devBuild.description = 'Build the development version of the browser';
336329devBuild . flags = BROWSER_FLAGS ;
337330
338331async function releaseBuild ( ) {
339- const packageJsonString = await fs . readFile ( 'package.json' ) ;
332+ const packageJsonString = await fs . readFile ( 'package.json' ) as any as string ;
340333 const packageJson = JSON . parse ( packageJsonString ) ;
341334 if ( ! packageJson . version ) {
342335 throw new Error ( 'Cannot get version from package.json' )
@@ -351,7 +344,7 @@ releaseBuild.description = 'Build for all releases';
351344
352345// Task to be run after running `npm version [major/minor]`
353346export async function postVersion ( ) {
354- const packageJsonString = await fs . readFile ( 'package.json' ) ;
347+ const packageJsonString = await fs . readFile ( 'package.json' ) as any as string ;
355348 const packageJson = JSON . parse ( packageJsonString ) ;
356349 if ( ! packageJson . version ) {
357350 throw new Error ( 'Cannot get version from package.json' )
@@ -389,14 +382,15 @@ watchDevBuild.description = 'Watch for changes in source files and build develop
389382async function runUnitTest ( ) {
390383 const bc = new BuildContext ( 'chrome' , 10000 ) ;
391384 await runSeries (
392- bc . build ,
385+ series ( bc . generateDomainDotJs , bc . buildUnitTestDependencies ) ,
393386 bc . runUnitTest ( ) ,
394387 ) ;
395388}
396389runUnitTest . description = 'Run unit tests in a headless chrome instance' ;
397390
398391async function watchUnitTest ( ) {
399392 const bc = new BuildContext ( 'chrome' , 10000 ) ;
393+ const buildTest = series ( bc . generateDomainDotJs , bc . buildUnitTestDependencies ) ;
400394 gulp . watch (
401395 [
402396 'src/**' ,
@@ -407,10 +401,10 @@ async function watchUnitTest() {
407401 __filename ,
408402 ] ,
409403 { events : 'all' } ,
410- bc . build
404+ buildTest
411405 ) ;
412406 await runSeries (
413- bc . build ,
407+ buildTest ,
414408 bc . runUnitTest ( true ) ,
415409 ) ;
416410}
@@ -427,7 +421,7 @@ export async function clean() {
427421clean . description = 'Remove all build outputs' ;
428422
429423// Allow --chrome, --firefox, --edge as command line args
430- function getBrowser ( ) {
424+ function getBrowser ( ) : Browser {
431425 const args = minimist ( process . argv . slice ( 1 ) ) ;
432426 for ( const browser of BROWSERS ) {
433427 if ( args [ browser ] ) {
@@ -437,7 +431,7 @@ function getBrowser() {
437431 if ( ! process . env . BROWSER ) {
438432 throw new Error ( 'Browser must be specified with --chrome, --firefox, or --edge' ) ;
439433 }
440- return process . env . BROWSER ;
434+ return process . env . BROWSER as Browser ;
441435}
442436
443437export default devBuild ;
0 commit comments