import { CleanWebpackPlugin } from 'clean-webpack-plugin' ; import * as CopyWebpackPlugin from 'copy-webpack-plugin' ; import * as fse from 'fs-extra' ; import * as path from 'path' ; import * as TerserPlugin from 'terser-webpack-plugin' ; import * as webpack from 'webpack' ; import { Verbosity } from '../..' ; import { DefaultWebpackOptions } from '../../index' ; import { excludeNodeModulesAndDependencies , PackageLock } from './excludeNodeModulesAndDependencies' ; type MessageVerbosity = Exclude < Verbosity , 'silent' > ; const verbosityMap = new Map < Verbosity , number > ( ) ; verbosityMap . set ( 'silent' , 0 ) ; verbosityMap . set ( 'normal' , 1 ) ; verbosityMap . set ( 'debug' , 2 ) ; const defaultExternalNodeModules = [ 'clipboardy' , 'opn' , 'open' ] ; export function getDefaultWebpackConfig ( options ) { const loggingVerbosity = options . verbosity || 'normal' ; const packageLockJson = fse . readJsonSync ( path . resolve ( options . projectRoot , 'package-lock.json' ) ) ; const existingDefaultExtNodeModules = defaultExternalNodeModules . filter ( ( moduleName ) => packageLockJson . dependencies && ! ! packageLockJson . dependencies [ moduleName ] ) ; const externalNodeModules = ( options . externalNodeModules || [ ] ) . concat ( existingDefaultExtNodeModules ) ; log ( 'debug' , 'External node modules:' , externalNodeModules ) ; function log ( messageVerbosity , ... args ) { logCore ( loggingVerbosity , messageVerbosity , ... args ) ; } const config = { context : options . projectRoot , target : 'node' , node : { __filename : false , __dirname : false } , entry : { "extension.bundle" : './extension.bundle.ts' , ... options . entries } , output : { path : path . resolve ( options . projectRoot , 'dist' ) , filename : '[name].js' , libraryTarget : 'commonjs2' , devtoolModuleFilenameTemplate : '../[resource-path]' } , devtool : 'source-map' , externals : { vscode : 'commonjs vscode' , ... options . externals } , optimization : { minimizer : [ new TerserPlugin ( { terserOptions : { keep_classnames : true , keep_fnames : true } } ) ] } , plugins : [ new CopyWebpackPlugin ( { patterns : [ { from : path . join ( options . projectRoot , 'out' , 'test' ) , to : path . join ( options . projectRoot , 'dist' , 'test' ) , noErrorOnMissing : true } , { from : toGlobSafePath ( path . join ( options . projectRoot , 'node_modules' , 'vscode-azureextensionui' , 'resources' , '**' , '*.svg' ) ) , to : path . join ( options . projectRoot , 'dist' ) , noErrorOnMissing : true } , { from : toGlobSafePath ( path . join ( options . projectRoot , 'node_modules' , 'vscode-azureappservice' , 'resources' , '**' , '*.svg' ) ) , to : path . join ( options . projectRoot , 'dist' ) , noErrorOnMissing : true } ] } ) , new webpack . ContextReplacementPlugin ( /^\./ , ( context ) : void => { if ( /node_modules[/\\]ms-rest[/\\]lib/ . test ( context . context ) ) { for ( const d of context . dependencies ) { if ( d . critical ) { d . critical = false ; } } } } ) , ... ( options . plugins || [ ] ) ] , resolve : { extensions : [ '.ts' , '.js' ] } , module : { rules : [ { test : /\.ts$/ , exclude : /node_modules/ , use : [ { loader : require . resolve ( 'ts-loader' ) } ] } , ... ( options . loaderRules || [ ] ) ] } } ; if ( ! options . suppressCleanDistFolder ) { config . plugins ! . push ( new CleanWebpackPlugin ( { verbose : true } ) ) ; } excludeNodeModulesAndDependencies ( options . projectRoot , config , packageLockJson , externalNodeModules , ( ... args ) => log ( 'debug' , ... args ) ) ; return config ; } function logCore ( loggingVerbosity , messageVerbosity , ... args ) { const loggingVerbosityValue = verbosityMap . get ( loggingVerbosity ) ! ; const messageVerbosityValue = verbosityMap . get ( messageVerbosity ) ! ; if ( messageVerbosityValue >= loggingVerbosityValue ) { console . log ( ... args ) ; } } /**
 * We always want to use posix separators for glob paths
 * See https://github.com/microsoft/vscode-azuretools/issues/879 and https://github.com/webpack-contrib/copy-webpack-plugin#from
 */ function toGlobSafePath ( fsPath ) { return fsPath . replace ( /\\/g , '/' ) ; }