Created
January 24, 2018 21:37
-
-
Save niieani/1111967dda3bd43945f661cf5910cb0f to your computer and use it in GitHub Desktop.
WrappedImportDependencyTemplate - wrap the closest asynchronous import() and add logic to it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const exampleWrapper = (dep : Object, loadModulePart : string) => { | |
if (SOME_LOGIC_HERE) { | |
const wrappedAsync = loadModulePart.replace( | |
requireEnsureRegex, | |
(match) => `Promise.all([someMagicThatHappensWhileThisAsyncChunkLoads(), ${match}]).then(function(_r){return _r[1]})` | |
) | |
if (wrappedAsync === loadModulePart) { | |
// fallback to synchronous loading | |
return `${functionName}(${stringifiedBundles}, function(){return ${loadModulePart}})` | |
} else { | |
return wrappedAsync | |
} | |
} | |
return loadModulePart | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {WrappedDependencyTemplate} from './WrappedDependencyTemplate' | |
// let's ensure we require the right instance of webpack (when package is linked): | |
const require = module.parent && module.parent.require | |
? module.parent.require.bind(module.parent) | |
: module.require | |
const importDependencies = [ | |
require('webpack/lib/dependencies/ImportDependency'), | |
require('webpack/lib/dependencies/ImportEagerDependency'), | |
require('webpack/lib/dependencies/ImportEagerContextDependency'), | |
require('webpack/lib/dependencies/ImportLazyOnceContextDependency'), | |
require('webpack/lib/dependencies/ImportLazyContextDependency'), | |
] | |
export default class WrappedImportPlugin { | |
constructor(importEmitWrapper) { | |
this.importEmitWrapper = importEmitWrapper | |
} | |
apply(compiler) { | |
// see exampleWrapper: | |
const {importEmitWrapper} = this | |
compiler.plugin('after-plugins', () => { | |
// after-plugins ensures the dependencyTemplate will be overwritten by our own template | |
compiler.plugin('compilation', (compilation, params) => { | |
// we overwrite the default ImportDependencyTemplates with our own that wraps it: | |
importDependencies.forEach(importDependency => { | |
const originalTemplate = compilation.dependencyTemplates.get(importDependency) | |
compilation.dependencyTemplates.set( | |
importDependency, | |
new WrappedDependencyTemplate(originalTemplate, importEmitWrapper) | |
) | |
}) | |
}) | |
}) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
// let's ensure we require the right instance of webpack (when package is linked): | |
const require = module.parent && module.parent.parent && module.parent.parent.require | |
? module.parent.parent.require.bind(module.parent.parent) | |
: module.require | |
export type DebuggerType = (context : string, meta : Object) => void | |
const ImportDependency = require('webpack/lib/dependencies/ImportDependency') | |
const DepBlockHelpers = require('webpack/lib/dependencies/DepBlockHelpers') | |
const ImportDependencyTemplate = new ImportDependency.Template() | |
const noop : DebuggerType = function() {} | |
export type ImportEmitWrapperFunctionType = (depBlock : any, loadModulePart : string) => string | |
export class WrappedDependencyTemplate { | |
importEmitWrapper : ?ImportEmitWrapperFunctionType | |
originalDependencyTemplate : Object | |
debug : DebuggerType | |
constructor(originalDependencyTemplate : Object, importEmitWrapper? : ImportEmitWrapperFunctionType, debug? : DebuggerType) { | |
this.originalDependencyTemplate = originalDependencyTemplate | |
this.importEmitWrapper = importEmitWrapper | |
this.debug = debug || noop | |
} | |
apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { | |
const {originalDependencyTemplate, importEmitWrapper, debug} = this | |
const range = dep.range || (dep.block && dep.block.range) | |
if (!importEmitWrapper || !range) { | |
// short-circuit the wrapper, use the default ImportDependency template: | |
return originalDependencyTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates) | |
} | |
const [rangeStart, rangeEnd] = [range[0], range[1] - 1] | |
const sourceWrapperProxyHandler = { | |
get(target, key) { | |
if (key !== 'replace') { | |
return target[key] | |
} | |
return function replace(start, end, content) { | |
if (start === rangeStart && end === rangeEnd) { | |
const replacement = importEmitWrapper(dep, content) | |
debug('applying', { | |
dependencyType: dep.constructor.name, | |
range, | |
replacement, | |
}) | |
return target[key](start, end, replacement) | |
} | |
return target[key](start, end, content) | |
} | |
}, | |
} | |
const fakeSource = new Proxy(source, sourceWrapperProxyHandler) | |
return originalDependencyTemplate | |
.apply(dep, fakeSource, outputOptions, requestShortener, dependencyTemplates) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment