import { Compiler , compilation } from 'webpack' ; import { ConcatSource } from 'webpack-sources' ; export interface OSJsonpWebpackPluginOption { injectVars ? : string [ ] ; jsonpCall ? : string ; id : string ; } export class OSJsonpWebpackPlugin { public option : OSJsonpWebpackPluginOption ; public constructor ( option ) { this . option = { ... option , } ; } public apply ( compiler ) { if ( compiler . hooks ) { compiler . hooks . compilation . tap ( 'OSJsonpPlugin' , ( compilation ) => { compilation . hooks . afterOptimizeChunkAssets . tap ( 'OSJsonpPlugin' , ( chunks ) => { this . wrappChunks ( compiler , compilation , chunks ) ; } ) ; } ) ; } else { compiler . plugin ( 'compilation' , ( compilation ) => { compilation . plugin ( 'after-optimize-chunk-assets' , ( chunks ) => { this . wrappChunks ( compiler , compilation , chunks ) ; } ) ; } ) ; } } private wrappChunks ( compiler , compilation , chunks ) { chunks . forEach ( firstChunk => { if ( ! firstChunk ) { return ; } const entryFile = firstChunk . files . find ( ( file ) => file . endsWith ( '.js' ) ) ; if ( ! entryFile ) { return chunks ; } const entryAsset = compilation . assets [ entryFile ] ; if ( ! entryAsset ) { return ; } const [ prefix , suffix ] = this . _wrapCodeWithOSJsonp ( this . option . id || this . getId ( compiler ) ) ; compilation . assets [ entryFile ] = new ConcatSource ( prefix , entryAsset , suffix ) ; } ) ; } private getId ( compiler ) { const { output } = compiler . options ; if ( ! output ) { return '' ; } const { library } = output ; if ( typeof library === 'string' ) { return library ; } if ( typeof library === 'object' ) { return library . name ; } throw new Error ( 'library for os jsonp plugin should be string' ) ; } private _wrapCodeWithOSJsonp ( id ) { const injectVars = [ 'window' , 'location' , 'history' , 'document' , ... ( this . option . injectVars || [ ] ) ] ; const jsonpCall = this . option . jsonpCall || 'window.__CONSOLE_OS_GLOBAL_HOOK__' ; return [ `
if (!window.__CONSOLE_OS_GLOBAL_HOOK__){window.__CONSOLE_OS_GLOBAL_VARS_={};window.__CONSOLE_OS_GLOBAL_HOOK__ = function(id, resolver) {resolver(undefined, undefined, undefined, {${ injectVars . map ( ( item ) => `${ item }: ${ item }` ) . join ( ',' ) }})};window.__CONSOLE_OS_GLOBAL_HOOK__.standalone = true}
${ jsonpCall }(${ JSON . stringify ( id ) }, function(require, module, exports, context){ ${ injectVars . map ( item => `var ${ item } = context.${ item }` ) . join ( ';' ) };with(window.__CONSOLE_OS_GLOBAL_VARS_) { \n
` , '\n}})' ] ; } }