@@ -23,6 +23,7 @@ const path = require('path');
2323async function checkDeps ( ) {
2424 const root = path . normalize ( path . join ( __dirname , '..' ) ) ;
2525 const src = path . normalize ( path . join ( __dirname , '..' , 'src' ) ) ;
26+ const packageJSON = require ( path . join ( root , 'package.json' ) ) ;
2627 const program = ts . createProgram ( {
2728 options : {
2829 allowJs : true ,
@@ -44,7 +45,7 @@ async function checkDeps() {
4445 if ( errors . length ) {
4546 console . log ( `--------------------------------------------------------` ) ;
4647 console . log ( `Changing the project structure or adding new components?` ) ;
47- console . log ( `Update DEPS in // ${ path . relative ( root , __filename ) } . ` ) ;
48+ console . log ( `Update DEPS in ./ ${ path . relative ( root , __filename ) } ` ) ;
4849 console . log ( `--------------------------------------------------------` ) ;
4950 }
5051 process . exit ( errors . length ? 1 : 0 ) ;
@@ -55,6 +56,8 @@ async function checkDeps() {
5556 const importPath = path . resolve ( path . dirname ( fileName ) , importName ) + '.ts' ;
5657 if ( ! allowImport ( fileName , importPath ) )
5758 errors . push ( `Disallowed import from ${ path . relative ( root , fileName ) } to ${ path . relative ( root , importPath ) } ` ) ;
59+ if ( ! alllowExternalImport ( fileName , importPath , importName ) )
60+ errors . push ( `Disallowed external dependency ${ importName } from ${ path . relative ( root , fileName ) } ` ) ;
5861 }
5962 ts . forEachChild ( node , x => visit ( x , fileName ) ) ;
6063 }
@@ -91,6 +94,35 @@ async function checkDeps() {
9194 }
9295 return false ;
9396 }
97+
98+
99+ function alllowExternalImport ( from , importPath , importName ) {
100+ const EXTERNAL_IMPORT_ALLOWLIST = [ 'electron' ] ;
101+ // Only external imports are relevant. Files in src/web are bundled via webpack.
102+ if ( importName . startsWith ( '.' ) || importPath . startsWith ( path . join ( src , 'web' ) ) )
103+ return true ;
104+ if ( EXTERNAL_IMPORT_ALLOWLIST . includes ( importName ) )
105+ return true ;
106+ try {
107+ const resolvedImport = require . resolve ( importName )
108+ const resolvedImportRelativeToNodeModules = path . relative ( path . join ( root , 'node_modules' ) , resolvedImport ) ;
109+ // Filter out internal Node.js modules
110+ if ( ! resolvedImportRelativeToNodeModules . startsWith ( importName ) )
111+ return true ;
112+ const resolvedImportRelativeToNodeModulesParts = resolvedImportRelativeToNodeModules . split ( path . sep ) ;
113+ if ( packageJSON . dependencies [ resolvedImportRelativeToNodeModulesParts [ 0 ] ] ) {
114+ return true ;
115+ }
116+ // handle e.g. @babel /code-frame
117+ if ( resolvedImportRelativeToNodeModulesParts . length >= 2 && packageJSON . dependencies [ resolvedImportRelativeToNodeModulesParts . splice ( 0 , 2 ) . join ( path . sep ) ] ) {
118+ return true ;
119+ }
120+ return false ;
121+ } catch ( error ) {
122+ if ( error . code !== 'MODULE_NOT_FOUND' )
123+ throw error
124+ }
125+ }
94126}
95127
96128function listAllFiles ( dir ) {
0 commit comments