import { ConcatSource } from 'webpack-sources' export default class ElementsPlugin { constructor (tag) { this.tag = tag } apply (compiler) { compiler.hooks.compilation.tap('ElementsPlugin', compilation => { const handler = modules => { modules.map((module) => { if (module.id) { // Replace ../../node_modules module.id = module.id.replace('../../node_modules', './node_modules') } return module }) } compilation.hooks.moduleIds.tap( 'ElementsPlugin', handler ) // Intercept default chunk template plugin compilation.chunkTemplate.hooks.render.intercept( { 'register': (options) => { if (options.name === 'JsonpChunkTemplatePlugin') { options.fn = (modules, chunk) => { const jsonpFunction = compilation.chunkTemplate.outputOptions.jsonpFunction const globalObject = compilation.chunkTemplate.outputOptions.globalObject const source = new ConcatSource() source.add( `(${globalObject}[${JSON.stringify( jsonpFunction )}] = ${globalObject}[${JSON.stringify( jsonpFunction )}] || []).push([${JSON.stringify(chunk.ids)},` ) source.add(modules) const entries = [ chunk.entryModule ].filter(Boolean).map(m => [ m.id ].concat( Array.from(chunk.groupsIterable)[ 0 ] .chunks.filter(c => c !== chunk) .map(c => c.id) ) ) if (entries.length > 0) { source.add(`,${JSON.stringify(entries)}`) } // Add manual element entry point source.add(`,[['./${this.tag}/index.js']]])`) return source } } return options } } ) } ) } }