Browse Source

Access global.* using array notation

This allows arbitrary `moduleName` (including names with dashes like `ui-router` or scoped npm packages like `@angular/core`) to be added to the global object.

Closes #582
Closes #584
gh-1132
Chris Thielen 8 years ago
parent
commit
f43fd99554
  1. 15
      src/finalisers/iife.js
  2. 17
      src/finalisers/shared/propertyStringFor.js
  3. 21
      src/finalisers/umd.js
  4. 6
      test/form/module-name-scoped-package/_config.js
  5. 9
      test/form/module-name-scoped-package/_expected/amd.js
  6. 7
      test/form/module-name-scoped-package/_expected/cjs.js
  7. 3
      test/form/module-name-scoped-package/_expected/es.js
  8. 8
      test/form/module-name-scoped-package/_expected/iife.js
  9. 13
      test/form/module-name-scoped-package/_expected/umd.js
  10. 1
      test/form/module-name-scoped-package/main.js
  11. 6
      test/form/module-name-with-dashes/_config.js
  12. 9
      test/form/module-name-with-dashes/_expected/amd.js
  13. 7
      test/form/module-name-with-dashes/_expected/cjs.js
  14. 3
      test/form/module-name-with-dashes/_expected/es.js
  15. 8
      test/form/module-name-with-dashes/_expected/iife.js
  16. 13
      test/form/module-name-with-dashes/_expected/umd.js
  17. 1
      test/form/module-name-with-dashes/main.js

15
src/finalisers/iife.js

