|
| 1 | +/* eslint-env es6 */ |
| 2 | + |
| 3 | +const UMD_WRAPPER_RE = /(\(function \(global, factory\) \{)((?:\s.*?)*)(\}\(this,)/; |
| 4 | +const CJS_FACTORY_RE = /(module.exports = )(factory\(.*?\))( :)/; |
| 5 | +const AMD_FACTORY_RE = /(define\()(.*?, factory)(\) :)/; |
| 6 | + |
| 7 | +function optional(config = {}) { |
| 8 | + return { |
| 9 | + name: 'optional', |
| 10 | + renderChunk(code, chunk, options) { |
| 11 | + if (options.format !== 'umd') { |
| 12 | + this.error('only UMD format is currently supported'); |
| 13 | + } |
| 14 | + |
| 15 | + const wrapper = UMD_WRAPPER_RE.exec(code); |
| 16 | + const include = config.include; |
| 17 | + if (!wrapper) { |
| 18 | + this.error('failed to parse the UMD wrapper'); |
| 19 | + } |
| 20 | + |
| 21 | + let content = wrapper[2]; |
| 22 | + let factory = (CJS_FACTORY_RE.exec(content) || [])[2]; |
| 23 | + let updated = false; |
| 24 | + |
| 25 | + for (let lib of chunk.imports) { |
| 26 | + if (!include || include.indexOf(lib) !== -1) { |
| 27 | + const regex = new RegExp(`require\\('${lib}'\\)`); |
| 28 | + if (!regex.test(factory)) { |
| 29 | + this.error(`failed to parse the CJS require for ${lib}`); |
| 30 | + } |
| 31 | + |
| 32 | + // We need to write inline try / catch with explicit require |
| 33 | + // in order to enable statical extraction of dependencies: |
| 34 | + // try { return require('moment'); } catch(e) {} |
| 35 | + const loader = `function() { try { return require('${lib}'); } catch(e) { } }()`; |
| 36 | + factory = factory.replace(regex, loader); |
| 37 | + updated = true; |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + if (!updated) { |
| 42 | + return; |
| 43 | + } |
| 44 | + |
| 45 | + // Replace the CJS factory by our updated one. |
| 46 | + content = content.replace(CJS_FACTORY_RE, `$1${factory}$3`); |
| 47 | + |
| 48 | + // Replace the AMD factory by our updated one: we need to use the |
| 49 | + // following AMD form in order to be able to try/catch require: |
| 50 | + // define(['require'], function(require) { ... require(...); ... }) |
| 51 | + // https://github.com/amdjs/amdjs-api/wiki/AMD#using-require-and-exports |
| 52 | + content = content.replace(AMD_FACTORY_RE, `$1['require'], function(require) { return ${factory}; }$3`); |
| 53 | + |
| 54 | + return code.replace(UMD_WRAPPER_RE, '$1' + content + '$3'); |
| 55 | + } |
| 56 | + }; |
| 57 | +} |
| 58 | + |
| 59 | +module.exports = { |
| 60 | + optional |
| 61 | +}; |
0 commit comments