@ -3,16 +3,23 @@ import { getName } from '../utils/map-helpers.js';
import getInteropBlock from './shared/getInteropBlock.js';
import getExportBlock from './shared/getExportBlock.js';
import getGlobalNameMaker from './shared/getGlobalNameMaker.js';
import propertyStringFor from './shared/propertyStringFor';
// thisProp('foo.bar.baz') === "this['foo']['bar']['baz']"
const thisProp = propertyStringFor('this');
// propString('foo.bar') === "['foo']['bar']"
const propString = propertyStringFor('');
function setupNamespace ( keypath ) {
const parts = keypath.split( '.' ); // TODO support e.g. `foo['something-hyphenated']`?
const parts = keypath.split( '.' );
parts.pop();
let acc = 'this';
return parts
.map( part => ( acc += `.${part}`, `${acc} = ${acc} || {};` ) )
.map( part => ( acc += propString(part), `${acc} = ${acc} || {};` ) )
.join( '\n' ) + '\n';
}
@ -31,7 +38,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString,
}
if ( exportMode === 'named' ) {
dependencies.unshift( `(this.${name} = this.${name} || {})` );
dependencies.unshift( `(${thisProp(name)} = ${thisProp(name)} || {})` );
args.unshift( 'exports' );
}
@ -41,7 +48,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString,
const wrapperOutro = `\n\n}(${dependencies}));`;
if ( exportMode === 'default' ) {
wrapperIntro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${wrapperIntro}`;
wrapperIntro = ( isNamespaced ? thisProp(name) : `${bundle.varOrConst} ${name}` ) + ` = ${wrapperIntro}`;
}
if ( isNamespaced ) {

17
src/finalisers/shared/propertyStringFor.js

@ -0,0 +1,17 @@
// Generate strings which dereference dotted properties, but use array notation
const shouldUseDot = /^[a-zA-Z$_][a-zA-Z0-9$_]*$/;
const dereferenceString = prop =>
prop.match(shouldUseDot) ? `.${prop}` : `['${prop}']`;
/**
* returns a function which generates property dereference strings for the given name
*
* const getGlobalProp = propertyStringFor('global');
* getGlobalProp('foo.bar.baz') => `global['foo']['bar']['baz']`
*/
const propertyStringFor = objName => propName =>
objName + propName.split('.').map(dereferenceString).join('');
export default propertyStringFor;

21
src/finalisers/umd.js

@ -4,6 +4,13 @@ import getInteropBlock from './shared/getInteropBlock.js';
import getExportBlock from './shared/getExportBlock.js';
import getGlobalNameMaker from './shared/getGlobalNameMaker.js';
import esModuleExport from './shared/esModuleExport.js';
import propertyStringFor from './shared/propertyStringFor.js';
// globalProp('foo.bar') === "global['foo']['bar']"
const globalProp = propertyStringFor('global');
// propString('foo.bar') === "['foo']['bar']"
const propString = propertyStringFor('');
function setupNamespace ( name ) {
const parts = name.split( '.' );
@ -11,8 +18,8 @@ function setupNamespace ( name ) {
let acc = 'global';
return parts
.map( part => ( acc += `.${part}`, `${acc} = ${acc} || {}` ) )
.concat( `global.${name}` )
.map( part => ( acc += propString(part), `${acc} = ${acc} || {}` ) )
.concat( globalProp(name) )
.join( ', ' );
}
@ -27,14 +34,14 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i
const amdDeps = bundle.externalModules.map( quotePath );
const cjsDeps = bundle.externalModules.map( req );
const globalDeps = bundle.externalModules.map( module => `global.${globalNameMaker( module )}` );
const globalDeps = bundle.externalModules.map( module => globalProp(globalNameMaker( module )) );
const args = bundle.externalModules.map( getName );
if ( exportMode === 'named' ) {
amdDeps.unshift( `'exports'` );
cjsDeps.unshift( `exports` );
globalDeps.unshift( `(${setupNamespace(options.moduleName)} = global.${options.moduleName} || {})` );
globalDeps.unshift( `(${setupNamespace(options.moduleName)} = ${globalProp(options.moduleName)} || {})` );
args.unshift( 'exports' );
}
@ -50,10 +57,10 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i
const globalExport = options.noConflict === true ?
`(function() {
var current = global.${options.moduleName};
var current = ${globalProp(options.moduleName)};
var exports = factory(${globalDeps});
global.${options.moduleName} = exports;
exports.noConflict = function() { global.${options.moduleName} = current; return exports; };
${globalProp(options.moduleName)} = exports;
exports.noConflict = function() { ${globalProp(options.moduleName)} = current; return exports; };
})()` : `(${defaultExport}factory(${globalDeps}))`;
const wrapperIntro =

6
test/form/module-name-scoped-package/_config.js

@ -0,0 +1,6 @@
module.exports = {
description: 'allows module name with dashes to be added to the global object',
options: {
moduleName: '@scoped/npm-package'
}
};

9
test/form/module-name-scoped-package/_expected/amd.js

@ -0,0 +1,9 @@
define(['exports'], function (exports) { 'use strict';
let foo = 'foo';
exports.foo = foo;
Object.defineProperty(exports, '__esModule', { value: true });
});

7
test/form/module-name-scoped-package/_expected/cjs.js

@ -0,0 +1,7 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
let foo = 'foo';
exports.foo = foo;

3
test/form/module-name-scoped-package/_expected/es.js

@ -0,0 +1,3 @@
let foo = 'foo';
export { foo };

8
test/form/module-name-scoped-package/_expected/iife.js

@ -0,0 +1,8 @@
(function (exports) {
'use strict';
let foo = 'foo';
exports.foo = foo;
}((this['@scoped/npm-package'] = this['@scoped/npm-package'] || {})));

13
test/form/module-name-scoped-package/_expected/umd.js

@ -0,0 +1,13 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global['@scoped/npm-package'] = global['@scoped/npm-package'] || {})));
}(this, (function (exports) { 'use strict';
let foo = 'foo';
exports.foo = foo;
Object.defineProperty(exports, '__esModule', { value: true });
})));

1
test/form/module-name-scoped-package/main.js

@ -0,0 +1 @@
export let foo = 'foo';

6
test/form/module-name-with-dashes/_config.js

@ -0,0 +1,6 @@
module.exports = {
description: 'allows module name with dashes to be added to the global object',
options: {
moduleName: 'module-name-with-dashes'
}
};

9
test/form/module-name-with-dashes/_expected/amd.js

@ -0,0 +1,9 @@
define(['exports'], function (exports) { 'use strict';
let foo = 'foo';
exports.foo = foo;
Object.defineProperty(exports, '__esModule', { value: true });
});

7
test/form/module-name-with-dashes/_expected/cjs.js

@ -0,0 +1,7 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
let foo = 'foo';
exports.foo = foo;

3
test/form/module-name-with-dashes/_expected/es.js

@ -0,0 +1,3 @@
let foo = 'foo';
export { foo };

8
test/form/module-name-with-dashes/_expected/iife.js

@ -0,0 +1,8 @@
(function (exports) {
'use strict';
let foo = 'foo';
exports.foo = foo;
}((this['module-name-with-dashes'] = this['module-name-with-dashes'] || {})));

13
test/form/module-name-with-dashes/_expected/umd.js

@ -0,0 +1,13 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global['module-name-with-dashes'] = global['module-name-with-dashes'] || {})));
}(this, (function (exports) { 'use strict';
let foo = 'foo';
exports.foo = foo;
Object.defineProperty(exports, '__esModule', { value: true });
})));

1
test/form/module-name-with-dashes/main.js

@ -0,0 +1 @@
export let foo = 'foo';
Loading…
Cancel
Save